Sunday, September 29, 2013

35. Driving the Bi-Colour 8 x 8 LED Array Properly

The last post shows a bi-colour 8 x 8 but it's only by disconnecting the reds and connecting the greens, and vice versa, that you can get them both going.  To get them going at the same time in the same sketch, you need a bit more circuitry...that's what I mean by 'properly'.

As I said in the last post, building a circuit for the 8 x 8 bi-colour array was one of the first things I tried.  I soldered it up on a Perfboard and it worked!  I don't know why, but I dismantled the whole thing, probably because it looked a mess with all the wires.

Anyway, I didn't document it so here it is again on breadboard - documented this time! It's still a mess, but never mind.

The tutorial was recorded by Derek Molloy of Dublin City University, one of his many excellent video tutorials on electronics. (ref http://www.youtube.com/watch?v=wXvs0CrRPIw).  He develops the circuit using an increasing number of ICs, the final configuration taking care of the provision of enough, and not too much current to the array.  He uses 74HC595B serial to parallel converters, also described as an 8-bit shift register (I used 74HC595Ns.  Apparently this is the same chip, with just some difference in manufacturer or packaging).  One of these is devoted to the rows of the common anode dot matrix, while another is used for the green columns, and a third for the red columns.



You can just about see the 8 x 8 LED array at the bottom right beside the 16 resistors.  At the top is the Arduino Uno R3, supplying power and ground below and, above, only 3 pins - Pin 8 for data, Pin 9 for the clock and Pin 10 for the latch.

In order to supply current comfortably to the rows, (there is only one row illuminated at a time - persistence of vision makes you think there are more rows on), a UDN2981A 8-channel current source is employed (mine was a UDN2981AT).   This is essentially a transistor array.

Derek Molloy hasn't published his circuit diagram and code, other than on the video, but I was able to freeze the video at all the critical parts and reproduce them:


The diagram is a little blurred, but the detail of the 8 x 8 array is given below:
You can see the array pin numbers in the circles, referring to both rows and columns.  Pin 1 on the array itself can be identified by an indication on the underside.  Notice that on the circuit diagram, the UDN2981A is upside-down, but that's just because of the way the wiring worked out.

Here is the sketch code:

1:  /*  
2:   8 x 8 LED array with 3 x 74HC595N Serial to Parallel converters  
3:   and a UDN2981AT 8-channel Source Driver  
4:   driving a dual colour 8 x 8 array  
5:   Derek Molloy, Dublin City University  
6:   Modified to only use a single data line from the Arduino  
7:  */  
8:  const int NUM_ROWS = 8;  
9:  const int NUM_COLS = 8;  
10:  const int dataPin = 8;  // Row data line  
11:  const int clockPin = 9; // Clock sequence  
12:  const int latchPin = 10; // Latch pin  
13:  int gdataset[13][8] = {{3,6,12,24,48,96,192,96}, {6,12,24,48,96,192,96,48},  
14:    {12,24,48,96,192,96,48,0}, {24,48,96,192,96,48,0,12},  
15:    {48,96,192,96,48,0,12,6}, {96,192,96,48,0,12,6,3},  
16:    {192,96,48,0,12,6,3,6}, {96,48,0,12,6,3,6,12},  
17:    {48,0,12,6,3,6,12,24}, {0,12,6,3,6,12,24,48},  
18:    {12,6,3,6,12,24,48,96}, {6,3,6,12,24,48,96,192}, {3,6,12,24,48,96,192,96}  
19:   };  
20:  int rdataset[13][8] = {{192,96,48,0,12,6,3,6}, {96,48,0,12,6,3,6,12},  
21:    {48,0,12,6,3,6,12,24}, {0,12,6,3,6,12,24,48},  
22:    {12,6,3,6,12,24,48,96}, {6,3,6,12,24,48,96,192},  
23:    {3,6,12,24,48,96,192,96}, {6,12,24,48,96,192,96,48},  
24:    {12,24,48,96,192,96,48,0}, {24,48,96,192,96,48,0,12},  
25:    {48,96,192,96,48,0,12,6}, {96,192,96,48,0,12,6,3}, {192,96,48,0,12,6,3,6}  
26:   };  
27:  void setup(){  
28:   pinMode(clockPin, OUTPUT);   
29:   pinMode(dataPin, OUTPUT);   
30:   pinMode(latchPin, OUTPUT);   
31:  }  
32:  void loop() {  
33:   int i=0;  
34:   while(true) // replay the animation forever  
35:   {  
36:    displayPixels(i,20); // call the function below with the chatacter  
37:               // to be displayed  
38:               // the 2nd value indicates the animation speed  
39:    i++;  
40:    if (i==11) {i=0;}   // go back to the start  
41:   }   
42:  }  
43:  void displayPixels(int val, int delay){  
44:   for (int i=0; i<delay; i++)  
45:   {   
46:    for (int row=0; row<NUM_ROWS; row++){  
47:     int rcur = rdataset[val][row];  
48:     int gcur = gdataset[val][row];  
49:     shiftOut(dataPin, clockPin, MSBFIRST, 255-rcur);  
50:     shiftOut(dataPin, clockPin, MSBFIRST, 255-gcur);  
51:     shiftOut(dataPin, clockPin, MSBFIRST, B00000001 << row);  
52:     digitalWrite(latchPin, HIGH);  
53:     digitalWrite(latchPin, LOW);  
54:     delayMicroseconds(100);  
55:     shiftOut(dataPin, clockPin, MSBFIRST, 255);  
56:     shiftOut(dataPin, clockPin, MSBFIRST, 255);  
57:     shiftOut(dataPin, clockPin, MSBFIRST, B00000001 << row);    
58:     digitalWrite(latchPin, HIGH);  
59:     digitalWrite(latchPin, LOW);  
60:    }  
61:   }  
62:  }  

And here's a video of it working:



Not a pretty sight, but it works.  (You might notice a little flaw in the way the LEDs are illuminated - I haven't quite gotten to the bottom of that.  Suggestions welcome!)

I reaslised that I must have had a connection or two incorrect.

Anyway, because the whole thing is a mess, and on two breadboards, I decided to completely pull it apart and build it again, all on one breadboard.  And I did.  This time it's not so messy looking, but the error now is that one of the columns is not working.  I'll keep fiddling.

Here's the new setup:




Much neater - eh?







No comments:

Post a Comment