switch case or if/else

Hello,
what I want to do is straightforward I think but I’m getting stuck on how exactly to implement it.

I am making a MIDI foot pedal with 5 buttons. I want to be able to choose between toggle and momentary, using a dip switch for each button. So the logic in psuedo code would be
dip switch is either on or off
on = momentary
off=toggle
if (on) then button sends the same MIDI message out every press (CC1, value 64)
if (off) then button uses a state change code to monitor whether it’s high or low, and sends out (value 64) and (value 0) alternately.

So far, the things I’ve tried haven’t worked. The toggle code works just fine, and I know how momentary should work, but knowing where to put the condition in is slowing me down. I think what’s confusing me mostly is how to do this with an array of buttons

Here’s my code as of last night when I gave up in exasperation: I look forward to your comments, cynicism, and help.

// CODE EXAMPLE FROM ADAFRUIT

#define DEBOUNCE 10  // button debouncer, how many ms to debounce, 5+ ms is usually plenty

// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {
  3, 4, 5, 6, 7, 8, 16, 17, 18, 19}; // the analog 0-5 pins are also known as 14-19
//pins 8 -19 are auxiliary inputs which will be turned off by
//default at a 10x microswitch, in turn wired to a VGA 15 pin socket for future expansion

// This handy macro lets us determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)
// we will track if a button is just pressed, just released, or 'currently pressed' 
byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];


//Microswitches allow user to change mode of foot switches from momentary to latching
int modeSelect[5] ={
  9, 10, 11, 12, 13};



int number = 5; //CC number
int val = 0; //CC value
boolean state = 0; // check state of button for toggle


//________________POT 
int pot = 14;
//int val = 0;
int threshold = 1;
int oldVal[6];
//_______________/POT


void setup() {
  byte i;

  // set up serial port
  Serial.begin(31250);
  // Serial.print("Button checker with ");
  //  Serial.print(NUMBUTTONS, DEC);
  //Serial.println(" buttons");
  //______________MODE SELECTOR CONDITIONAL CODE
  //if dip switch is high, then button acts as a toggle switch, executing the state change code
  //otherwise, if dipswitch is low, the button acts as a momentary, sending out the same
  //midi message everytime it's pressed.

  // Make input & enable pull-up resistors on switch pins
  for (i=0; i< NUMBUTTONS; i++) {
    pinMode(buttons[i], INPUT_PULLUP);
    digitalWrite(buttons[i], HIGH);
  }

  pinMode(pot, INPUT);
  //initialise dipswitches for mode selection
  for (i=0; i< 5; i++) {
    pinMode(modeSelect[i], INPUT_PULLUP);
    digitalWrite(modeSelect[i], HIGH);
  }
}

void check_switches()
{
  static byte previousstate[NUMBUTTONS];
  static byte currentstate[NUMBUTTONS];
  static long lasttime;
  byte index;

  if (millis() < lasttime) {
    // we wrapped around, lets just try again
    lasttime = millis();
  }

  if ((lasttime + DEBOUNCE) > millis()) {
    // not enough time has passed to debounce
    return; 
  }
  // ok we have waited DEBOUNCE milliseconds, lets reset the timer
  lasttime = millis();

  for (index = 0; index < NUMBUTTONS; index++) {
    justpressed[index] = 0;       // when we start, we clear out the "just" indicators
    justreleased[index] = 0;

    currentstate[index] = digitalRead(buttons[index]);   // read the button

    /*     
     Serial.print(index, DEC);
     Serial.print(": cstate=");
     Serial.print(currentstate[index], DEC);
     Serial.print(", pstate=");
     Serial.print(previousstate[index], DEC);
     Serial.print(", press=");
     */

    if (currentstate[index] == previousstate[index]) {
      if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
        // just pressed
        justpressed[index] = 1;
      }
      else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
        // just released
        justreleased[index] = 1;
      }
      pressed[index] = !currentstate[index];  // remember, digital HIGH means NOT pressed
    }
    //Serial.println(pressed[index], DEC);
    previousstate[index] = currentstate[index];   // keep a running tally of the buttons
  }
}


void loop() {

//_______________TOGGLE BUTTON CODE_____________________
  for (byte i = 0; i < 5; i++) { //check dipswitches 
    if (digitalRead (modeSelect[i] == LOW)){ // if dipswitch is low, run toggle code
      check_switches();      // when we check the switches we'll get the current state

      for (byte i = 0; i < NUMBUTTONS; i++) {
        if (justpressed[i]) {
          if(state)
          {
            state = !state; 
            CC(0, number + i, 64);
          }
          else
          {
            state = !state; 
            CC(0, number + i, 0);
          }
        }
      }
    } 
//__________________MOMENTARY BUTTON CODE_______________________
    else{
      for (byte i = 0; i < NUMBUTTONS; i++) { //attempt at momentary mode. Want button to always send out value 64 at relevant CC number
        if (digitalRead (buttons[i] == LOW)){
          CC(0, number + i, 64);
        }
      }
    }
  }
//_________________END BUTTON CODE____________________________
  //____________________EXPRESSION PEDAL CODE_____________________
  for (int i = 0; i<6;i++){ // look at the analogue inputs one at a time
    val = analogRead(pot); // get the analogue input value
    val >> 2;
    // compare it to what you had last time
    if (abs(val - oldVal[i]) > threshold) {
      // Serial.println(val);
      //  delay(100);
      CC(0, 10, val/8); //1023 divided by 8 scales to range 0-127
    }
    oldVal[i] = val; // store the reading in the array for next time
    delay(10); // send the reading out if it has changed a lot
  }
  //________________END EXPRESSION PEDAL CODE_____________________
}
// Continuos Controller Function
void CC(int ChannelByte,int ControlNumber,int ControlValue){
  Serial.write(ChannelByte + 0xb0);
  Serial.write(ControlNumber);
  Serial.write(ControlValue);
}
byte buttons[] = {

The values aren't buttons. They are pin numbers. Your variable name should reflect that.

int modeSelect[5] ={
  9, 10, 11, 12, 13};

The values have nothing to do with any mode being selected. You variable name should reflect what the values actually mean.

int oldVal[6];

The old value of what?

  static byte previousstate[NUMBUTTONS];
  static byte currentstate[NUMBUTTONS];

camelCase is the norm, for a reason.

  static long lasttime;

Does time run backwards in your universe? If not, it's unsigned long!

Beyond that, I got confused about what you are doing. The variable names make no sense, unless you refer back to the comments. Good names don't need comments.

Putting every { on a new line would help you see the structure of the code. The way it is, I can't see it.

You don't need three variables representing the state of each switch pin to determine if the switch just became pressed, just became released, or has not changed state. Using three is too confusing.

Mixing global and static arrays is confusing. Stick with one form. You have 5 variables (arrays) that define the state of a given pin - pressed, justpressed, justreleased, previousstate, and currentstate. Surely you don't need that many. The switch is pressed, or it isn't. The switch changed state or it didn't.

Hi PaulS,

most of the things you mention there are taken directly from a page on adafruit.com. I’ve cleaned them up as best I can so hopefully it’s a bit easier to read. Thanks for the { tip, it does make the code a lot easier to follow :slight_smile:
There’s a lot of extra stuff I don’t need in the adafruit code, I’ll try hacking it back a bit to see what I can do without. However, this code works fine for toggling the buttons, but what I’m looking for is a way of changing the behaviour of the buttons depending on the state of the dip switches.

oldCcVal is for smoothing values coming in off the expression pedal.

Here’s the code, cleaned up a bit:

#define DEBOUNCE 10  // button debouncer, how many ms to debounce, 5+ ms is usually plenty

byte buttons[] = {
  3, 4, 5, 6, 7, 8, 16, 17, 18, 19}; 
//pins 8 -19 are auxiliary inputs

// This handy macro lets us determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)
// we will track if a button is just pressed, just released, or 'currently pressed' 
byte pressed[NUMBUTTONS], justPressed[NUMBUTTONS], justReleased[NUMBUTTONS];

int dipSwitch[5] ={
  9, 10, 11, 12, 13};

int ccNumber = 5;
int ccVal = 0; 
boolean state = 0; // check state of button for toggle


//________________POT 
int pot = 14;
int threshold = 1;
int oldCcVal[6];
//_______________/POT


void setup() {


  Serial.begin(31250);


  // Make input & enable pull-up resistors on switch pins
  byte i;
  for (i=0; i< NUMBUTTONS; i++) 
  {
    pinMode(buttons[i], INPUT_PULLUP);
    digitalWrite(buttons[i], HIGH);
  }

  pinMode(pot, INPUT);
  //initialise dipswitches for mode selection
  for (i=0; i< 5; i++) 
  {
    pinMode(dipSwitch[i], INPUT_PULLUP);
    digitalWrite(dipSwitch[i], HIGH);
  }
}

void check_switches()
{
  static byte previousState[NUMBUTTONS];
  static byte currentState[NUMBUTTONS];
  unsigned long lasttime;
  byte index;

  if (millis() < lasttime) 
  {
    lasttime = millis();
  }

  if ((lasttime + DEBOUNCE) > millis()) 
  {
    return; 
  }
  // ok we have waited DEBOUNCE milliseconds, lets reset the timer
  lasttime = millis();

  for (index = 0; index < NUMBUTTONS; index++) 
  {
    justPressed[index] = 0;       // when we start, we clear out the "just" indicators
    justReleased[index] = 0;

    currentState[index] = digitalRead(buttons[index]);   // read the button

    if (currentState[index] == previousState[index]) {
      if ((pressed[index] == LOW) && (currentState[index] == LOW)) {
        // just pressed
        justPressed[index] = 1;
      }
      else if ((pressed[index] == HIGH) && (currentState[index] == HIGH)) {
        // just released
        justReleased[index] = 1;
      }
      pressed[index] = !currentState[index];  // remember, digital HIGH means NOT pressed
    }
    //Serial.println(pressed[index], DEC);
    previousState[index] = currentState[index];   // keep a running tally of the buttons
  }
}


void loop() {
  for (byte i = 0; i < 5; i++) 
  { //check dipswitches 
    if (digitalRead (dipSwitch[i] == LOW))
    { 
      check_switches();      // when we check the switches we'll get the current state

      for (byte i = 0; i < NUMBUTTONS; i++) 
      {
        if (justPressed[i]) 
        {
          if(state)
          {
            state = !state; 
            CC(0, ccNumber + i, 64);
          }
          else
          {
            state = !state; 
            CC(0, ccNumber + i, 0);
          }
        }
      }
    } 
    else
    {
      for (byte i = 0; i < NUMBUTTONS; i++) 
      { //attempt at momentary mode. Want button to always send out value 64 at relevant CC number
        if (digitalRead (buttons[i] == LOW))
        {
          CC(0, ccNumber + i, 64);
        }
      }
    }
  }
  //____________________EXPRESSION PEDAL CODE_____________________
  for (int i = 0; i<6;i++)
  { // look at the analogue inputs one at a time
    ccVal = analogRead(pot); // get the analogue input value
    ccVal >> 2;
    // compare it to what you had last time
    if (abs(ccVal - oldCcVal[i]) > threshold) 
    {
      CC(0, 10, ccVal/8); //1023 divided by 8 scales to range 0-127
    }
    oldCcVal[i] = ccVal; // store the reading in the array for next time
    delay(10); // send the reading out if it has changed a lot
  }
  //________________END EXPRESSION PEDAL CODE_____________________
}


// Continuos Controller Function
void CC(int ChannelByte,int ControlNumber,int ControlValue){
  Serial.write(ChannelByte + 0xb0);
  Serial.write(ControlNumber);
  Serial.write(ControlValue);
}

I think here is where my (main) problem is

    else
    {
      for (byte i = 0; i < NUMBUTTONS; i++) 
      { //attempt at momentary mode. Want button to always send out value 64 at relevant CC number
        if (digitalRead (buttons[i] == LOW))
        {
          CC(0, ccNumber + i, 64);
        }
      }
    }
  }

what I want here is is the dipSwitch = low, then buttons should send out the value 64 instead of 0

I think here is where my (main) problem is

It isn't clear what your (main) problem is.

what I want here is is the dipSwitch[] = low, then buttons[] should send out the value 64 instead of 0

What does the code ACTUALLY do?

my main problem is, the code I have posted above doesn't work, and in frustration I am coming to the forums looking for some help or pointers in the right direction.

Right now, the dip switches aren't implemented well / at all. What I'm looking for is an example of code where one button influences what code another button presses.

SO my main problem can be broken down as follows. button 1 can either do This, or That. Which of these it will do is determined by dip switch 1 (high =This, low = That)

It's pretty simple to understand, I'm just getting bogged down in how to actually go about doing it.

What I'm looking for is an example of code where one button influences what code another button presses.

Unless you have a servo, set up just right, code does not press buttons.

button 1 can either do This, or That. Which of these it will do is determined by dip switch 1 (high =This, low = That)

Do you know that you are even reading the switch state correctly? How ARE the switches wired?

buttonState = digitalRead(buttonPin);
if (digitalRead(dipSwitch) == HIGH)
{
  if (buttonState == HIGH)
  {
    //do this -  dip switch HIGH/button HIGH
  }
  else
  {
    //do this -  dip switch HIGH/button LOW
  }
}

else
  if (buttonState == HIGH)
  {
    //do this -  dip switch LOW/button HIGH
  }
  else
  {
    //do this -  dip switch LOW/button LOW
  }

thanks for being helpful UKHeliBob, I'll give that a go now.