Author Options:

Are there any coding wizards around when I need them? Answered

I'm sorry to ask a total newb question... but I'm a total newb to shift registers being used with my arduino and 8x8 led matrices.
Would somebody be willing to help me make the code in THIS example so that I can use cascaded 595 shift registers to make for less pin usage on my arduino?
Thank you!

I'm using an Arduino Duemilanove with pin 8 to LATCH, 11 to Serial Data input, and 12 to storage register clock going into two cascaded 595 chips. My displays are 8x8 dual color LED, common cathode, and I've only wired up the red for the time being.

Also, I'm VERY bad at coding. If there's a code, I can read it, but it's like a foreign language whereas I'm better at understanding than reading and writing.
I'm sorry :/ I think I need more help understanding how to plug "shiftout" where "datawrite" would be and how to get it all working.


Really this is a POV (persistence of vision) system, i.e. you need to control the anodes and cathodes separately but quickly using the microcontroller's interrupts.  Only one row or column is lit at any one time, but it goes very fast to make it appear to be permanently lit.

Which Arduino are you using?

What format is your data in? Ideally it would be a byte array, e.g.:
unsigned char LED_DATA[8];
where each byte is one row or column of data.

You could use a 74HC595 for the data (anodes), and a 74HC138 for the cathodes. The 138 takes a 3 pin input, and the 8-pin output ALWAYS has just one pin low. You would need 3 pins for the 595 (data, data-clock, latch-clock) and 3 for the 138 (A,B and C) Would that be acceptable for you? The code should be deliciously simple, but the interrupt code depends on which Arduino you are using.  I've worked with the UNO and MEGA, so should be able to figure anything out!

Actually I misread frollard's reply, so what he says is probably better. You would only use 3 pins for the 595s (data, shift_clock and latch_clock), and cascade the data from the "data" 595 onto the "row select" 595 via Q7S to DS. The "select" output would be inverted, e.g.:
to unset which bit the current data row is for.  That will pull the cathode low on that row, and whichever columns are at "1" will light up.

Anyway, let me know which Arduino you have and I'll mangle together some nice test code for you later.  :o)

I guess you could say my last edit was a bit of a reply. Thanks a lot for all your help!!

Hi!  I think this should work OK.  I've based the code upon stuff I wrote to drive an 8x8x8 LED cube on an Arduino MEGA, which works perfectly.  The 8x8 LED array is MUCH simpler to work with.  Hopefully the code is well enough commented.  It's written in Arduino 1.0 for the Arduino Duemilanove with the ATmega 168.  Just change the board to the 328 if that's what you have.

All my code does is sets up the pins, kicks off an interrupt to update the array, and then does 3 "effects".  A square, a sweeping line and then it fills the square from 0,0 to 7,7.  If it's inverted (LEDs all ON instead of OFF) then swap the two shiftout() statements in the ISR() routine.  Just yell if anything else doesn't work as expected.

I really hope this helps.  Feel free to ask anything.  I'll be around all weekend.

I hit send without finishing! Too early in the morning. What I meant to add was that this code will just test the LED array. To complete the code to do what the example does (the A/D stuff with the potentiometers) will be trivial. Could you just let me know if the test effects work, and if the last bit (filling from top-left to bottom-right) goes in the correct order. It should fill up across the way one row at a time. If it's rotated, just let me know which corner it starts in, and which way it goes.

So, I believe I have it all wired up correctly, but all that's happening is the first column of red LEDs are staying lit.

The second entry in shiftout() is wrong:

Change LOW to HIGH and let me know what happens! :o)

in line 47 of the code, I changed LOW to HIGH. It's spitting some random patterns at me, but no constructive pattern. I may just need to check my wiring, but it seems to stop on a different picture each time I reset it. That is, I power the circuit, the display shows quick patterns, then it freezes on one phase. Normal?

Oh, do you have MR tied to Vcc and OE tied to GND on each 595 too?

Hmmmm... Can you check the functions of pins 8 and 13? "latch" and "storage" actually mean the same thing on the 595 I just realised. My brain obviously picked "latch" as "shift". One should be SH_CP and the other ST_CP. The wiring should be straightforward. Q0-Q7 on the "first" 74HC595 should go to the cathodes. Q0-Q7 on the second 74HC595 should go to the anodes. Q7S on the first should go to DS on the second. Pin 11 on the Arduino should go to DS on the first. SH_CP and ST_CP should be wired together on both chips, and go to pins 8 and 13 respectively.

:o) That looks fine. The code should be very simple, and I'll comment it as much as needed. Do you have any code to write anything to the display, or would you like me to put in some test code, e.g. draw a square, moving dot, just to see how it behaves when running?

you have a plethora of options;

shift register controlling columns, and rows on data pins
shift register controlling rows, columns on data pins
shift resisterS on rows and columns.

You run into a problem that a given shift register will only source or sink current (it will only be + or - in the circuit), usually not both, so if you run the columns, you will need transistors on the rows, or vice versa.

Look at http://www.arduino.cc/en/Tutorial/ShiftOut
this will teach you how to use a 595. Learn it well. From then on its a matter of pretending the 595's pins are arduino pins, and 'shiftout' is the new 'digitalwrite'.

You'll need your matrix of data you want to shift out, 8 bytes ideally (8 groups of 8 bits = 64 bits or leds). I would personally use an array of byte values
now imagine the column 595 cascades into the row 595, we need to write the data for a row as a byte, then write the row as a byte, then latch the data to both to enable the outputs

for y = 0 to 7 //rows
latchpin = 0;
shiftout array[y]
shiftout B00000001 << y; use the bitshift operator to move the binary number 1 over by the number of bits represented by 'y' to drive which row is on. You could also shift out 2^y, same thing, but bitshift is faster.
latchpin = 1;
delay(1); // change to make the leds stay lit for a short amount of time
end y for;

what does it do?
puts out the value y in the array, then cascades the value 1 bitshifted by y bits, so the first value in the array goes to the first row
the second value goes to the 2nd column, and so on until all 7 are done.


6 years ago

Check out http://conductiveresistance.com/interactive-595-shift-register-simulator/
it is a very useful simulator, that will help you understand how to implement the code.

there is complete step by step guide at http://www.arduino.cc/en/Tutorial/ShiftOut