Tuesday, January 18, 2011

Waving Display with Arduino

When I first got my SunSPOT kit two years ago, the first example I ran on it was a demo called AirText. The SPOTs have 8 LEDs aligned in a row on-board. What the example did was to light up the on-board LEDs at a certain frequency. You have to imagine that a character consists of several columns. When displaying one column after another you get the whole character. For example for an 'H' you would set all LEDs of the column to high. Afterwards you would set all LEDs to low except for the middle one. Then again you would set all LEDs to high.

I build a small array of 5 red LEDs and hooked them up to the Arduino board. If I start the program with the board just lying on the table, you would see some flashing LEDs. Nothing fancy so far. But if I pick up the board and wave it continously from left to right at a certain frequency, you can see each column of a character after another "written" into the air, which forms the whole character.

The setup is pretty easy. Here is a simplified schematic:

The source code is easy as well. You can extend it to write new characters. You might need to enhance the LED array or the column count if you want to display special characters, as I only worked with a 3x5 display.

int top = 8;
int topmiddle = 9;
int middle = 10;
int bottommiddle = 11;
int bottom = 12;
int characterDelay = 500;
int columnDelay = 15;

void setup() {
}

void loop() {
  displayH();
  allOff();
  displayE();
  allOff();
  displayL();
  allOff();
  displayL();
  allOff();
  displayO();
  allOff();
}

//I found that by displaying the columns from left to right
//and then again from right to left gives a better result.
void displayH() {
    //set left column all high
    digitalWrite(top, HIGH);
    digitalWrite(topmiddle, HIGH);
    digitalWrite(middle, HIGH);
    digitalWrite(bottommiddle, HIGH);
    digitalWrite(bottom, HIGH);
    delay(columnDelay);
    //set all low except middle
    digitalWrite(top, LOW);
    digitalWrite(topmiddle, LOW);
    digitalWrite(bottommiddle, LOW);
    digitalWrite(bottom, LOW);
    delay(columnDelay);
    //set right column all high (middle is still high)
    digitalWrite(top, HIGH);
    digitalWrite(topmiddle, HIGH);
    digitalWrite(bottommiddle, HIGH);
    digitalWrite(bottom, HIGH);
    delay(columnDelay);
    //second delay so that right column is still high
    delay(columnDelay);
    //set all low except middle
    digitalWrite(top, LOW);
    digitalWrite(topmiddle, LOW);
    digitalWrite(bottommiddle, LOW);
    digitalWrite(bottom, LOW);
    delay(columnDelay);
    //set right column all high (middle is still high)
    digitalWrite(top, HIGH);
    digitalWrite(topmiddle, HIGH);
    digitalWrite(bottommiddle, HIGH);
    digitalWrite(bottom, HIGH);
    delay(columnDelay);
}

void displayE() {
    digitalWrite(top, HIGH);
    digitalWrite(topmiddle, HIGH);
    digitalWrite(middle, HIGH);
    digitalWrite(bottommiddle, HIGH);
    digitalWrite(bottom, HIGH);
    delay(columnDelay);
    digitalWrite(topmiddle, LOW);
    digitalWrite(bottommiddle, LOW);
    delay(columnDelay);
    delay(columnDelay);
    delay(columnDelay);
    delay(columnDelay);
    digitalWrite(topmiddle, HIGH);
    digitalWrite(bottommiddle, HIGH);
    delay(columnDelay);
}

void displayL() {
  digitalWrite(top, HIGH);
  digitalWrite(topmiddle, HIGH);
  digitalWrite(middle, HIGH);
  digitalWrite(bottommiddle, HIGH);
  digitalWrite(bottom, HIGH);
  delay(columnDelay);
  digitalWrite(top, LOW);
  digitalWrite(topmiddle, LOW);
  digitalWrite(middle, LOW);
  digitalWrite(bottommiddle, LOW);
  delay(columnDelay);
  delay(columnDelay);
  delay(columnDelay);
  delay(columnDelay);
  digitalWrite(top, HIGH);
  digitalWrite(topmiddle, HIGH);
  digitalWrite(middle, HIGH);
  digitalWrite(bottommiddle, HIGH);
  delay(columnDelay);
}

void displayO() {
    digitalWrite(top, HIGH);
    digitalWrite(topmiddle, HIGH);
    digitalWrite(middle, HIGH);
    digitalWrite(bottommiddle, HIGH);
    digitalWrite(bottom, HIGH);
    delay(columnDelay);
    digitalWrite(topmiddle, LOW);
    digitalWrite(middle, LOW);
    digitalWrite(bottommiddle, LOW);
    delay(columnDelay);
    digitalWrite(topmiddle, HIGH);
    digitalWrite(middle, HIGH);
    digitalWrite(bottommiddle, HIGH);
    delay(columnDelay);
    delay(columnDelay);
    digitalWrite(topmiddle, LOW);
    digitalWrite(middle, LOW);
    digitalWrite(bottommiddle, LOW);
    delay(columnDelay);
    digitalWrite(topmiddle, HIGH);
    digitalWrite(middle, HIGH);
    digitalWrite(bottommiddle, HIGH);
    delay(columnDelay);
}

//set all LEDs off in between characters and provide a bigger delay
void allOff() {
  digitalWrite(top, LOW);
  digitalWrite(topmiddle, LOW);
  digitalWrite(middle, LOW);
  digitalWrite(bottommiddle, LOW);
  digitalWrite(bottom, LOW);
  delay(characterDelay);
}
 
In the video you can see me waving the breadboard continously from left to right varying my waving frequency until you can see the letters a little bit better. I think the result right at the end is the best one.

No comments:

Post a Comment