Arduino hacking and experimenting

I’ve recently started experimenting with Arduino, an open source hardware prototyping platform, and with electronics in general. After the standard first few experiments (blinking LED’s and such) I wanted to do something a bit more exciting.

I Already purchased a cheap 5x7 led matrix and thought it would be easy to hook it up to the Arduino and control it. There were a few problems however:

  • It only has 12 pins to control 35 led’s. This means you can’t just turn on individual LED’s.
  • Even though Arduino should have enough output pins to control the entire matrix, the pins are divided into anode and cathode pins which means you control colums and rows by sourcing current on the anode (columns) and/or grounding cathodes (row). See the datasheet for the schema.
  • Not all combinations are possible! By enabling row/col (1,1) and (2,2), you won’t get two LED’s to light up, but 4: (1,1), (1,2), (2,1) and (2,2)!

This turned out to be a more challenging task than I thought (at least for me, being an electronics noob). I had already learned about the 74HC595 shift register. However, it only acts as a current source, not a current sink, which is required to control the cathodes. This can be easily solved using some transistors which ground the cathode when there’s current on their base. Combining two of these registers gives us 16 outputs, and we only need 12, so that problem is solved. For claritly, let’s put the rows on one register and cols on the other.

Controlling individual LED’s can be solved by alternating quickly between different rows and columns. E.g. (pseudo code)

  while(1) {
    enable(1,1);
    delay(5);
    enable(2,2);
    delay(5);
  }

will make the individual LED’s light up and it will appear asif they’re both lit up simoultaneously. Now, you can write a very smart algorithm to determine what rows and cols to set efficiently to get any random pattern, but since there are only 5 columns it’s easier to just iterate over the columns individually.

The end result looks like this:

Van misc

The code

Now that we can control the matrix, let’s do something fun on it: scrolling text. I’ve written a little python program that translates text into individual bitmasks for columns:

text = [
"x           x x                         x    x   xxx",
"x           x x                         x    x   xxx",
"x xx   xxx  x x  xxx  x   x  xxx  x xx  x    x   xx ",
"xx  x x   x x x x   x x   x x   x  x  x x  xxx   xx ",
"x   x xxxx  x x x   x x   x x   x  x    x x  x   x  ",
"x   x x     x x x   x x x x x   x  x    x x  x      ",
"x   x  xxx  x x  xxx   x x   xxx   x    x  xx x xx  "
]

chars = []
for i in range(0, len(text[0])):
    v = 0
    for j in range(0, 7):
        v <<= 1
        if text[6-j][i] == "x":
            v += 1
            
    chars.append(v)
print ",".join(map(str, chars))

This will output 127,8,4,4,120,0,56,84,84,84,8,0,127,0,127,0,56,68,68,68,56,0,60,64,32,64,60,0,56,68,68,68,56,0,4,120,4,4,8,0,127,0,48,72,72,63,64,0,64,95,15,3 which we can then use in a small arduino program to scroll on the matrix (I’ve added some extra zeroes so the text doesn’t immediately start in the leftmost column but scrolls nicely from right to left):

const int latchPin = 8;
const int clockPin = 12;
const int dataPin = 11;

void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
  Serial.begin(9600);
  Serial.println("reset");
}

byte text[] = {0, 0, 0, 0, 0, 127,8,4,4,120,0,56,84,84,84,8,0,127,0,127,0,56,68,68,68,56,0,60,64,32,64,60,0,56,68,68,68,56,0,4,120,4,4,8,0,127,0,48,72,72,63,64,0,64,95,15,3};

void loop() {
  for(int x = 0; x < sizeof(text); x++) {
    for(int repeat=0; repeat < 4; repeat++) {
      for(byte i = 0; i < 5; i++) {
        doit(1<<i, text[(i+x)%sizeof(text)]);
        delay(5);
      }     
    }
  }
}

void doit(byte low, byte high) {
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, high);
  shiftOut(dataPin, clockPin, MSBFIRST, low);
  digitalWrite(latchPin, HIGH);
}

This is what the end result looks like:

For me, being a software guy, this is quite an achievement. I’ve probably done things not as good/efficient as possible, feel free to notify me of any improvements in the comments. If anyone wants the schematics for the entire setup, let me know as well and I’ll see what I can do.

Closed comments

    Hey man this is very cool. Would it be cool with you if you sent me the full version of the code

    THANKS, THIS IS AWESOME

    Comment by Brady — Apr 27, 2011 12:46:44 AM

    All relevant source is in the post.

    Comment by ivo — May 16, 2011 8:56:28 AM

Last updated July 2, 2013, 9:51 a.m. | filed under Software | c hacking arduino
comments powered by Disqus