Shift registers and LED's

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.

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.

:slight_smile:

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.

Good God man, you've done it... what do you walk around carrying 8 x 8 matrix circuit diagrams in your back pocket? XD

No, it had been drawn up already for an earlier discussion.
Is there a way to see the date on that file? Oct 2011 8)

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.

8 X 8 Matrix flow chart.pdf (5.59 KB)

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 ...

8_X_8_Matrix_flow_chart[1].docx (12.3 KB)

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

Diagram 2.bmp (958 KB)

For some reason Diagram 1 did not hurtle through cyber-space too... so here it comes 8)

Diagram 1.bmp (1.12 MB)

I have been “goggling my heart out” 8), 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.

MR must be held High, making it low clears the outputs.
OE must be held Low, making it high disables the output drivers.
High Power pin is either called Vcc or Vdd. Connects to 5V or 3.3V typically.
Low Power pin is called Vss. Connects to Ground typically.

Thanks again for that Crossroads. I have got some ULN2803's coming on "the slow boat from China" so when they arrive I will put it all together and see how I go.
Pedro.

I finally received the ULN2803 arrays to complete the 8 x 8 matrix and after connecting it all up have eventually got a diagonal row of LED's lighting from left to right, top to bottom. Not knowing anything about the coding in the test array
({0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; I do not really know where to go from here… (now there's something new hey ) :smiley:
Does it look like it is operating as it should and if so how do I "move forward" as they say in the classics. Thanks again Pedro.

Good news!
The array would indeed make a diagonal line.

What is it you wanted to display? You could have static 'pictures' defined, and every so often switch to a new one. Maybe based on time, maybe when a button is pushed, maybe when a serial message was received. You could have the display slowly scroll left or right, or up & down. Put what else you want displayed in a larger array and read that data out and write it to the display array. Or make up what is being displayed on the fly.

Thanks for the good news Crossroads. I am glad that my perseverance with sorting out the wiring paid off, I love it when a plan comes together. I suppose that I want to try and understand how to use your code to perform simple displays so that I can start to understand how the arrays control the matrix. For example with the 3 x 3 x 3 cube that you helped me with, I found some PatternTable code that I found useful and after much head scratching and rewiring, worked out which part of the array was controlling each LED.
i.e. - in this array {B100, B000, B000, B000, B000, B000, B000, B000, B000} ;
on my cube this would turn on the first LED on the top level and I also deduced that the first nine numeric's controlled the nine LED's on the top level, the 10th to 18th numeric's the center level LED's etc. and obviously a one was on and zero off.
I know that it's not rocket science, but to me it showed me how to use the code to control the cube in a much simpler way that turning everything on and off one by one, and that using arrays is the way to go. I therefore would like to develop a similar understanding of this matrix code so that I can start to control simple things like individual control of each LED, scrolling lights etc and eventually static and scrolling symbols and text. I don't even recognize the array that you have used here;
byte dataArray[]= {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; Thanks again for your help in trying to educate me Pedro.

"I don't even recognize the array that you have used here;
byte dataArray[]= {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; "

Okay, so rewrite it like the cube display then:
B00000001, B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000
Same data, different number format. Lot easer to follow than:
Decimal, 1,2,4,6,16,32,64,128 - who can tell where those bits are going to end up? Hex (0x01) and Binary (B00000001) are a lot easier to visualize.

In this case, each group represents 1 column of data, and you have 8 columns representing the matrix.
B00000001, B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000
column 0, column 1, column 2, column 3, column 4, column 5, column 6, column 7

As wired to the shift registers & matrix:
cccccccc
76543210

10000000
01000000
00100000
00010000
00001000
00000100
00000010
00000001

So now you have this 8x8 set of data and it up to you to decide how you will fill that set up and when you will change/update it. Content, that's always the killer :slight_smile:
We already have blink-without-delay going to determine when the display is refreshed.
Add a second one at different time interval, and shift the data in the array:
7 goes into a temporary copy, 6 goes into 7, 5 goes into 6, 4 into 5, 3 into 4, 2 into 3, 1 into 2, 0 into 1, and the temporary copy goes into 0. Now the display becomes:
1st shift 2nd shift 3rd shift
01000000 00100000 00010000
00100000 00010000 00001000
00010000 00001000 00000100
00001000 00000100 00000010
00000100 00000010 00000001
00000010 00000001 10000000
00000001 10000000 01000000
10000000 01000000 00100000

You see how the data moves right and then wraps around?
So that's one thing you can do, and then build other features from there.

Thanks for that. I'll play around with those type of arrays if I can work out how to put them into your code. Yes it did perplex me when I saw that
" byte dataArray[]= {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 " in your original code you gave me because straight after it you had some in the B00000001 format but it was "commented out"

#include <SPI.h> // bring in SPI library

byte 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] = B10000000

I think that it's time for me to really knuckle down and get a grasp on how all this coding is put together. Thanks again Crossroads and I'll let you know how I go, Pedro.

The commented out part was to show you what the initial data would look like.
dataArray [ x ] represents one column of data, the columns are 0 to 7. Or perhaps 7 to 0. You can make all the data 0 except for 1 and see how your display actually relates to the array data.

Yes I am starting to see how it works. I had a play around with it last night and managed to make a diagonal cross and the letter H. Now there’s progress XD
I have a lot of written material about all things Arduino, but can you recommend anything in particular that I read as there is so much information on Arduino in general that it’s hard to know where to start. Thinking in three dimensions with the cubes and two dimensions with data moving in, down and across with the matrix is certainly taxing my intellect I can tell you. Sometimes I’m flat out thinking in one dimension.

I struggle with the same. So much of what can be found for examples is like uncommented cryptic C commands, hard to follow or to tell what it does.
And then they go into classes and functions and libraries and .cpp files and .h files, and its late at night & my eyes just glaze over.
Get some basic stuff working, ask questions in the forum.
I downloaded a book
"Thinking in C++ Vol 1 - 2nd Edition_bumatek.pdf"
"Thinking in C++ Vol 2 - 2nd Edition_bumatek.pdf"
but didn't get very far reading it yet.