Is there an easier way to write code to read multiple digital pins than this?

I'm making a midi controller and need to read lots of buttons... is there an easier way to write code to read multiple digital pins and return the number of which one goes HIGH...??

Easier than this...

if (!digitalRead(buttonPin1[0]) == HIGH) { count = 1; } else if (!digitalRead(buttonPin1[1]) == HIGH) { count = 2; } else if (!digitalRead(buttonPin1[2]) == HIGH) { count = 3; }

....etc

I have A LOT of button and as I new to learning arduino... can't figure out if there is a better way to simplify this.

Any Help would be greatly appreciated. :)

The first thing that comes to mind is a for loop to read through the buttonPin array. The value of count can be derived from the for loop variable and if you break from the for loop when a pin is found HIGH you will get the same effect as your if/else and stop reading pins at the first one found HIGH

Sorry for being stupidly new too this, I know how to read them in a for loop

for (int i = 0; i < 10; i++) {

digitalRead(buttonPin*);*

  • }*
    but have no idea how to get a value out of which one has gone high.

Following your example above

for (int i = 0; i < 10; i++) {

   if (digitalRead(i));
   {
   count = i + 1;
    }
  }

sirkristofer: I'm making a midi controller and need to read lots of buttons... is there an easier way to write code to read multiple digital pins and return the number of which one goes HIGH...??

Easier than this...

if (!digitalRead(buttonPin1[0]) == HIGH) { count = 1; } else if (!digitalRead(buttonPin1[1]) == HIGH) { count = 2; } else if (!digitalRead(buttonPin1[2]) == HIGH) { count = 3; }

....etc

I have A LOT of button and as I new to learning arduino... can't figure out if there is a better way to simplify this.

Any Help would be greatly appreciated. :)

Show full declaration of button pins and use for-loops then to loop though all buttons!

sirkristofer:
Sorry for being stupidly new too this, I know how to read them in a for loop

for (int i = 0; i < 10; i++) {

digitalRead(buttonPin*);*

  • }*
    but have no idea how to get a value out of which one has gone high.
    [/quote]Not throwing away the value you have read would be a good start

Hutkikz:
Following your example above

for (int i = 0; i < 10; i++) {

if (digitalRead(i));
  {
  count = i + 1;
   }
 }

That would be OK if pins 0 to 9 were being used otherwise you need to use the value of i as an index to an array of pin numbers. Also, it doesn’t quite do what the original code does as it does not stop at the first HIGH pin found

Yeah, I want to once a pin goes high, execute a task using the ‘count’ as a pointer to which pin it was to modify what code is executed… if that makes any sense??

Sorry I’m super ew to coding and having great fun learning it, but this has got me stumped. It might be easier if I show you the code I’m working on…

#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();

int buttonPin1 = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};

int butPinMin1 = 2;
int butPinMax1 = 13;

int count = 0;
int countLast = 0;

void setup() {

for (int i = butPinMin1; i <= butPinMax1; i++) {
pinMode(i, INPUT_PULLUP);

}

void loop() {

count = 0;

if (!digitalRead(buttonPin1[0]) == HIGH) {
count = 1;
}
else if (!digitalRead(buttonPin1[1]) == HIGH) {
count = 2;
}
else if (!digitalRead(buttonPin1[2]) == HIGH) {
count = 3;
}
else if (!digitalRead(buttonPin1[3]) == HIGH) {
count = 4;
}
else if (!digitalRead(buttonPin1[4]) == HIGH) {
count = 5;
}
else if (!digitalRead(buttonPin1[5]) == HIGH) {
count = 6;
}
else if (!digitalRead(buttonPin1[6]) == HIGH) {
count = 7;
}
else if (!digitalRead(buttonPin1[7]) == HIGH) {
count = 8;
}
else if (!digitalRead(buttonPin1[8]) == HIGH) {
count = 9;
}
else if (!digitalRead(buttonPin1[9]) == HIGH) {
count = 10;
}
else if (!digitalRead(buttonPin1[10]) == HIGH) {
count = 11;
}
/*else if (!digitalRead(buttonPin1[11]) == HIGH) {
count = 12;
}

if (count > 0) {
if (count != countLast) {
Serial.println(count);
MIDI.sendControlChange(count, 127, 1);
} else {
MIDI.sendControlChange(count, 0, 1);
count = 0;
}
delay(100);
countLast = count;
}

}

Sorry for the lenghy post. Any help is appreciated.

A for loop with a break?

I’m making a midi controller and need to read lots of buttons… is there an easier way to write code to read multiple digital pins and return the number of which one goes HIGH…??

Yes.
I’m reading all 20 pins with the following code in and displaying them with only 30 lines of code. the actual reading only takes 3 lines.

Tested and works 100% on UNO

union PinsLink {
  volatile uint32_t All;
  volatile uint8_t  Port[4];
} Pins;

uint8_t  PinNumber[22] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, 14, 15, 16, 17, 18, 19};                 // Key = Bit Val = Position List of pins that could be used as ping inputs:
uint8_t  BitNumber[20] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21};                 // Key = Pin Val = Position List of pins that could be used as ping inputs:

void setup() {
  Serial.begin(115200);
  for (int i = 2; i < 20; i++) { // pins 0 & 1 are for Serial communications
    pinMode(i, INPUT_PULLUP);
  }
}

void loop() {
  // The following 3 lines gets the status of all the pins and stores them in a 32 bit interager using a union
  Pins.Port[0] = PIND; // 0~7
  Pins.Port[1] = PINB; // 8~13
  Pins.Port[2] = PINC; // A0~A5

 // Lets see what we have:
  for (int Pin = 0; Pin < 20; Pin++) { // pins 14 ~ 19 are analog A0 ~ A5
    Serial.print("Pin# ");
    Serial.print(Pin);
    Serial.print(" = ");
    int Bit = BitNumber[Pin]; // the BitNumer array links the pin number to the bit representing the pin.
    Serial.println(Pins.All >> Bit & 1); // Lets see if Just that bit is high and print the results.
  }
  delay(1000);

AWOL:
A for loop with a break?

I don’t know what that means…lol thats kinda my problem.

You can read the internal registers directly. As an example: Pin5 is bit number 5 of register D. The following code reads reg. D, using a binary mask (B00100000), selects bit#5. The if statement does the rest.

if (DDRD && B00100000) { // Code to do when Pin5 is HIGH } else { // Code to do when Pin5 is LOW }

To test other Pins, use DDRB or DDRC and test the bit you want by setting the appropriate mask.

Also, this method is much faster that digitalRead().

You can read the internal registers directly. As an example: Pin5 is bit number 5 of register D.

I don't think that the OP is quite ready for that yet.

You have a for loop in your original program to set the pinMode() of the input pins. Write one to print the value returned by digitalRead() for each of the pins in the buttonPin1 array and the for loop index for each of them and you are on your way.

The following code reads reg. D, using a binary mask (B00100000), selects bit#5.

if (DDRD && B00100000)

DDRD is the data direction register and will not contain the state of the pins. You have also confused the logical && with the bitwise & used to create a mask. The code will not do what you think it will.

digitalRead() was created as an Arduino function to avoid errors like this.

cattledog:

if (DDRD && B00100000)

DDRD is the data direction register and will not contain the state of the pins. You have also confused the logical && with the bitwise & used to create a mask. The code will not do what you think it will.

digitalRead() was created as an Arduino function to avoid errors like this.

You seem to know your onions, sir.

I mean I’m happy to just let the long list of 'else if’s be but I’m sure there is a more econmical way to write what is essential (in dummy logical code that I understand…)

Read these pins – if a pin goes low to high – output that number into a thing were I can use it.

I am SUCH a noob. but literally only just started playing with coding and arduino. So please talk in idiot speak and/or give me an example. Otherwise, I’ll just stick with the rediculous and lenghy digitalRead if else thing that works but seems inneficient

sirkristofer: I don't know what that means...lol thats kinda my problem.

That's why I provided the links. I don't spoon-feed.

AWOL I spoon-fed sirkristofer with working example of what he's asking for. See my earlier post.

Oh well...

I spoon-fed sirkristofer with working example of what he's asking for. See my earlier post.

@ zhomeslice

The OP has working code based on sequential digitalRead()s and setting an index which he tests for. The OP thought his code was cumbersome because of its length or repetition, and AWOL suggested an appropriate way to trim it down.

I don't think it is helpful to provide a newbie with an example reading every pin on a UNO using unions, port reads, and bit masks. I doubt the OP will see how that is an"easier way".

Ya, your correct. I just seek these types of things to resolve my struggles self and so when I can share a incredibly quick way of doing something, I do. If someone googles this post and I can help them instead... Well thanks to all those who helped me with working examples of more complex items like this. And to sirkristofer good luck with your midi project looks interesting.