Shift Registers and Arrays?

Hi,
I'm currently working on a project which involves at least 16 buttons and 16 LEDs. For the sake of example, I'll say it's 2 rows of 8 buttons and 2 rows of 8 LEDs.

Because of the fact that the Arduino simply doesn't have that many IO pins, I'm planning on using shift registers for the buttons and LEDs. As I am new to using shift registers with Arduino, I was wondering if/how I would be able to do useful things with them. Most examples do things like count up in binary, but for my application I would have to do something like "Push button 3 and turn on LED 3" (along with some other things being done but we won't worry about that now). Would using an array be the way to do this, and if so, how exactly would I do that?

Also, because of the physical layout of the LEDs/buttons, is there a way to use a 2D array (if the arrays are even the right way) with this design? Having the "row 1 LED 3" idea would be very helpful.

Thanks in advance!

Hi

You could also consider a port expander chip, such as the MCP23017.

This connects to the Arduino using the 2-wire I2C bus. You can connect multiple chips in parallel to the same 2 wires and talk to each one separately.

Each pin is configurable as input or output. The current each pin can handle is lower than for an Arduino pin, but would be enough to drive an LED.

You asked about arrays. They could well be useful in your situation. As an example, checking the current state of each button and saving it in an array element for later processing, using a for loop, would take less code than assigning the button values to separate variables - and it would be easier to spot bugs than with lots of similar repeated code - and it would be easier to change the code if you need to.

And 2D arrays are also possible. Again, depends on what your program logic does, and whether the relationship between rows and columns is significant.

All the best

Ray

274HC165 for shifting, 2 74Hc595 or TOIC6B595 for shifing.
Use SPI.transfer to read & write at the same time:

digitalWrite (csInPin, LOW);
digitalWrite (csInPin, HIGH); // capture inputs at '165s with low pulse
byte1in = SPI.transfer(byte1out); // read in while writing out
byte2in = SPI.transfer(byte2out);
digitalWrite (csOutPin, LOW);
digitalWrite (csOutPin,  HIGH); // move newly shifted data to '595 outputs

Parts are around 50 cents as well.

Cascade as many as you'd like.
Don't forget 0.1uF caps on the Vcc pins.

Take a look at this page:
http://bildr.org/2011/08/74hc595-breakout-arduino/

i have used the Shifter library a couple of times and it worked very well!
:wink:

Need a library for 6 lines of code? Seems like overkill.

OK... My idea for using an array was basically that each array element would represent an output (or input) pin on the shift register so that you'd basically "shift out" the contents of the array. For example, say everything in the array was 0 except for index 3, then shifting out the array would only turn on LED 3. I'm pretty sure you could do this, I'm just having trouble coming up with the logic to do so.

Replace byte1 and byte2 in my example with
dataArray[0] and dataArray[1]
element represent the 8 bits that go to a shift register.

Some manipulation examples:
clear bit 3:
dataArray[0] = dataArray[0] & 0b11110111;

set bit 5:
dataArray[0] = dataArray[0] | 0b00100000;

Then transfer the data out as shown.

CrossRoads:
Need a library for 6 lines of code? Seems like overkill.

no, you are right. But depending on what you want to do, this library might be an option.
It allows you to "target" each leds directly, something like

shifter.setPin(4, HIGH)

that would be for the "4th led on the shifter", the 4th on the chain
or

shifter.setPin(10, HIGH)

to turn on the 2nd led on the second shifter, so the 10th on the chain

...so i guess it would be possible to use it with arrays.

But, like you said, it is kind of overkill.
But it doesn't hurt to know all the possibilities out there, when looking for a solution for something
:wink: