Neater way to code these choices?

I'm setting a variable using a 1P x 12W rotary switch. Some of the switch settings have an obvious relationship with the pins used. So is there a neater/smarter/more compact way to code the following please?

if (digitalRead(3) == LOW)
{
  file = 2;
}
if (digitalRead(4) == LOW)
{
  file = 3;
}
if (digitalRead(5) == LOW)
{
  file = 4;
}
if (digitalRead(6) == LOW)
{
  file = 5;
}
if (digitalRead(7) == LOW)
{
  file = 6;
}
if (digitalRead(8) == LOW)
{
  file = 7;
}

if (digitalRead(9) == LOW)
{
  file = 8;
}
if (digitalRead(10) == LOW)
{
  file = 9;
}

since you're not using else if, is there a priority? in other words, file will always be 9 if pin 10 is LOW

1 Like

Make an array with the GPIO pin numbers.

Make an array with the values file can be.

Use a for( ) loop, scan each element in the GPIO array, set file to the equivalent element.

1 Like

Or, for an alternate approach, look through this thread(it's long, look near the end). Uses a single analog input for a rotary wafer.

1 Like

consider collecting 3 of the inputs into a 3-bit value used to determine file

const byte PinInp [] = { A1, A2, A3 };
const int  Ninp = sizeof(PinInp);

byte file;
byte bitsLst;
char s [80];

void loop () 
{
    byte bits = 0;
    for (int n = 0; n < Ninp; n++) {
        bits <<= 1;
        bits |= LOW == digitalRead (PinInp [n]) ? 1 : 0;
    }

    if (bitsLst != bits)  {
        bitsLst = bits;
        delay (20);     // debounce, testing with buttons

        file = 2 + bits;
        sprintf (s, " %d bits, %d file", bits, file);
        Serial.println (s);
    }
}

void
setup (void)
{
    Serial.begin (9600);
    for (int n = 0; n < Ninp; n++)
        pinMode (PinInp [n], INPUT_PULLUP);
}
for (int i=3;i<11;i++){
  if (!digitalRead(i)){
    file = i - 1;
    break;
  }
}

have fun.. ~q

1 Like

Please elaborate.

How do we go from a 12 position selector switch to this collection of three inputs?

@Terrypin are you just not going to use but 8 of the switch positions?

Otherwise it seems this proposed collecting would need to collect 4 inputs.

a7

1 Like

i only saw 8 possible values for file.

if there are 16 or less, use 4 pins

Yes, like I said.

Now 'splain this "collecting".

a7

ok, i didn't read that the OP is using a rotary switch.

guess i'm suggesting not only a way to make the SW simpler, but the hardware as well

No priority, all mutually exclusive. And all code is in setup(), nothing in loop().

Is the resistor divider technique not of interest, or is the hardware already built? Your selections appear mutually exclusive, so using a single analog input would seem more 'frugal' than many digitals.

Thanks, looks interesting, assuming it does not need any code in loop()? Will study more closely ad report back.

consider


#if 0
const byte PinInp [] = { 3, 4, 5 };
#else
const byte PinInp [] = { A1, A2, A3 };
#endif
const int  Ninp = sizeof(PinInp);

byte file;
byte bitsLst;
char s [80];

void loop () 
{
    for (int n = 0; n < Ninp; n++) {
        if (LOW == digitalRead (PinInp [n]))  {
            file = n;
            Serial.println (n);
            break;
        }
    }
}

void
setup (void)
{
    Serial.begin (9600);
    for (int n = 0; n < Ninp; n++)
        pinMode (PinInp [n], INPUT_PULLUP);
}

Yes, hardware is already in place.

Will consider the several interesting alternative approaches for any future projects needing a single variable to be set at power-up. But for this one just want improve my code.

The project plays an MP3 file chosen before power-up, such as sea surf sound, babbling brook, etc, and fades it to silence over a user-settable duration. To set duration I'm using an analog approach: a 4K7 pot voltage to A5. But for 12 choices of sound file I thought it would be harder work getting the 12 ranges coded, and I can afford the 12 pins.

Also depends, of course, on which Arduino you're using. Some have sufficient analog in, some are scanty that way. The resistor solution is frugal only if you have analogs uncommitted.

Great, thanks, works fine! But what exactly does this command mean in plain english please?

if (!digitalRead(i))

the code in post #14 should work with your hardware

1 Like

Thanks, but looks like heavy C/C++ to my amateur eyes!

if a pin is HIGH it is also true..
the ! is the NOT operator..
in english.. if (NOT digitalRead(pin) is HIGH)

good luck.. ~q