Push Button Array

Hi

I'm searching all over the place but I don't quite seems to find the exact example of what I want so I'm asking for help!

I want to connect 32 buttons to my Arduino Uno. So I can read the values, process them and output something. I need to be able to push more then one button at the same time. I just need On/Off. I would probably do a script that check for buttons values every 100ms or so.

I saw a few methods using different resistor values but for 6 buttons. Would'nt make sense for 32!
The best solution I saw was using 4 shift registers 74hc565. However I'm allready using shift register to check the status of other inputs. If this is the best solution, can I put 2 series of shift registers (on different pins)?

I saw that there were output solution of doing array (specially with led).. Is there a similar thing for push buttons?

Thanks!

You can use 4 74HC595's, 4 PCF8574's, 4 74HC165's or 2 MCP23017's. In fact there are several shift registers.
All these will give you on/off with several or all pushed at the same time.
The PCF8574's and MCP23017's are port expander IC's.
Example:

Is there a similar thing for push buttons?

Yes.
This project has an array for both switches and LEDs. Just take the switches part of the circuit.
http://www.thebox.myzen.co.uk/Hardware/Hexome.html

Wow, thanks for your quick reply.

So if Shift Register are the best, then I will stick with the 74HC165, since I am already using them in another part of the circuit.

Thanks!!!

Steven

Depends what you mean by "best".

Your idea that is similar to an LED array would need least extra hardware. For 32 buttons you would need 7 Arduino inputs and 32 diodes. No other chips.

I have drawn the first 18 switches for you in the diagram below. You should be able to work out the connections for the others yourself.

Read the switches as follows:

byte switchPin[7] = { 4, 5, 6, 7, 8, 9, 10 };

byte switchValue[42];

void setup() {
  for (byte i = 0; i <= 7; i++) {
    pinMode(switchPin[i], INPUT_PULLUP);
  }
}

void loop() {
  byte n = 0;
  for (byte i = 0; i <= 7; i++) {
    pinMode(switchPin[i], OUTPUT);
    digitalWrite(switchPin[i], LOW);
    for (byte j = 0; j <= 7; j++) {
      if (j != i) {
        switchValue[n++] = digitalRead(switchPin[j]);
      }
    }
    pinMode(switchPin[i], INPUT_PULLUP);
  }
}

Raiden38:
So if Shift Register are the best, then I will stick with the 74HC165, since I am already using them in another part of the circuit.

With or without shift registers, you want to use a button matrix. 32 buttons is 4 by 5; 9 control lines. Or a shift register (8 by 4 - 7 control lines, two can be shared) - or a counter (4017; 6 control lines) . The only requirement for a matrix is a diode for each button if more than one may be pressed simultaneously. Note that the code becomes quite concise.

The PCF8574 and MCP23017 port expander only need 2 I2C lines, and you can have 100 of them.

steinie44:
The PCF8574 and MCP23017 port expander only need 2 I2C lines, and you can have 100 of them.

No you can't!

There are only 3 address lines on the MCP23017 so that is a maximum of 8 chips on one but.
The PCF8574 has the same so you can only have 8 of those. In addition the PCF8574A is the same but with a different base address so you can have another 8.
So that makes 24 of the devices you quoted not 100.

So that makes 24 of the devices you quoted not 100

Sure, just use another PCF8574 as a decoder to control the address lines for the rest of them.

Besides 24 * 8 buttons = 192.
and 8 * 16 buttons = 128.

Besides 24 * 8 buttons = 192.
and 8 * 16 buttons = 128.

Look if you are going to give advice, give advice not the half **** claptrap you are giving.
You said:-

steinie44:
The PCF8574 and MCP23017 port expander only need 2 I2C lines, and you can have 100 of them.

Nothing about buttons in that sentence. The only noun mentioned are parts, so the 100 can only mean parts, unless you expect every one to be a mind reader.

just use another PCF8574 as a decoder to control the address lines for the rest of them.

And you said that in your reply did you? I think not.
If you are going for that method then a lot more explanation of how to drive the address decoding is needed than you gave.

However if your object is to confuse the OP then you are doing very well.

The PCF8574 and MCP23017 port expander only need 2 I2C lines, and you can have 100 of them.

Like I said

just use another PCF8574 as a decoder to control the address lines for the rest of them.

With a MCP23017 port expander, you can address over 200 of these IC's with it's 16 bits!

In case you don't know it, you don't have to hard wire the address pins!

@steinie44
When it comes to helping, you have a lot to learn.

When it comes to helping, you have a lot to learn.

Well, at least I don't go around and flame other peoples posts and give useless
remarks about peoples code that is not in the interest of any kind of help.

As for what I said, that is help for the OP. Pushing your products is not!

Pushing your products is not!

What products? I don't sell anything.

An other example of how poor you are at reading words and understanding meaning.

Learn to read Paragraphs. There are two of them.

Sure, just use another PCF8574 as a decoder to control the address lines for the rest of them.

Besides 24 * 8 buttons = 192.
and 8 * 16 buttons = 128.

This implementation using 3 digital control lines and a 4017 may be of interest: 4017 IC switch matrix controller and library. Up to 100 switches with 3 pins! - Exhibition / Gallery - Arduino Forum

PaulRB:
Depends what you mean by "best".

Your idea that is similar to an LED array would need least extra hardware. For 32 buttons you would need 7 Arduino inputs and 32 diodes. No other chips.

I have drawn the first 18 switches for you in the diagram below. You should be able to work out the connections for the others yourself.

Read the switches as follows:

byte switchPin[7] = { 4, 5, 6, 7, 8, 9, 10 };

byte switchValue[42];

void setup() {
  for (byte i = 0; i <= 7; i++) {
    pinMode(switchPin[i], INPUT_PULLUP);
  }
}

void loop() {
  byte n = 0;
  for (byte i = 0; i <= 7; i++) {
    pinMode(switchPin[i], OUTPUT);
    digitalWrite(switchPin[i], LOW);
    for (byte j = 0; j <= 7; j++) {
      if (j != i) {
        switchValue[n++] = digitalRead(switchPin[j]);
      }
    pinMode(switchPin[i], INPUT_PULLUP);
    }
  }
}

Thanks so much, it's a great solution. However, I'm kinda limited on the cables I can use so 7 might be too much but I will try to work it out!

Thanks again!

Steven

No problem. But watch out, just realised I got a } in the wrong place in that code! I will go back and correct it in my earlier post.

Thanks!

Do you think that I could maybe connect those 7 inputs to a shift register? therefore, it would reduce the number of inputs from 7 to 3...

Thanks!

No (but...). The technique I suggested relies on the ability of an Arduino pin to be individually flipped between being an input or an output. Look at the what the pinMode() functions are doing. No conventional shift register can do that.

However, if using shift registers, it can be done with a more conventional matrix setup. You would need a 74hc595 (for outputs) and a 74hc165 (for inputs). Each register would need 3 pins to operate, but the clock signal can be shared, so 5 pins in all. If you can figure out how to get them to share the latch signal also, you could get it down to 4, but not sure how easy this would be.

Another option would be an i2c input/output expander. This is kind-of-similar to a shift register, but cleverer. Its pins can be individually flipped from input to output, and it requires only 2 pins connected to the Arduino. Example chip would be PCF8574

The other thing you could do is share with us what else your Arduino is doing and what pins are being used for other things. There may be ways to free up 7 pins for your key matrix.