Button / led problem

Hi. I'm building a double footswitch with led to extend to a midi controller where switch timing is vital. I've taken the basics of this code from a working project, but for some reason it doesn't "behave". The led works (as in the "intro" code and I've tested both buttons using the arduino example code, but the switches don't operate the led on/off as I'd hoped. For the simplest test, I wanted one switch to light the led, other other to switch it off.

Probably something obvious, but it's giving me headaches!

// orange 2 way box midi controller sending CC and note midi data

#define SWITCH1 2
#define SWITCH2 3
#define SWITCHES 2  // how many switches?

int switches[SWITCHES] = { SWITCH1, SWITCH2 };
int switchState[SWITCHES] = { LOW, LOW };  // Initial state of switch
int currentSwitch = 0;
const int led1 = 7;  // led 1
// int scene = 1;

unsigned long SwitchMillis = 0;     // when button was released
unsigned long DebounceMillis = 20;  //
unsigned long CurrentMillis = 0;

void setup() {
  pinMode(led1, OUTPUT);  // setup LED 1
  for (currentSwitch = 0; currentSwitch < SWITCHES; currentSwitch++) {
    pinMode(switches[currentSwitch], INPUT);      // Set pin for switch
    digitalWrite(switches[currentSwitch], HIGH);  // Turn on internal pullup
  }
  for (int i = 0; i < 5; i++)  // show "welcome" message
  {
    digitalWrite(led1, HIGH);
    delay(100);
    digitalWrite(led1, LOW);
    delay(100);
  }
}  // end setup

void loop() {

  CurrentMillis = millis();                            // get the time at the start of this loop()
  if (CurrentMillis - SwitchMillis >= DebounceMillis)  //is it time to check the switches?
  {
    SwitchMillis = millis();  //re-initilize Timer
    for (currentSwitch = 0; currentSwitch < SWITCHES; currentSwitch++) {
      if ((digitalRead(switches[currentSwitch]) != switchState[currentSwitch]) && (switchState[currentSwitch] == HIGH)) {
        switch (currentSwitch) {
          case 0:
            digitalWrite(led1, HIGH);
            break;
          case 1:
            digitalWrite(led1, LOW);
            break;
        }  // end case
      }    // end current switch
    }      // end if changed
    switchState[currentSwitch] = digitalRead(switches[currentSwitch]);
  }  // go thru switches
}  // end loop

Can yo explain what you are expecting to see? I see two switches and one led so it isn't clear how that should be controlled.

Also,

Instead, just do
pinMode(switches[currentSwitch], INPUT_PULLUP);

apologies, for the simplest test, I wanted one switch to light the led, other other to switch it off.

Hello nickrobinson

Make a check:

// orange 2 way box midi controller sending CC and note midi data

#define SWITCH1 2
#define SWITCH2 3
#define SWITCHES 2  // how many switches?

int switches[SWITCHES] = { SWITCH1, SWITCH2 };
int switchState[SWITCHES] = { LOW, LOW };  // Initial state of switch
int currentSwitch = 0;
const int led1 = 7;  // led 1
// int scene = 1;

unsigned long SwitchMillis = 0;     // when button was released
unsigned long DebounceMillis = 20;  //
unsigned long CurrentMillis = 0;

void setup() {
  pinMode(led1, OUTPUT);  // setup LED 1
  for (currentSwitch = 0; currentSwitch < SWITCHES; currentSwitch++) {
    pinMode(switches[currentSwitch], INPUT);      // Set pin for switch
    digitalWrite(switches[currentSwitch], HIGH);  // Turn on internal pullup
  }
  for (int i = 0; i < 5; i++)  // show "welcome" message
  {
    digitalWrite(led1, HIGH);
    delay(100);
    digitalWrite(led1, LOW);
    delay(100);
  }
}  // end setup

void loop() {

  CurrentMillis = millis();                            // get the time at the start of this loop()
  if (CurrentMillis - SwitchMillis >= DebounceMillis)  //is it time to check the switches?
  {
    SwitchMillis = millis();  //re-initilize Timer
    for (currentSwitch = 0; currentSwitch < SWITCHES; currentSwitch++)
    {
      //      if ((digitalRead(switches[currentSwitch]) != switchState[currentSwitch]) && (switchState[currentSwitch] == HIGH)) {
      // read current state
      uint8_t stateNew = digitalRead(switches[currentSwitch]);
      // dedect state change
      if (switchState[currentSwitch] != stateNew)
      {
        // save new state
        switchState[currentSwitch] = stateNew;
        switch (currentSwitch) {
          case 0:
            digitalWrite(led1, HIGH);
            break;
          case 1:
            digitalWrite(led1, LOW);
            break;
        }  // end case
      }    // end current switch
    }      // end if changed
    //    switchState[currentSwitch] = digitalRead(switches[currentSwitch]);
  }  // go thru switches
}  // end loop

I have added a correct state change detection, not tested.

Right now you have a for loop that reads one switch and then the other. The code to turn on or off the led is in that for loop such that either switch has complete control. The part that turns the led on or off should check currentSwitch to see which switch has been flipped.

Or even better, let the switch reading part of the code just decide which switch is in which state and set up a couple of variables to track that. Then move the part that lights leds to a separate section and write logic based only on whether those switches are flipped or not.

It works! Many thanks...

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