More elegant solution for 16 digitalReads?

Hi guys,

I have a selector switch with 4 toggles, 1 or 0.

I need to find the position of them and this is what I come up with. It works but I'm wondering if there is a fancier way of reaching the same solution.

  if((digitalRead(Selector1), LOW) && (digitalRead(Selector2), LOW) && (digitalRead(Selector3), LOW) && (digitalRead(Selector4), LOW)) {
    Channel = 1; //0000
  }
  if((digitalRead(Selector1), LOW) && (digitalRead(Selector2), LOW) && (digitalRead(Selector3), LOW) && (digitalRead(Selector4), HIGH)) {
    Channel = 2; //0001
  }
  if((digitalRead(Selector1), LOW) && (digitalRead(Selector2), LOW) && (digitalRead(Selector3), HIGH) && (digitalRead(Selector4), LOW)) {
    Channel = 3; //0010
  } 
  if((digitalRead(Selector1), LOW) && (digitalRead(Selector2), LOW) && (digitalRead(Selector3), HIGH) && (digitalRead(Selector4), HIGH)) {
    Channel = 4; //0011
  } 
  if((digitalRead(Selector1), LOW) && (digitalRead(Selector2), HIGH) && (digitalRead(Selector3), LOW) && (digitalRead(Selector4), LOW)) {
    Channel = 5; //0100
  } 
  if((digitalRead(Selector1), LOW) && (digitalRead(Selector2), HIGH) && (digitalRead(Selector3), LOW) && (digitalRead(Selector4), HIGH)) {
    Channel = 6; //0101
  } 
  if((digitalRead(Selector1), LOW) && (digitalRead(Selector2), HIGH) && (digitalRead(Selector3), HIGH) && (digitalRead(Selector4), LOW)) {
    Channel = 7; //0110
  } 
  if((digitalRead(Selector1), LOW) && (digitalRead(Selector2), HIGH) && (digitalRead(Selector3), HIGH) && (digitalRead(Selector4), HIGH)) {
    Channel = 8; //0111
  } 
  if((digitalRead(Selector1), HIGH) && (digitalRead(Selector2), LOW) && (digitalRead(Selector3), LOW) && (digitalRead(Selector4), LOW)) {
    Channel = 9; //1000
  } 
  if((digitalRead(Selector1), HIGH) && (digitalRead(Selector2), LOW) && (digitalRead(Selector3), LOW) && (digitalRead(Selector4), HIGH)) {
    Channel = 10; //1001
  } 
  if((digitalRead(Selector1), HIGH) && (digitalRead(Selector2), LOW) && (digitalRead(Selector3), HIGH) && (digitalRead(Selector4), LOW)) {
    Channel = 11; //1010
  } 
  if((digitalRead(Selector1), HIGH) && (digitalRead(Selector2), LOW) && (digitalRead(Selector3), HIGH) && (digitalRead(Selector4), HIGH)) {
    Channel = 12; //1011
  } 
  if((digitalRead(Selector1), HIGH) && (digitalRead(Selector2), HIGH) && (digitalRead(Selector3), LOW) && (digitalRead(Selector4), LOW)) {
    Channel = 13; //1100
  } 
  if((digitalRead(Selector1), HIGH) && (digitalRead(Selector2), HIGH) && (digitalRead(Selector3), LOW) && (digitalRead(Selector4), HIGH)) {
    Channel = 14; //1101
  } 
  if((digitalRead(Selector1), HIGH) && (digitalRead(Selector2), HIGH) && (digitalRead(Selector3), HIGH) && (digitalRead(Selector4), LOW)) {
    Channel = 15; //1110
  } 
  if((digitalRead(Selector1), HIGH) && (digitalRead(Selector2), HIGH) && (digitalRead(Selector3), HIGH) && (digitalRead(Selector4), HIGH)) {
    Channel = 16; //1111
  } 

You could digitalRead the four selector pins (in a for() loop),
and use bitSet() to change the Channel variable.
Leo..

What do you believe this does?

digitalRead(Selector3), LOW);

Hint: It does not do what you think.

This will do what your code attempts to do (but does not do correctly).

uint8_t sel = digitalRead(Selector1) | (digitalRead(Selector2) << 1) | (digitalRead(Selector3) << 2) | (digitalRead(Selector4) << 3);
sel += 1;

Compiles, untested:

const uint8_t selector[] = {3, 4, 5, 6};  // What ever your "selector" pins are

void setup() {
  uint16_t channel;
  for (uint8_t i : selector) {
    pinMode(i, INPUT_PULLUP);
  }

  channel = 0;
  for (uint8_t i : selector) {
    channel <<= 1;
    channel |= (digitalRead(i) == HIGH) ? 1 : 0;
  }

}

void loop() {
}

Thanks gfvalvo,

That code works, had to run though each option to get the channel number associated.

@Ray, you are right, my code returned them all as high. I was under the impression the statement

if (digitalRead(Selector3), LOW));

checked the Selector3 pins state and if LOW returned True

Hi,
Another method.
Assign each of the four inputs a number 1, 2, 4, 8
Read them once and calculate the total value, this value will be unique for each switch combination.
Then use switch... case to evaluate the appropriate response.

Tom... :grinning: :+1: :coffee: :australia:

Channel = ( (digitalRead(Selector1)*8) + 
(digitalRead(Selector2)*4) + 
(digitalRead(Selector3)*2) + 
(digitalRead(Selector4) );

The OP numbered channels from 1 so add 1 to the result:

Channel = (digitalRead(Selector1) * 8)
    + (digitalRead(Selector2) * 4)
    + (digitalRead(Selector3) * 2)
    + (digitalRead(Selector4) 
    + 1;