Input selector. Mode switch

Im working on an audio input selector with six buttons.

I wanna have two different modes.

  1. "Mix Mode" Any Input can be selected at any time.
  2. "Radio Mode" Only one Input can be selected at a time.

The mode switch should be a latching mini-toggle switch.

I can use pin 0 on my Arduino Uno for the mode switch.

const int modePin =  0;

How do I merge these two sketches and switch between "Mix Mode" and "Radio Mode" with the mode switch?

"Radio Mode" code

const int led1Pin =  7;    // LED pin number
const int button1 =  1;
const int led2Pin =  8; 
const int button2 =  2;
const int led3Pin =  9;
const int button3 =  3;
const int led4Pin =  10;
const int button4 =  4;
const int led5Pin =  11;
const int button5 =  5;
const int led6Pin =  12;
const int button6 =  6;
char bstate1 = 0;
char bstate2 = 0;
char bstate3 = 0;
char bstate4 = 0;
char bstate5 = 0;
char bstate6 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.
unsigned long bcount2 = 0;
unsigned long bcount3 = 0;
unsigned long bcount4 = 0;
unsigned long bcount5 = 0;
unsigned long bcount6 = 0;


// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
// Routines by Paul__B of Arduino Forum
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) { 
    *marker += interval;    // move on ready for next interval
    return true;       
  } 
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far, 
    if (button == HIGH) return false; // Nothing happening!
    else { 
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far, 
    if (button == LOW) return false; // Nothing happening!
    else { 
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else 
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else 
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    {  
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

void setup() {
  pinMode(led1Pin, OUTPUT);      
  pinMode(button1, INPUT_PULLUP); 
  pinMode(led2Pin, OUTPUT);      
  pinMode(button2, INPUT_PULLUP);      
  pinMode(led3Pin, OUTPUT);      
  pinMode(button3, INPUT_PULLUP);      
  pinMode(led4Pin, OUTPUT);      
  pinMode(button4, INPUT_PULLUP);   
  pinMode(led5Pin, OUTPUT);      
  pinMode(button5, INPUT_PULLUP);  
  pinMode(led6Pin, OUTPUT);      
  pinMode(button6, INPUT_PULLUP);      
  digitalWrite (led1Pin, LOW);
  digitalWrite (led2Pin, LOW);
  digitalWrite (led3Pin, LOW);
  digitalWrite (led4Pin, LOW);
  digitalWrite (led5Pin, LOW);
  digitalWrite (led6Pin, LOW);
}

void loop() {
  // Select LED if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    digitalWrite (led1Pin, HIGH);
    digitalWrite (led2Pin, LOW);
    digitalWrite (led3Pin, LOW);
    digitalWrite (led4Pin, LOW);
    digitalWrite (led5Pin, LOW);
    digitalWrite (led6Pin, LOW);
    delay(100);
  } 
  // Select LED if button debounced
  if (butndown(digitalRead(button2), &bcount2, &bstate2, 10UL )) {
    digitalWrite (led1Pin, LOW);
    digitalWrite (led2Pin, HIGH);
    digitalWrite (led3Pin, LOW);
    digitalWrite (led4Pin, LOW);
    digitalWrite (led5Pin, LOW);
    digitalWrite (led6Pin, LOW);
    delay(100);
  } 
  // Select LED if button debounced
  if (butndown(digitalRead(button3), &bcount3, &bstate3, 10UL )) {
    digitalWrite (led1Pin, LOW);
    digitalWrite (led2Pin, LOW);
    digitalWrite (led3Pin, HIGH);
    digitalWrite (led4Pin, LOW);
    digitalWrite (led5Pin, LOW);
    digitalWrite (led6Pin, LOW);
    delay(100);
  } 
  if (butndown(digitalRead(button4), &bcount4, &bstate4, 10UL )) {
    // Select LED if button debounced
    digitalWrite (led1Pin, LOW);
    digitalWrite (led2Pin, LOW);
    digitalWrite (led3Pin, LOW);
    digitalWrite (led4Pin, HIGH);
    digitalWrite (led5Pin, LOW);
    digitalWrite (led6Pin, LOW);
    delay(100);      
     } 
  if (butndown(digitalRead(button5), &bcount5, &bstate5, 10UL )) {
    // Select LED if button debounced
    digitalWrite (led1Pin, LOW);
    digitalWrite (led2Pin, LOW);
    digitalWrite (led3Pin, LOW);
    digitalWrite (led4Pin, LOW);
    digitalWrite (led5Pin, HIGH);
    digitalWrite (led6Pin, LOW);
    delay(100);    
      } 
  if (butndown(digitalRead(button6), &bcount6, &bstate6, 10UL )) {
    // Select LED if button debounced
    digitalWrite (led1Pin, LOW);
    digitalWrite (led2Pin, LOW);
    digitalWrite (led3Pin, LOW);
    digitalWrite (led4Pin, LOW);
    digitalWrite (led5Pin, LOW);
    digitalWrite (led6Pin, HIGH);
    delay(100);   
  } 
}

"Mix Mode" code

// Multiple toggles!
const int led1Pin =  7;    // LED pin number
const int button1 =  1;
const int led2Pin =  8; 
const int button2 =  2;
const int led3Pin =  9;
const int button3 =  3;
const int led4Pin =  10;
const int button4 =  4;
const int led5Pin =  11;
const int button5 =  5;
const int led6Pin =  12;
const int button6 =  6;
char bstate1 = 0;
char bstate2 = 0;
char bstate3 = 0;
char bstate4 = 0;
char bstate5 = 0;
char bstate6 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.
unsigned long bcount2 = 0;
unsigned long bcount3 = 0;
unsigned long bcount4 = 0;
unsigned long bcount5 = 0;
unsigned long bcount6 = 0;

char led1State = LOW;        // initialise the LED
char led2State = LOW;
char led3State = LOW;
char led4State = LOW;
char led5State = LOW;
char led6State = LOW;

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
// Routines by Paul__B of Arduino Forum
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) { 
    *marker += interval;    // move on ready for next interval
    return true;       
  } 
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far, 
    if (button == HIGH) return false; // Nothing happening!
    else { 
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far, 
    if (button == LOW) return false; // Nothing happening!
    else { 
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else 
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else 
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    {  
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

// ----------------------------- toggle ------------------------------------------
char toggle(char *flip) {   // Yes, it toggles the variable pointed to
  if (*flip == LOW) {
    *flip = HIGH;
  }
  else {
    *flip = LOW; 
  } 
  return *flip;
}

void setup() {
  pinMode(led1Pin, OUTPUT);      
  pinMode(button1, INPUT_PULLUP); 
  pinMode(led2Pin, OUTPUT);      
  pinMode(button2, INPUT_PULLUP);      
  pinMode(led3Pin, OUTPUT);      
  pinMode(button3, INPUT_PULLUP);      
  pinMode(led4Pin, OUTPUT);      
  pinMode(button4, INPUT_PULLUP);   
  pinMode(led5Pin, OUTPUT);      
  pinMode(button5, INPUT_PULLUP);   
  pinMode(led6Pin, OUTPUT);      
  pinMode(button6, INPUT_PULLUP);      
  digitalWrite (led1Pin, LOW);
  digitalWrite (led2Pin, LOW);
  digitalWrite (led3Pin, LOW);
  digitalWrite (led4Pin, LOW);
  digitalWrite (led5Pin, LOW);
  digitalWrite (led6Pin, LOW);
}

void loop() {
  // Toggle LED if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    toggle(&led1State);
    digitalWrite(led1Pin, led1State);
  } 

  if (butndown(digitalRead(button2), &bcount2, &bstate2, 10UL )) {
    toggle(&led2State);
    digitalWrite(led2Pin, led2State);
  } 

  if (butndown(digitalRead(button3), &bcount3, &bstate3, 10UL )) {
    toggle(&led3State);
    digitalWrite(led3Pin, led3State);
  } 

  if (butndown(digitalRead(button4), &bcount4, &bstate4, 10UL )) {
    toggle(&led4State);
    digitalWrite(led4Pin, led4State);
  } 

  if (butndown(digitalRead(button5), &bcount5, &bstate5, 10UL )) {
  toggle(&led5State);
  digitalWrite(led5Pin, led5State);
  } 

  if (butndown(digitalRead(button6), &bcount6, &bstate6, 10UL )) {
  toggle(&led6State);
  digitalWrite(led6Pin, led6State);
} 
}

Hello, you can simply change names of data in Mix Mode, for example if you have

you can rename it as "const int Mled2Pin =8;" :+1:
Paste code of two projects in one file
Than make two main voids. Radio Mode and Mix Mode
And and call this void from the click of a button.

1 Like

Sure about that? Pins 0 and 1 are dedicated to serial comms with the IDE.

What happens to switch X when mode is changed?

1 Like

Hello buffalo_tom

Check, study and fine tune to your project needs.

#define ProjectName "Input selector. Mode switch"
/* BLOCK COMMENT
  - https://forum.arduino.cc/t/input-selector-mode-switch/1109707
  https://europe1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg
*/
#define usl unsigned long // I am too lazy to type
// make names
enum Modes {RadioMode, MixMode};
// make variables
constexpr int ModePin {3}; 
// make structures
struct BUTTON2LED
{
  const int LedPin;
  const int ButtonPin;
  int stateOld;
  usl previousMillis;
  const usl IntervalMillis;
};
BUTTON2LED button2Leds []
{
  {8, A0, LOW,  0, 20},
  {9, A1, LOW,  0, 20},
  {10, A2, LOW,  0, 20},
  {11, A3, LOW,  0, 20},
  {12, A4, LOW,  0, 20},
  // add led button combinations
};
// tools
void heartBeat(int LedPin, usl currentMillis)
{
  static bool setUp = false;
  if (!setUp) pinMode (LedPin, OUTPUT), setUp = !setUp;
  digitalWrite(LedPin, (currentMillis / 500) % 2);
}
void setup()
{
  Serial.begin(115200);
  Serial.println(ProjectName);
  Serial.println(__FILE__);
  Serial.println(__DATE__);
  Serial.println(__TIME__);
  pinMode (ModePin, INPUT_PULLUP);
  Serial.print(F("mode selected = ")), Serial.println(digitalRead(ModePin) ? (F("mixed mode")) : (F("radio mode")));
  for (auto &button2Led : button2Leds)
  {
    pinMode(button2Led.ButtonPin, INPUT_PULLUP);
    pinMode(button2Led.LedPin, OUTPUT);
    digitalWrite(button2Led.LedPin, HIGH);
    delay(1000);
    digitalWrite(button2Led.LedPin, LOW);
  }
}
void loop()
{
  usl currentMillis = millis();
  heartBeat(LED_BUILTIN, currentMillis);
  for (auto &button2Led : button2Leds)
  {
    if (currentMillis - button2Led.previousMillis >= button2Led.IntervalMillis)
    {
      button2Led.previousMillis = currentMillis;
      int stateNew = digitalRead(button2Led.ButtonPin) ? LOW : HIGH;
      if (button2Led.stateOld != stateNew)
      {
        button2Led.stateOld = stateNew;
        if (stateNew == HIGH)
        {
          if (digitalRead(ModePin) == RadioMode)
          {
            for (auto &button2Led : button2Leds) digitalWrite(button2Led.LedPin, LOW);
          }
          digitalWrite(button2Led.LedPin, digitalRead(button2Led.LedPin) ? LOW : HIGH);
        }
      }
    }
  }
}
//------------------------------------------------------------

Have a nice day and enjoy coding in C++.

1 Like

Thanks! After some testing back and forth I believe I got it right.. It works!

const int ModeSwitch = 13; // Selecet Mode

const int led1Pin =  7;    
const int button1 =  1;
const int led2Pin =  8; 
const int button2 =  2;
const int led3Pin =  9;
const int button3 =  3;
const int led4Pin =  10;
const int button4 =  4;
const int led5Pin =  11;
const int button5 =  5;
const int led6Pin =  12;
const int button6 =  6;

const int Mled1Pin =  7;    
const int Mbutton1 =  1;
const int Mled2Pin =  8; 
const int Mbutton2 =  2;
const int Mled3Pin =  9;
const int Mbutton3 =  3;
const int Mled4Pin =  10;
const int Mbutton4 =  4;
const int Mled5Pin =  11;
const int Mbutton5 =  5;
const int Mled6Pin =  12;
const int Mbutton6 =  6;

char bstate1 = 0;
char bstate2 = 0;
char bstate3 = 0;
char bstate4 = 0;
char bstate5 = 0;
char bstate6 = 0;

unsigned long bcount1 = 0; // button debounce timer.
unsigned long bcount2 = 0;
unsigned long bcount3 = 0;
unsigned long bcount4 = 0;
unsigned long bcount5 = 0;
unsigned long bcount6 = 0;

char led1State = LOW;        // initialise the LED
char led2State = LOW;
char led3State = LOW;
char led4State = LOW;
char led5State = LOW;
char led6State = LOW;

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
// Routines by Paul__B of Arduino Forum
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) { 
    *marker += interval;    // move on ready for next interval
    return true;       
  } 
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far, 
    if (button == HIGH) return false; // Nothing happening!
    else { 
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far, 
    if (button == LOW) return false; // Nothing happening!
    else { 
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else 
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else 
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    {  
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

// ----------------------------- toggle ------------------------------------------
char toggle(char *flip) {   // Yes, it toggles the variable pointed to
  if (*flip == LOW) {
    *flip = HIGH;
  }
  else {
    *flip = LOW; 
  } 
  return *flip;
}

void setup()
{

pinMode(ModeSwitch, INPUT_PULLUP); 

pinMode(Mled1Pin, OUTPUT);      
pinMode(Mbutton1, INPUT_PULLUP); 
pinMode(Mled2Pin, OUTPUT);      
pinMode(Mbutton2, INPUT_PULLUP);      
pinMode(Mled3Pin, OUTPUT);      
pinMode(Mbutton3, INPUT_PULLUP);      
pinMode(Mled4Pin, OUTPUT);      
pinMode(Mbutton4, INPUT_PULLUP);   
pinMode(Mled5Pin, OUTPUT);      
pinMode(Mbutton5, INPUT_PULLUP);   
pinMode(Mled6Pin, OUTPUT);      
pinMode(Mbutton6, INPUT_PULLUP);      
digitalWrite (Mled1Pin, LOW);
digitalWrite (Mled2Pin, LOW);
digitalWrite (Mled3Pin, LOW);
digitalWrite (Mled4Pin, LOW);
digitalWrite (Mled5Pin, LOW);
digitalWrite (Mled6Pin, LOW);

}

void loop()
{

int buttonState = digitalRead(ModeSwitch);
if (buttonState == HIGH) {
MixMode();
} else {
RadioMode();
}
}

void MixMode()

{
  // Toggle LED if button debounced
  if (butndown(digitalRead(Mbutton1), &bcount1, &bstate1, 10UL )) {
    toggle(&led1State);
    digitalWrite(Mled1Pin, led1State);
  } 

  if (butndown(digitalRead(Mbutton2), &bcount2, &bstate2, 10UL )) {
    toggle(&led2State);
    digitalWrite(Mled2Pin, led2State);
  } 

  if (butndown(digitalRead(Mbutton3), &bcount3, &bstate3, 10UL )) {
    toggle(&led3State);
    digitalWrite(Mled3Pin, led3State);
  } 

  if (butndown(digitalRead(Mbutton4), &bcount4, &bstate4, 10UL )) {
    toggle(&led4State);
    digitalWrite(Mled4Pin, led4State);
  } 

  if (butndown(digitalRead(Mbutton5), &bcount5, &bstate5, 10UL )) {
  toggle(&led5State);
  digitalWrite(Mled5Pin, led5State);
  } 

  if (butndown(digitalRead(Mbutton6), &bcount6, &bstate6, 10UL )) {
  toggle(&led6State);
  digitalWrite(Mled6Pin, led6State);
} 
}


void RadioMode()
{
  // Select LED if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    digitalWrite (led1Pin, HIGH);
    digitalWrite (led2Pin, LOW);
    digitalWrite (led3Pin, LOW);
    digitalWrite (led4Pin, LOW);
    digitalWrite (led5Pin, LOW);
    digitalWrite (led6Pin, LOW);
    delay(100);
  } 
  // Select LED if button debounced
  if (butndown(digitalRead(button2), &bcount2, &bstate2, 10UL )) {
    digitalWrite (led1Pin, LOW);
    digitalWrite (led2Pin, HIGH);
    digitalWrite (led3Pin, LOW);
    digitalWrite (led4Pin, LOW);
    digitalWrite (led5Pin, LOW);
    digitalWrite (led6Pin, LOW);
    delay(100);
  } 
  // Select LED if button debounced
  if (butndown(digitalRead(button3), &bcount3, &bstate3, 10UL )) {
    digitalWrite (led1Pin, LOW);
    digitalWrite (led2Pin, LOW);
    digitalWrite (led3Pin, HIGH);
    digitalWrite (led4Pin, LOW);
    digitalWrite (led5Pin, LOW);
    digitalWrite (led6Pin, LOW);
    delay(100);
  } 
  if (butndown(digitalRead(button4), &bcount4, &bstate4, 10UL )) {
    // Select LED if button debounced
    digitalWrite (led1Pin, LOW);
    digitalWrite (led2Pin, LOW);
    digitalWrite (led3Pin, LOW);
    digitalWrite (led4Pin, HIGH);
    digitalWrite (led5Pin, LOW);
    digitalWrite (led6Pin, LOW);
    delay(100);      
     } 
  if (butndown(digitalRead(button5), &bcount5, &bstate5, 10UL )) {
    // Select LED if button debounced
    digitalWrite (led1Pin, LOW);
    digitalWrite (led2Pin, LOW);
    digitalWrite (led3Pin, LOW);
    digitalWrite (led4Pin, LOW);
    digitalWrite (led5Pin, HIGH);
    digitalWrite (led6Pin, LOW);
    delay(100);    
      } 
  if (butndown(digitalRead(button6), &bcount6, &bstate6, 10UL )) {
    // Select LED if button debounced
    digitalWrite (led1Pin, LOW);
    digitalWrite (led2Pin, LOW);
    digitalWrite (led3Pin, LOW);
    digitalWrite (led4Pin, LOW);
    digitalWrite (led5Pin, LOW);
    digitalWrite (led6Pin, HIGH);
    delay(100);   
  } 
}
1 Like

Ok! Im using pin 13 now.. But pin 1 is still used for a button... It works

T@paulpaulson

Thanks a lot for the code. Will definitely look into this!

You are welcome :blush:

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.