Saturday, April 28, 2012

Multiplexing LEDs

If you want to do anything really over the top using an Arduino than the limited number of pins you have will become a problem. For little projects there are more than enough pins, but if you want to make for example a table with a ton of LEDs or a large cube of LEDs you won't have enough.





One way to get around this problem is the use of a multiplexer. With the NTE4097B multiplexer I bought three output pins on the Arduino can control a total of 8 LEDs.

To get it to work I connected the pins as follows:
1: Vin on the Arduino, through a resistor (connected to 9V power supply )
2: The + side of an LED
3: Another LED
4: Another LED
5: Another LED
6: Another LED
7: Another LED
8: Another LED
9: Another LED
10: Digital Pin #4 on the Arduino
11: Digital Pin #5 on the Arduino
12: Ground
13: Ground
14: Pin #6 on the Arduino
15: Unused
16: Unused
17:Vin on the Arduino, through a resistor
18: Unused
19: Unused
20: Unused
21: Unused
22: Unused
23: Unused
24:  Vin on the Arduino

The program cycles through the 8 LEDs with 1 on at a time:



I found this to be a poor way to handle things. For one, this chip was a bit touchy. I accidentally shorted out something momentarily a while after making this video and the chip seems to have stopped working. Perhaps it will recover, but more importantly, there is no way to turn on more than 1 LED at a time. Next time I will have to try Shift Registers.


Here is the code, mostly stolen from here:

// Define binary control output pins
#define S0 4
#define S1 5
#define S2 6

void setup()
{
  // Set multiplexer controller pins to output
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
}

void loop()
{
  // Loop through the 8 possible channels in the multiplexer
  for( int i = 0; i < 8; i++ ){
    setMultiplexer(i);
    delay(1000);
  }
 
}

void setMultiplexer( int i ){
 
  int s0Value = i & 0x01;      // get value of first bit
  int s1Value = (i>>1) & 0x01; // get value of second bit
  int s2Value = (i>>2) & 0x01; // get value of third bit
 
  digitalWrite( S0, s0Value ); // turn first pin on or off
  digitalWrite( S1, s1Value ); // turn second pin on or off
  digitalWrite( S2, s2Value ); // turn third pin on or off

Arduino Controlled Motor

The more powerful simple generator which I had built always seemed like it should work as a perfectly respectable motor if I could just reverse the direction of the current with accurate enough control. The Arduino is perfect for this. I can turn on and off electricity with millisecond level control.

If the motor required less current than the Arduino itself could run the motor. Unfortunately the microcontroller is restricted to very low currents before components will melt. This can be worked around by using the Arduino to control relays.

A relay is simply a switch. Think of it as a light switch which can be turned on and off with an electronic signal. In this case I used some opto-isolated relays to control the output from a 13.5V wall wart (if you choose to repeat this, you can cut off the end connector of a wall wart and separate the wires; be careful though this can be a fire hazard if you leave it plugged in and don't pay attention to it; also make sure the amperage rating is high enough for the application).

I connected four relays to the arduino board. Two relays are connected to the positive lead from the wall wart, two to ground. I connected one relay attached to positive and one connected to ground to each wire coming from the generator. Then I turned the relays on and off such that the current would flow in opposite directions to ground. In the image below this means closing the relays connected to the brown wires than waiting a short time than closing the relays connected to the purple wires.



This is unlikely to be a workable solution for long term use. The relay will eventually burn up because it is just not rated for enough switching operations to run a motor for a useful length of time. I bought a MOSFET board to try and make a more useful solution but it mysteriously stopped working within an hour of my using it. 


In the video below it is running at about 600RPM. It runs a bit more trouble-free when at about half this speed.



Here is the code for it. It creates a basic inverter waveform where the voltage is high for 120 degrees, zero for 60 degrees, low for 120 degrees, than zero for another 60 degrees:

// constants won't change. Used here to
// set pin numbers:
const int PhaseA1 =  2;     // the number of a the pin used to control relay "A1"
const int PhaseA2 =  4;     // the number of a the pin used to control relay "A2"
const int PhaseB1 =  3;     // the number of a the pin used to control relay "B1"
const int PhaseB2 =  5;     // the number of a the pin used to control relay "A2"

// Variables will change:
int relayStateA1 = HIGH;             // relayState used to set the relay, HIGH is open
int relayStateA2 = LOW;
int relayStateB1 = LOW;
int relayStateB2 = HIGH;

long previousMillis = 0;        // will store last time since the cycle started

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long wavelength = 100;           // length of one full wavelength (milliseconds)
;

void setup() {
  // set the digital pins as output:
  pinMode(PhaseA1, OUTPUT);
  pinMode(PhaseA2, OUTPUT);
  pinMode(PhaseB1, OUTPUT);
  pinMode(PhaseB2, OUTPUT);

}

void loop()
{
unsigned long currentMillis = millis();

if(currentMillis - previousMillis < wavelength/2-wavelength/12 && currentMillis - previousMillis > wavelength/12) {
  relayStateA1=LOW;      // a LOW state will turn the relay on
  relayStateA2=LOW;     
  digitalWrite(PhaseA1, relayStateA1);    // turns "A1" relay on for 120 degrees of the cycle.
  digitalWrite(PhaseA2, relayStateA2);    // turns "A2" relay on for 120 degrees of the cycle
}
else{
  relayStateA1=HIGH;
  relayStateA2=HIGH;
  digitalWrite(PhaseA1, relayStateA1);    // turns "A1" relay off for 240 degrees of a cycle
  digitalWrite(PhaseA2, relayStateA2);    // turns "A2" relay off for 240 degrees of a cycle
}
 
if(currentMillis - previousMillis > wavelength/2+wavelength/12 && currentMillis - previousMillis < 11*wavelength/12  ) {
  relayStateB1=LOW;      // Repeats what was done with A1 for B1
  relayStateB2=LOW;
  digitalWrite(PhaseB1, relayStateB1);
  digitalWrite(PhaseB2, relayStateB2);
}
else{
 
  relayStateB1=HIGH;  // Repeats what was done with A1 for B1
  relayStateB2=HIGH;
  digitalWrite(PhaseB1, relayStateB1);
  digitalWrite(PhaseB2, relayStateB2);
 

}

if(currentMillis - previousMillis > wavelength){
  previousMillis=currentMillis;    // Tells the program to start a new cycle
}

}

Arduino 7 Segment Display Countdown

This is just me repeating something I remember doing years ago in an electronics lab. An Arduino is controlling a LSD5061-11 seven segment display. The display counts down from 9 to 0 again and again.

I imagine the Arduino is smart enough to turn into a clock fairly easily, although three of these will require a little extra circuitry or they will melt the board.



Here is the code. It is a bit crude but works well enough. If I was to modify it to take an imput I would alter it so that it does not use the delay function so much:


void setup() {               
  // initialize the digital pins as an output.
 
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);  
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);

}

void loop() {
 
  digitalWrite(3, HIGH); // Turn all LEDs off
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
  delay(10);
  digitalWrite(3, LOW); // Display 9
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, HIGH);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
  delay(1000);
  digitalWrite(3, LOW); // Display 8
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
  delay(1000); 
  digitalWrite(3, HIGH); // Display 7
  digitalWrite(4, HIGH);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, HIGH);
  digitalWrite(8, HIGH);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
  delay(1000); 
  digitalWrite(3, LOW); // Display 6
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, HIGH);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
  delay(1000); 
  digitalWrite(3, LOW); // Display 5
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
  delay(1000);
  digitalWrite(3, LOW); // Display 4
  digitalWrite(4, LOW);
  digitalWrite(5, HIGH);
  digitalWrite(6, LOW);
  digitalWrite(7, HIGH);
  digitalWrite(8, HIGH);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
  delay(1000);
  digitalWrite(3, LOW); // Display 3
  digitalWrite(4, HIGH);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, HIGH);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
  delay(1000);
  digitalWrite(3, LOW); // Display 2
  digitalWrite(4, HIGH);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
  delay(1000);
  digitalWrite(3, HIGH); // Display 1
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, LOW);
  digitalWrite(7, HIGH);
  digitalWrite(8, HIGH);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
  delay(1000);
    digitalWrite(3, HIGH); // Display 0
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
  delay(1000);

}

Arduino Controlled Extension Cord

This is almost certainly the most dangerous project I have tried with electricity. I recently bought a board of relays. These are essentially just switches which can be electronically controlled and will turn on and off when given a signal from a device such as my Arduino.

I then took an extension cord and cut the hot wire of the cord and put the two ends into the COM and NC(Normally Closed) inputs on the relay. It is important to cut the hot wire because if you instead cut the neutral you might have full wall voltage at your device even when the relay is turned off.

Then with a simple program I turned on and off the relay while using the extension cord to power a lamp.





From what I can tell creating a light or other device that turns on at a particular time, temperature, reading from a motion sensor, microphone, or light level would be fairly trivial. The hardest part would simply be hardening the relay so that it will not be a fire or electrocution hazard.

The code running this project is:

// constants won't change. Used here to
// set pin numbers:
const int RelayPin =  2;      // the number of the relay pin


// Variables will change:
int RelaySetting = HIGH;             // ledState used to set the relay to off


long previousMillis = 0;        // will store last time relay was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long wavelength = 2000;           // interval at which to blink (milliseconds)
;

void setup() {
 
  digitalWrite(RelayPin, HIGH);  // set the digital pin as output:
  pinMode(RelayPin, OUTPUT);


}

void loop()
{
unsigned long currentMillis = millis();

if(currentMillis - previousMillis < wavelength/2 && currentMillis - previousMillis > 0) {
  RelaySetting=LOW;    // turns the relay on
  digitalWrite(RelayPin, RelaySetting);
}
else{
  RelaySetting=HIGH;      // turns the relay off
  digitalWrite(RelayPin, RelaySetting);

}
 

if(currentMillis - previousMillis > wavelength){
  previousMillis=currentMillis;
}

}

Friday, April 27, 2012

Arduino controlled LEDs

I have started making some simple Arduino programs. Here is one where I turn a knob and LED racer lights move faster or slower:






Code used to run it:
int val = 0;         
int potPin = 2;  // the pin connected to the LED

void setup() {
  // use a for loop to initialize each pin as an output:
  for (int thisPin = 3; thisPin < 13; thisPin++)  {
    pinMode(thisPin, OUTPUT);     
  }
}

void loop() {
  // turn on pins from the lowest pin to the highest:
  for (int thisPin = 3; thisPin < 13; thisPin++) {

    digitalWrite(thisPin, HIGH);      // turn the pin on:
    val = analogRead(potPin)/5;      // set the delay length based on potentiometer setting
    delay(val);                      // delay for the specified time
   
    digitalWrite(thisPin, LOW);    // turn the pin off:
  }
  }
The middle lead of the potentiometer was connected to analog pin #2, while digital pins 3-13 were used for digital input.

Saturday, April 21, 2012

No End to Spending

I thought this quote did a good job of summing up the problem we will be having in the next fifty years:



“The problems of democracy are inherent. It’s like having dinner with a million people and deciding up front the bill will be split evenly. Everyone has a strong incentive to order more than he would individually, resulting in a huge bill that everyone deplores but no individual could do anything about. Democracy therefore has a very limited self-cleansing capability. Our politicians have a natural short-term outlook since they are only temporarily in office. They will overspend, overtax and over borrow knowing their successors will have to deal with the negative consequences. Besides that, they spend other people’s money anyhow.”

Everyone  has a lot of motivation to fight for whatever money is going in their direction. No one is taking the role of cutting off programs which are a waste of government money seriously.

Monday, April 16, 2012

College Rankings

I have long thought that college rankings were bad. They give too much weight to matters which don't mean much to students like the number of papers professors publish and too little weight to things like 4 year graduation rates, average student debt and unemployment rates after graduating.

This ranking, summarized in this article from Businessweek seems like a step above most. Their 30 year net return on investment seems to be properly weighted to punish schools which don't actually seem to improve the financial situation of their students.

What is most shocking is how well the ivy league and other private schools do. In the long run their high tuition is more than made up for by high graduation rates and high salaries. While most public schools get crushed, the highest being Colorado School of Mines at 20th. The low graduation rates and long average times to graduation end up costing more than the tuition at a private school.

Cornell was ranked a respectable 14, adding about a million dollars on average to the income of its graduates.

Fresno State on the other hand was ranked 419, only adding about $170,000 income to its attendees, hardly paying for the time spent there. Even that puts it almost in the top third though. The worst two or three hundred schools actually decrease lifetime income for their students, never paying for the tuition and lost income from not working those years.

Tuesday, April 10, 2012

Unemployment really is falling

The usual unemployment number which is cited is the U3 number. Essentially to be included you have to not have a job, and have been looking for a job actively. Why this number is so popular is beyond me, the U6 value is a whole lot more meaningful. Essentially it does include anyone who does not have a full time job who would take one if it was offered.




This graph makes a few things pretty clear: First, it has been more than twenty years since unemployment has been as bad as the past four years. This really is a crisis by any measure. Second, Bush is at least as much to blame as Obama, When Bush entered office the U6 rate was 7.1, when he left office it was 14.2. So unemployment actually doubled under Bush. Under Obama unemployment hit a peak of 17.2 during his first year, and has slowly fallen since then. Today it is down to 14.5, the lowest it has been since his first month of office. Of course many will point out that this recovery is pathetically slow, and they are right. Obama failed to fix a bad economy, which is far better than breaking a perfectly good one.

If anything like the past few months continues though, Obama is a shoe in. While it took three years longer than I expected, it really does look like unemployment is finally coming back down to where it should be.

Sunday, April 8, 2012

Reusable rockets

I have long thought that the most important thing for NASA to be doing is improving the ability to get cheaply into space. I have long known that there in a whole lot of efficiency improvements allowed for by the laws of physics making it reasonable to foresee a world where getting to space costs a similar amount to flying around the world.

This question and answer session really made that clear to me

"We are trying to achieve full and rapid re-usability. If we can make fully and rapidly re-usable rockets that are cheaper to build than expendable rockets are today, then we will only be worried about the fuel, and the propellant cost per flight is only 0.3% of the cost of the mission."

Right now we are not paying for energy, we are paying for engineers and expendables. Once a fully reusable space ship exists the drop in costs should be dramatic.

Saturday, April 7, 2012

Arduino

I finally had heard about Arduino from one too many people. I broke down and bought an Arduino Uno along with a few accessories including an 8 channel relay board and a board with 4 power FET switches.

I am not entirely sure what I will do with this board. Initially I think I will use the ability to control a relatively high power DC source to turn my simple generator into a motor. I imagine that I can get fairly high RPMs out of the thing with a little bit of fiddling with.

After that, I am not sure. A lot of people do basic robotics projects on it:





There are also lots of useless but amusing things people have done:





Friday, April 6, 2012

Space science is of little use if people don't leave earth

I have commonly heard the argument that we should not bother putting humans in space because robots can do science there far cheaper than people can. I have always hated this argument. Space science is of little use if people don't ultimately establish permanent settlements in space. So what if we go to Mars, take a lot of pretty pictures and find water? If we are going to sit on earth and do little else they are only good for some minor amusement for a handful of people. If we establish a self-sufficient colony capable of expanding than we all but ensure that in a few centuries many billions live off this planet. A far larger payoff.

I was therefore particularly happy to see this article in The Atlantic arguing for humans in space. The main argument is good. If you try to sell space travel as an exciting adventure to build a future that no living thing in the several billion year history of the earth has managed to achieve you have a fighting chance of winning funding. If you try to sell it as a way to take pictures of rocks in space than we just better hope some other country makes a better case.

His main argument, then is those scientists consigning themselves to a future of interstellar probes are shooting themselves in the foot. Ventures like the James Webb Space Telescope may hit the ceiling for government expenditures on purely scientific ventures, but researchers and scientists can -- and should -- try to make the case for manned spaceflight in other contexts, if only for the sake of maximizing the scientific gains made from planetary exploration.