Bouncing a non latching FS

This code works, but send the midi command twice, once when I press, again when I release. Is this a bouncing issue or something else?

Thanks for your time!

// orange 2 way box midi controller sending CC and note midi data
// arduino nano old bootloader   help from Paul Paulson!
// sept 23

#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>
MIDI_CREATE_DEFAULT_INSTANCE();
// Constants
#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 = 4;  // led 1
const int led2 = 5;  // led 2
int scene = 1;

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

void setup() {
  pinMode(led1, OUTPUT);  // setup LED 1
  pinMode(led2, OUTPUT);  // setup LED 2
                          //  MIDI.begin(1);
  Serial.begin(9600);
  MIDI.begin(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 < 4; i++)  // show "welcome" message
  {
    digitalWrite(led1, HIGH);
    delay(100);
    digitalWrite(led1, LOW);
    delay(100);
    digitalWrite(led2, HIGH);
    delay(100);
    digitalWrite(led2, 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++) {
      uint8_t stateNew = digitalRead(switches[currentSwitch]);  // detect state change
      if (switchState[currentSwitch] != stateNew) {
        switchState[currentSwitch] = stateNew;  // save new state
        switch (currentSwitch) {
          case 0:
            if (scene == 1) {
              MIDI.sendControlChange(69, 0, 1);  // snapshot 1
              digitalWrite(led1, LOW);           // 1 off
              digitalWrite(led2, LOW);           // 2 off
            }
            if (scene == 2) {
              MIDI.sendControlChange(69, 1, 1);  // snapshot 2
              digitalWrite(led1, LOW);           // 1 off
              digitalWrite(led2, HIGH);          // 1 on
            }
            if (scene == 3) {
              MIDI.sendControlChange(69, 2, 2);  // snapshot 3
              digitalWrite(led1, HIGH);          // 2 on
              digitalWrite(led2, LOW);           // 1 off
              scene = 0;
            }
            scene++;
            break;
          case 1:
            MIDI.sendControlChange(61, 0, 1);  // loop stop
            break;
        }  // end case
      }    // end current switch
    }      // end if changed
  }        // go thru switches
}  // end loop

// end life

This will be true on a change from LOW to HIGH as well on a change from HIGH to LOW. After switchState[currentSwitch] = stateNew, you can decide on which of the two you want to react (L->H or H->L) using if(newState == ?).

I have replaced with this line

if ((switchState[currentSwitch] != stateNew) && (switchState[currentSwitch] == HIGH))

but it seems to stop any further progress through the switch loop

Please share your complete updated sketch in a new reply.

That is not what I described ;)

That is not what I described :wink:

probably not, I was just trying to find a solution ;(

// orange 2 way box midi controller sending CC and note midi data
// arduino nano old bootloader   help from Paul Paulson!
// sept 23

#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>
MIDI_CREATE_DEFAULT_INSTANCE();
// Constants
#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 = 4;  // led 1
const int led2 = 5;  // led 2
int scene = 1;

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

void setup() {
  pinMode(led1, OUTPUT);  // setup LED 1
  pinMode(led2, OUTPUT);  // setup LED 2
                          //  MIDI.begin(1);
  Serial.begin(9600);
  MIDI.begin(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 < 4; i++)  // show "welcome" message
  {
    digitalWrite(led1, HIGH);
    delay(100);
    digitalWrite(led1, LOW);
    delay(100);
    digitalWrite(led2, HIGH);
    delay(100);
    digitalWrite(led2, 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++) {
      uint8_t stateNew = digitalRead(switches[currentSwitch]);  // detect state change
      if ((switchState[currentSwitch] != stateNew)  && (switchState[currentSwitch] == LOW)) {
        switchState[currentSwitch] = stateNew;  // save new state
        switch (currentSwitch) {
          case 0:
            if (scene == 1) {
              MIDI.sendControlChange(69, 0, 1);  // snapshot 1
              delay(100);
              digitalWrite(led1, LOW);  // 1 off
              digitalWrite(led2, LOW);  // 2 off
            }
            if (scene == 2) {
              MIDI.sendControlChange(69, 1, 1);  // snapshot 2
              delay(100);
              digitalWrite(led1, LOW);   // 1 off
              digitalWrite(led2, HIGH);  // 1 on
            }
            if (scene == 3) {
              MIDI.sendControlChange(69, 2, 1);  // snapshot 3
              delay(100);
              digitalWrite(led1, HIGH);  // 2 on
              digitalWrite(led2, LOW);   // 1 off
              scene = 0;
            }
            scene++;
            break;
          case 1:
            MIDI.sendControlChange(61, 0, 1);  // loop stop
            break;
        }  // end case
      }    // end current switch
    }      // end if changed
  }        // go thru switches
}  // end loop

// end life

You have a bouncing file system?

Can you explain?

What does "FS" mean to you?

When you do the test that way, you might be are skipping the part where the timer state variable is updated.

   switchState[currentSwitch] = stateNew;  // save new state

has to happen whether or not you are choosing to react to the edge being observed by the difference between the reading and the stored state.

a7

Is it like FFS? :wink: