the following code for a midi pedal should alternate between no leds, 1 led, then both leds.
However, on the second press, both leds light up and on the third, only one. I don't understand why it's not following the apparent sequence?
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:
MIDI.sendControlChange(69, 0, scene); // snapshot
if (scene == 1) {
digitalWrite(led1, LOW); // 1 off
digitalWrite(led2, LOW); // 2 off
}
if (scene == 2) {
digitalWrite(led1, HIGH); // 1 on
}
if (scene == 3) {
digitalWrite(led2, HIGH); // 2 on
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
Yes. That said, put some serial printing in there where the LEDs are being turned on and off… how do you know your thinking is in phase with the cycle of the variable scene?
It might be a surprise. I will foolishly guess you are one step behind the sequence because you are getting one spurious event on account of how you are starting up everything.
Also assure us your LEDs are wired to be on when the pin is HIGH.
// 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 = 20; //
unsigned long CurrentMillis = 0;
void setup() {
pinMode(led1, OUTPUT); // setup LED 1
pinMode(led2, OUTPUT); // setup LED 2
// MIDI.begin(1);
Serial.begin(9600);
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:
MIDI.sendControlChange(69, 0, scene); // snapshot
if (scene == 1) {
digitalWrite(led1, LOW); // 1 off
digitalWrite(led2, LOW); // 2 off
}
if (scene == 2) {
digitalWrite(led2, HIGH); // 1 on
}
if (scene == 3) {
digitalWrite(led1, HIGH); // 2 on
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
A supplementary problem is that the actual midi values sent don't match those in the, plus it sends them twice, once when I press, the second when I release....
if (CurrentMillis - SwitchMillis >= DebounceMillis) //is it time to check the switches?
{
// stuff that only if it is time enough
SwitchMillis = CurrentMillis; // move timer along for next pass
}
Also and FWIW, since the entirety of the loop is governed by your timing mechanism, you can invert the test and the "out-dent" the controlled code.
This is desirable as it makes the code less indented. The pros try to minimise indentation depth and take measures to do.
if (CurrentMillis - SwitchMillis < DebounceMillis) // is it time to check the switches?
return; // nope, we are outta here
SwitchMillis = CurrentMillis; // move timer along then
// do the stuff that only if it is time enough