Go Down

### Topic: Shift registers and LED's (Read 27845 times)previous topic - next topic

#### Pedro147

##### Jul 19, 2012, 05:40 am
I have been using Arduino Uno and two 74HC595 shift registers daisy chained to control 16 LED's and now I would like to have independent control of 64 LED's in an 8 x 8 matrix wired as per attached diagram 1. As I see it, from my limited knowledge, the shift register connected to the anodes via resistors and transistors would set the appropriate anode row HIGH and the second shift register connected to the cathodes would set the appropriate cathode column LOW.  I understand the basic concept of coding for a single shift register to control eight LED's in whatever order I want them to light or not, but this matrix is baffling me. I only really want to do this to further my understanding the procedure with a view to ultimately building an 8 x 8 x 8 LED cube controlled by Arduino Uno and 8 bit shift registers. If someone could give me a few clues in lay terms I would appreciate some help. Thanks for your time Pedro.
http://www.pedroduino.com

#1

#### Pedro147

#2
##### Jul 19, 2012, 09:26 am
Thanks for that Mike. I have seen your excellent electronic tutorials etc on your site and elsewhere online but to be honest this one is above my skill level. I "somewhat" understand current syncing and sourcing to reduce the current that is actually drawn from the Arduino but was just hoping for some "simple code" to drive the shift registers I mentioned so I might start to understand how they might be used to control a matrix. However I will persist in trying to understand more of what you explain in this tutorial and thanks again for your response, Pedro.
http://www.pedroduino.com

#3
##### Jul 19, 2012, 10:48 pmLast Edit: Jul 20, 2012, 04:52 am by CrossRoads Reason: 1
Try this Pedro. Not debugged, should be pretty close.
Some might suggest burying stuff in functions, I say skip that and just let it run fast!

Code: [Select]
`// code to read data from an 8 byte array and display on 8x8 LED matrix with shift registers and current limit resistors driving anodes, // and shift register with high current drivers sinking common cathodes.// SPI commands will be used to send the data out// sequence: every xx milliseconds, turn off all cathodes// set up anodes from data stored in an array// turn on next cathode// // while time is passing for the next set of anodes, do other stuff// repeat#include <SPI.h> // bring in SPI librarybyte SSanodes = 9; // output latch for anodes shift register.  Can be any pin except 10,11,12,13.byte SScathodes = 10; // output latch for cathodes shift register.  Pin D10 needs to be an output for SPI.byte dataArray[]= {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};  // load up some initial data// dataArray[0] = B00000001// dataArray[1] = B00000010// dataArray[2] = B00000100// dataArray[3] = B00001000// dataArray[4] = B00010000// dataArray[5] = B00100000// dataArray[6] = B01000000// dataArray[7] = B10000000byte cathodePins[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};  // used to turn on 1 cathode at a timeunsigned long timeNow = 0;  // capture timeunsigned long previousTime = 0; // store previous timeunsigned long elapsedTime = 5; // time that each column will be onbyte anodeColumn = 0;  // keep track of column being drivenvoid setup(){pinMode (SSanodes, OUTPUT);pinMode (SScathodes, OUTPUT);SPI.begin();  // commits 11,12,13 for hardware SPI transfer. Make sure shift registers have 0.1uF/100nF on their VCC pins to ground.}void loop(){timeNow = millis(); // capture the current 'time'if ((timeNow - previousTime)>= elapsedTime){  // display refresh time?previousTime = previousTime + elapsedTime; //setup for next pass// keep track of which column is being writtenanodeColumn = anodeColumn+1;if (anodeColumn == 8){anodeColumn = 0;}  // reset after going 0,1,2,3,4,5,6,7 >> 0// turn off current cathodedigitalWrite (SScathodes, LOW);SPI.transfer(0); // 0 = all cathode off >> assumes HC595 driving base of NPN transistor or ULN2803digitalWrite (SScathodes, HIGH);// shift out next set of anodesdigitalWrite (SSanodes, LOW);SPI.transfer(dataArray[anodeColumn]); // read data from the array and send it outdigitalWrite (SSanodes, HIGH);// turn the next cathode ondigitalWrite (SScathodes, LOW);SPI.transfer(cathodePins[anodeColumn]); // 0 = all cathode off >> assumes HC595 driving base of NPN transistor or ULN2803digitalWrite (SScathodes, HIGH);} // end of time check// make sure that all compiles & runs okay. If too flickery, decrease elapsedTime. Maybe even go to micros() instead of millis();// next, add your code to read buttons, receive serial data, whatever your method for making updates to dataArray[x]// for example, this should move the On LED in each row across the screen every 1/2 second/*  add variable definitions as above// timeNow already captured at the top of void loopif ( (timeNow - previousShiftTime)>= elapsedShiftTime){previousShiftTime = previousShiftTime + elapsedShiftTime;tempArray = arrayData[0];  // store column 0arrayData[0] = arrayData[1]; // column 0 becomes column 1arrayData[1] = arrayData[2]; // 1 becomes 2arrayData[2] = arrayData[3];arrayData[3] = arrayData[4];arrayData[4] = arrayData[5];arrayData[5] = arrayData[6];arrayData[6] = arrayData[7];arrayData[7] = tempArray;  // finally 7 becomes what 0 was.}*/// display will show the new data at the next display update interval} // end void loop`
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

#### Pedro147

#4
##### Jul 19, 2012, 11:52 pm
Thanks for that Crossroads, I will build that matrix and try your code out. I just wanted to make sure that using shift registers was a viable option before actually building the matrix. Thanks again Pedro
http://www.pedroduino.com

#5
##### Jul 20, 2012, 04:50 am
Wow, tried to compile that, only 2 errors!

Needed to add these to the top  of the sketch:

#include <SPI.h>
byte anodeColumn = 0;

Revised post above to include them.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

#### Pedro147

#6
##### Jul 20, 2012, 06:09 am
Hey you're working on this harder than I am... your making me look bad. If I draw up how I think the circuit should go, would you mind perusing it and pointing out the inevitable mistakes I know that I am going to make. Thanks Pedro.
http://www.pedroduino.com

#7
##### Jul 20, 2012, 06:16 amLast Edit: Jul 20, 2012, 06:19 am by CrossRoads Reason: 1

What, you mean this?
Picture it rotated 90 degrees counter-clockwise so the anodes are driven from the left and the cathodes from the bottom.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

#### Pedro147

#8
##### Jul 20, 2012, 07:29 am
Good God man, you've done it... what do you walk around carrying 8 x 8 matrix circuit diagrams in your back pocket?  XD
http://www.pedroduino.com

#9
##### Jul 20, 2012, 07:34 am
Is there a way to see the date on that file? Oct 2011
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

#### Pedro147

#10
##### Jul 20, 2012, 01:58 pmLast Edit: Dec 15, 2014, 06:53 am by Pedro147
As my knowledge of electronics is rudimentary, I am trying to understand the basic power flow in this matrix. As I see it the Arduino digital signal goes to the input of the anode shift register which applies current to the selected anode row of the  matrix. The cathode shift register which is daisy chained to the anode shift register sends it's output to the input of the ULN2803. The output of the ULN2803 goes to the cathode columns of the  matrix.
Therefore when the selected input of the  ULN2803 receives current from the corresponding output of the cathode shift register, ground is applied to the corresponding output of the cathode shift register, effectively grounding the relevant matrix cathode column and lighting the LED. I apologise for my verbose, and more than likely technically inept explanation and have attached a basic flow chart which hopefully makes sense. Is this anything close to how it might operate and be constructed ? Thanks for your time, again… Pedro.
http://www.pedroduino.com

#11
##### Jul 20, 2012, 04:37 pm
You are basically correct.

I did not daisy chain them in the code, I made the anodes seperately writeable from the cathodes.

8 bits are shifted into the cathode shift register, turning off any high outputs, which turns off any UN2803 outputs.
8 bits are shifted into the Anode shift register, can be high or low.
8 bits are shifted into cathode shift register, only one will be a 1. The ULN2803 output for that 1 goes Low, any LEDs with a high anode turned on.

By wiring SCK & MOSI to both shift registers in parallel, both shift register input stages are loaded with the same data every time. Only the shift register that gets the seperate Register Clock (SSanode or SScathode) has the data moved to the output stage to show up at the LED matrix.

Compare that to daisy chaining them, where 2 bytes must be shifted out every time, even tho the anode outputs only change 1 of those times:
cathodes off + no anode change
cathodes off + new anodes
cathode on + no anode change

vs just 1 byte
cathodes off
new anodes
cathode on

Having the cathode off before changing the anode prevents any ghosting as the display is updated.
The digitalWrite for the Register Clock will be slow part of this operation, that can be changed to direct port manipulation later to really speed it up.
One thing at a time tho ...

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

#### Pedro147

#12
##### Jul 22, 2012, 12:41 pmLast Edit: Mar 16, 2013, 12:51 am by Pedro147 Reason: 1
I am endeavouring to draw up the matrix circuit based on my limited use of 74HC595 shift registers and Crossroads invaluable help. There seems to be a few different pinouts for the components but the  ones I will be using  worked o.k. when I used them to drive eight LED's using them as in attached diagram 1.

Crossroads from what you indicated in your code and flow chart, I thought that;

Pin 9 Arduino might go to pin 12 of anodes shift register
Pin 10 Arduino might go to pin 12 of cathodes shift register

It seems that pin 8 of my shift registers are VCC ?  where you indicate 0.1uf - 100nf capacitors ?

I see from your flowchart that  Arduino pins 11, and 13 go, in parallel to the SCK and RCK pins of the two shift registers  but there seem to be a multitude of names for these pins and I am uncertain as to what pin is what on the shift registers that I am using.

Also in the eight LED matrix circuit attached, pin 13  (OE) went to ground - what about in this 8 x 8 matrix ?

I apologise for being so vague, but as stated I am a rank  but enthusiastic amatuer here. (It's been a long day…)

I have included the circuit diagram 2 of what I have drawn up so far and would appreciate some further guidance if possible.

Thanks Pedro.

p.s - I just realise that I wired up the outputs of the cathode shift register to the inputs of the ULN2803 in the reverse order

http://www.pedroduino.com

#### Pedro147

#13
##### Jul 22, 2012, 12:46 pm
For some reason Diagram 1 did not hurtle through cyber-space too... so here it comes
http://www.pedroduino.com

#### Pedro147

#14
##### Jul 22, 2012, 03:02 pm
I have been "goggling my heart out"  , and  am I right in suggesting that;
SCK is shift register clock input which is pin 11  SH CP of the shift register
RCK is storage register clock input  which is pin 12 ST CP of the shift register
Serial data is pin 14  DS of the shift register
So I connect;
Arduino pin 9 to  anode shift register pin 12
Arduino pin 10 to cathode shift register pin 12
Arduino pin 13 to pin 11 on both anode and cathode shift registers
Arduino pin 11 to pin 14 on both anode and cathode shift registers

If this is all correct I am still wondering about the necessity of the  ground to shift register pins 13 OE that I used in the single shift register driving eight LED's circuit (are they required in this circuit?) and if those capacitors are in the right place on shift register pin 8 (if this is in fact pin VCC)
Also does the rest of the circuit appear to be o.k. apart from my homemade shift register and ULN2803 symbols.
http://www.pedroduino.com

Go Up