Saturday, December 4, 2010

Big LED Matrix

In my last post I built a 5x7 LED matrix. After reading this hackaday article, I decided to expand my LED matrix to the most.

In order to reuse the board I had to grow on the columns, which are 7 leds each.
So I soldered 7 more columns to a total of 12. With the existing 7 rows, I will need now 19 pins of the Arduino, the same as in the Jack-o-lantern (14+5), but my matrix totals 84 leds, against 70 of the mentioned article.

As I'm lighting by column, I can send a current of 20mA for the 7 leds to total the same safe 140mA to the Arduino.

In the previous post I also mentioned the issue when each pin of the Arduino can only support a 40mA current. To solve it we need to connect transistors to the matrix cathodes, for diverting that current to a real GND pin. That way, the Arduino pins that were connected to the cathodes will now connect to the base pin of each transistor, and the other pins will receive the total column current and send it to GND.
Notice that the GND pins can only support up to 200mA.

There are two types of transistors we can use in this case.
Here's the basic lecture I read on their differences.
In this case the difference will be how to program the Arduino. Using NPN transistors means we need to set the pin to HIGH to light a led column, an using PNP transistors the pin has to be LOW.

I wanted to use PNP transistors because that way I could save my NPN for other projects. But after some tests on finding the best resistor to attach to the base, I didn't achieve any satisfactory result, in comparison to the currents I could obtain using NPN transistors.

According to the math, I should be using 100 Ohm resistors for each line, and 2.2k Ohm resistors for the base of each transistor, but after some tests with a multimeter, those numbers were quite different from the reality.
I ended up using 47 Ohm for the lines and 1k Ohm for the transistors.

I used a flat ribbon for the wires to the Arduino. The male connector soldered on the board may look as a tidy way to use, but it's a nighmare to solder the wires, so I wouldn't recommend to use it for this kind of amateur project...

To finish the hardware I applied hot glue on the connections for isolation and fixation.

Now it's time for the software...

// Controlo de uma matriz de LEDs 12x7
// thylux
int L01 = 4;
int L02 = 6;
int L03 = 5;
int L04 = 8;
int L05 = 10;
int L06 = 12;
int L07 = 11;
int C01 = A5;
int C02 = A4;
int C03 = A3;
int C04 = A2;
int C05 = A1;
int C06 = A0;
int C07 = 0;
int C08 = 1;
int C09 = 2;
int C10 = 3;
int C11 = 7;
int C12 = 9;

void setup()
  // Positivos
  pinMode(L01, OUTPUT);
  pinMode(L02, OUTPUT);
  pinMode(L03, OUTPUT);
  pinMode(L04, OUTPUT);
  pinMode(L05, OUTPUT);
  pinMode(L06, OUTPUT);
  pinMode(L07, OUTPUT);
  // Negativos
  pinMode(C01, OUTPUT);
  pinMode(C02, OUTPUT);
  pinMode(C03, OUTPUT);
  pinMode(C04, OUTPUT);
  pinMode(C05, OUTPUT);
  pinMode(C06, OUTPUT);
  pinMode(C07, OUTPUT);
  pinMode(C08, OUTPUT);
  pinMode(C09, OUTPUT);
  pinMode(C10, OUTPUT);
  pinMode(C11, OUTPUT);
  pinMode(C12, OUTPUT);


int freq = 1000 / 600; // Hz
void loop()
  //char debug[10];
  // Demo
  for(int i = 1; i <= 12; i++)
      for(int j=0; j<7; j++)
        light(i, (byte) 2^j);
      //pot = map(analogRead(A0), 0, 1023, 0, 500);
      //sprintf(debug, "i:%d j:%d", i, j);
  int i=0;
  i = 0;

void writeMessage(char* msg)
  for(int i = 0; i < sizeof(msg); i++)

void writeSymbol(char chr)
      case 'a':
      case 'A':
        light(1, B1111100);
        light(2, B0010010);
        light(3, B0010001);
        light(4, B0010010);
        light(5, B1111100);
      case 'b':
      case 'B':
        light(1, B1111111);
        light(2, B1001001);
        light(3, B1001001);
        light(4, B1001001);
        light(5, B0111110);

// Ilumina os LED indicados na coluna
void light(int column, byte data)
      case 1: digitalWrite(C01, HIGH); break;
      case 2: digitalWrite(C02, HIGH); break;
      case 3: digitalWrite(C03, HIGH); break;
      case 4: digitalWrite(C04, HIGH); break;
      case 5: digitalWrite(C05, HIGH); break;
      case 6: digitalWrite(C06, HIGH); break;
      case 7: digitalWrite(C07, HIGH); break;
      case 8: digitalWrite(C08, HIGH); break;
      case 9: digitalWrite(C09, HIGH); break;
      case 10: digitalWrite(C10, HIGH); break;
      case 11: digitalWrite(C11, HIGH); break;
      case 12: digitalWrite(C12, HIGH); break;
  digitalWrite(L01, data & B0000001 ? HIGH : LOW);
  digitalWrite(L02, data & B0000010 ? HIGH : LOW);
  digitalWrite(L03, data & B0000100 ? HIGH : LOW);
  digitalWrite(L04, data & B0001000 ? HIGH : LOW);
  digitalWrite(L05, data & B0010000 ? HIGH : LOW);
  digitalWrite(L06, data & B0100000 ? HIGH : LOW);
  digitalWrite(L07, data & B1000000 ? HIGH : LOW);

void reset()
  digitalWrite(L01, LOW);
  digitalWrite(L02, LOW);
  digitalWrite(L03, LOW);
  digitalWrite(L04, LOW);
  digitalWrite(L05, LOW);
  digitalWrite(L06, LOW);
  digitalWrite(L07, LOW);
  digitalWrite(C01, LOW);
  digitalWrite(C02, LOW);
  digitalWrite(C03, LOW);
  digitalWrite(C04, LOW);
  digitalWrite(C05, LOW);
  digitalWrite(C06, LOW);
  digitalWrite(C07, LOW);
  digitalWrite(C08, LOW);
  digitalWrite(C09, LOW);
  digitalWrite(C10, LOW);
  digitalWrite(C11, LOW);
  digitalWrite(C12, LOW);

During my initial tests I couldn't understand why the columns connected to pin 0 (RX) and pin 1 (TX) were always HIGH.
I found later that it was caused by turning on Serial communication with Serial.begin().
The Serial was used to send debug information to the computer, so if you try to debug my program don't be alarmed by some row/column of leds not behaving as intended.

No comments:

Post a Comment