I’ve got Pin F4 set as an input, and pulled up internally. Metering it shows that it does indeed have 5V relative to ground, but the program is reading the port as low.
Code pasted below; this is a troubleshooting build. The problem is on the button referred to as constant "Prev". I replaced the normal code on that input with code that just sets the LED to either red or green depending on input state.
I'm actually having this problem on 3 other inputs as well, while the "Go", "Stop", and "Aux1" inputs are working perfectly fine.
Any ideas what might be wrong?
Thanks,
Andy
Code: Select all
#include <MIDI.h>
#include <Debounce.h>
#include <EEPROM.h>
/*
v2.0, build 092511
Port to ATmega32u4 via Teensyduino
Combination MIDI and USB
This section is where the messages sent on each button press/release are defined
There are two functions for each button, Press and Release. There is also a ToggleA and ToggleB function for the Aux 1 button.
Messages to be sent during each function should be entered as per the standard Arduino MIDI library or
the Teensyduino USB MIDI library, as appropriate. (Message formats are the same for both)
ex:
usbMIDI.sendNoteOn(note, velocity, channel)
usbMIDI.sendNoteOff(note, velocity, channel)
usbMIDI.sendPolyPressure(note, pressure, channel)
usbMIDI.sendControlChange(control, value, channel)
usbMIDI.sendProgramChange(program, channel)
usbMIDI.sendAfterTouch(pressure, channel)
usbMIDI.sendPitchBend(value, channel)
usbMIDI.sendSysEx(length, array)
Initially, these are programmed to send a Note On at 127 for each press, and a Note Off for each release, all on channel 1
*/
void PressGo()
{
usbMIDI.sendNoteOn(0, 127, 1);
//MIDI.sendNoteOn(0, 127, 1);
LEDblink();
}
void ReleaseGo()
{
usbMIDI.sendNoteOff(0, 127, 1);
//MIDI.sendNoteOff(0, 127, 1);
LEDblink();
}
void PressPrev()
{
usbMIDI.sendNoteOn(1, 127, 1);
//MIDI.sendNoteOn(1, 127, 1);
LEDblink();
}
void ReleasePrev()
{
usbMIDI.sendNoteOff(1, 127, 1);
//MIDI.sendNoteOff(1, 127, 1);
LEDblink();
}
void PressNext()
{
usbMIDI.sendNoteOn(2, 127, 1);
//MIDI.sendNoteOn(2, 127, 1);
LEDblink();
}
void ReleaseNext()
{
usbMIDI.sendNoteOff(2, 127, 1);
//MIDI.sendNoteOff(2, 127, 1);
LEDblink();
}
void PressStop()
{
usbMIDI.sendNoteOn(3, 127, 1);
//MIDI.sendNoteOn(3, 127, 1);
LEDblink();
}
void ReleaseStop()
{
usbMIDI.sendNoteOff(3, 127, 1);
//MIDI.sendNoteOff(3, 127, 1);
LEDblink();
}
void PressAux1()
{
usbMIDI.sendNoteOn(4, 127, 1);
//MIDI.sendNoteOn(4, 127, 1);
LEDblink();
}
void ReleaseAux1()
{
usbMIDI.sendNoteOff(4, 127, 1);
//MIDI.sendNoteOff(4, 127, 1);
LEDblink();
}
void ToggleA()
{
usbMIDI.sendNoteOn(5, 127, 1);
//MIDI.sendNoteOn(5, 127, 1);
LEDgreenON();
}
void ToggleB()
{
usbMIDI.sendNoteOff(5, 127, 1);
//MIDI.sendNoteOff(5, 127, 1);
LEDredON();
}
void PressAux2()
{
usbMIDI.sendNoteOn(5, 127, 1);
//MIDI.sendNoteOn(5, 127, 1);
LEDblink();
}
void ReleaseAux2()
{
usbMIDI.sendNoteOff(5, 127, 1);
//MIDI.sendNoteOff(5, 127, 1);
LEDblink();
}
void PressFoot()
{
usbMIDI.sendNoteOn(6, 127, 1);
//MIDI.sendNoteOn(6, 127, 1);
LEDblink();
}
void ReleaseFoot()
{
usbMIDI.sendNoteOff(6, 127, 1);
//MIDI.sendNoteOff(6, 127, 1);
LEDblink();
}
//Global declarations and other general housekeeping
int DoubleGoWindow;
#define DoubleGoDefault 250 //Value (in ms) for Double Go protection
#define DebounceVal 60 //Value (in ms) for regular debounce
#define LEDbrightness 2 // Set analog level (0-255) for LED
#define Go PIN_B0
#define Prev PIN_F4
#define Next PIN_B4
#define Stop PIN_B3
#define Aux1 PIN_D2
#define Aux2 PIN_F7
#define Foot PIN_D7
#define FootLED PIN_D6
#define LEDgreen PIN_B6
#define LEDred PIN_B7
//define variables for soft mode selection
int FootMode;
int AuxMode;
//define constants for tracking LED status, green=0, red=1
#define green 0
#define red 1
//define constants for Aux Mode and Footswitch Mode
#define aux 1
#define gpo 0
#define independent 1
#define mirror 0
//define constants for tracking contact closure, open=1, closed=0
#define open 0
#define closed 1
//define constants for button status values, inputs are using pull-ups, so pressed=LOW (0), released=HIGH (1)
#define pressed 0
#define released 1
//set variables for tracking button statuses, etc
unsigned long TimeOfLastGo = millis() - DoubleGoWindow;
unsigned long TimeOfLastGoRelease = millis() - DoubleGoWindow;
unsigned long TimeOfLastFootPress = millis() - DoubleGoWindow;
unsigned long TimeOfLastFootRelease = millis() - DoubleGoWindow;
unsigned long currentMillis = millis();
int LastGoSent = released;
//Set TimeOfLastGo so that first go can go instaneously. Never likely to be needed, but let's dot t's and cross i's
int CurrentGo=1;
int CurrentPrev=1;
int CurrentNext=1;
int CurrentStop=1;
int CurrentAux1=1;
int CurrentAux2=1;
int CurrentFoot=1;
int ChangedGo=0;
int ChangedPrev=0;
int ChangedNext=0;
int ChangedStop=0;
int ChangedAux1=0;
int ChangedAux2=0;
int ChangedFoot=0;
int InitialFoot;
byte CurrentContactState;
byte LastAux2=released;
byte CurrentLED;
// Constants for EEPROM addresses
#define EEPROMgpo 0
#define EEPROMaux 1
#define EEPROMfoot 2
#define EEPROMdoublego 3 //this value will be stored in two bytes, ending up in 3 and 4
//Set up debounce objects
Debounce debounceGo = Debounce( DebounceVal , Go ); // Initiate a debounce object for Go pin, with a 20 ms debounce time
Debounce debouncePrev = Debounce( DebounceVal , Prev ); // Initiate a debounce object for Prev pin, with a 20 ms debounce time
Debounce debounceNext = Debounce( DebounceVal , Next ); // Initiate a debounce object for Next pin, with a 20 ms debounce time
Debounce debounceStop = Debounce( DebounceVal , Stop ); // Initiate a debounce object for Stop pin, with a 20 ms debounce time
Debounce debounceAux1 = Debounce( DebounceVal , Aux1 ); // Initiate a debounce object for Aux1 pin, with a 20 ms debounce time
Debounce debounceAux2 = Debounce( DebounceVal , Aux2 ); // Initiate a debounce object for Aux2 pin, with a 20 ms debounce time
Debounce debounceFoot = Debounce( DebounceVal , Foot ); //Initiate a debounce object for Footswitch pin, with a 20 ms debounce time
//++++++++++++++++++++++++++++++++++++
void LEDgreenON()
{
analogWrite(LEDgreen, LEDbrightness);
digitalWrite(LEDred, LOW);
CurrentLED=green;
}
//++++++++++++++++++++++++++++++++++++
void LEDredON()
{
analogWrite(LEDred, LEDbrightness);
digitalWrite(LEDgreen, LOW);
CurrentLED=red;
}
//++++++++++++++++++++++++++++++++++++
void LEDoff()
{
digitalWrite(LEDgreen, LOW);
digitalWrite(LEDred, LOW);
}
//++++++++++++++++++++++++++++++++++++
void LEDtoggle(){
//LED is a bi-color LED, color determined by which pin is on (high); both pins the same (either high or low) turns it off
LEDoff();
if (CurrentLED==green)
{
LEDredON();
}
else
{
LEDgreenON();
}
}
//++++++++++++++++++++++++++++++++++++
void LEDblink()
{
//blinks LED opposite color for 50 ms
LEDtoggle();
delay(50);
LEDtoggle();
/* Commenting out for more tidy method using LEDtoggle()
if (CurrentLED==green){
digitalWrite(LEDgreen, LOW);
digitalWrite(LEDred, HIGH);
delay(20);
digitalWrite(LEDgreen, HIGH);
digitalWrite(LEDred, LOW);
}
else
{
digitalWrite(LEDgreen, HIGH);
digitalWrite(LEDred, LOW);
delay(20);
digitalWrite(LEDgreen, LOW);
digitalWrite(LEDred, HIGH);
}
*/
}
//++++++++++++++++++++++++++++++++++++
//Next two functions add support for writing/reading integers to EEPROM
void EEPROMWriteInt (int address, unsigned int integer)
{
EEPROM.write(address, highByte(integer));
EEPROM.write(address + 1, lowByte(integer));
}
unsigned int EEPROMReadInt (int address)
{
unsigned int higherByte = EEPROM.read(address);
unsigned int lowerByte = EEPROM.read(address + 1);
return (word (higherByte, lowerByte));
}
void setup() {
//MIDI.begin();
//Set each input pin to input mode
//Setting the input is technically redundant, as this is the default, but let's do it to be consistent
pinMode(Go, INPUT_PULLUP);
pinMode(Prev, INPUT_PULLUP);
pinMode(Next, INPUT_PULLUP);
pinMode(Stop, INPUT_PULLUP);
pinMode(Aux1, INPUT_PULLUP);
pinMode(Aux2, INPUT_PULLUP);
pinMode(Foot, INPUT_PULLUP);
//pinMode(Contact, OUTPUT);
// pinMode(FootMode, INPUT); //commented out with switch to soft mode selection on startup
// pinMode(AuxMode, INPUT); // same as above
pinMode(LEDgreen, OUTPUT);
pinMode(LEDred, OUTPUT);
delay (100); //trying delay to give time for inputs to initialize
//set add'l grounds
pinMode(PIN_E6, OUTPUT);
digitalWrite(PIN_E6, LOW);
pinMode(PIN_B2, OUTPUT);
digitalWrite(PIN_B2, LOW);
pinMode(PIN_D1, OUTPUT);
digitalWrite(PIN_D1, LOW);
pinMode(PIN_C7, OUTPUT);
digitalWrite(PIN_C7, LOW);
pinMode(PIN_F5, OUTPUT);
digitalWrite(PIN_F5, LOW);
//set 5V for footswitch LED
pinMode(FootLED, OUTPUT);
digitalWrite(FootLED, HIGH);
LEDgreenON();
//Sense polarity for Footswitch
InitialFoot=digitalRead(Foot);
/* REM out to test without startup functions
//Check for Aux mode setting change on startup
CurrentAux1=digitalRead(Aux1);
CurrentAux2=digitalRead(Aux2);
if (CurrentAux1==pressed){
EEPROM.write(EEPROMaux, aux);
LEDredON();
delay(1000);
LEDgreenON();
}
if (CurrentAux2==pressed){
EEPROM.write(EEPROMaux, gpo);
LEDredON();
delay(1000);
LEDgreenON();
delay(1000);
LEDredON();
delay(1000);
LEDgreenON();
}
//Check for/set custom double go window
CurrentPrev=digitalRead(Prev);
CurrentNext=digitalRead(Next);
if (CurrentPrev==pressed && CurrentNext==pressed){
int x=0;
while(x < 2){
if (x==0) {
LEDtoggle();
}
CurrentGo=digitalRead(Go);
if(CurrentGo==pressed && x==0){
TimeOfLastGo = millis();
LEDgreenON();
x=1;
}
if(CurrentGo==released && x==1){
currentMillis = millis();
DoubleGoWindow = currentMillis - TimeOfLastGo;
EEPROMWriteInt (EEPROMdoublego, DoubleGoWindow);
x=2;
LEDredON();
}
}
}
//Check for Footswitch mode setting change and default Double Go reset on startup
CurrentGo=digitalRead(Go);
CurrentStop=digitalRead(Stop);
if (CurrentGo==pressed && CurrentStop==pressed){
DoubleGoWindow=DoubleGoDefault;
EEPROMWriteInt (EEPROMdoublego, DoubleGoWindow);
LEDoff();
delay(1000);
LEDredON();
delay(1000);
LEDoff();
delay(1000);
LEDgreenON();
}
if (CurrentGo==pressed && CurrentStop==released){
EEPROM.write(EEPROMfoot, mirror);
LEDredON();
delay(1000);
LEDgreenON();
delay(1000);
LEDredON();
delay(1000);
LEDgreenON();
delay(1000);
LEDredON();
delay(1000);
LEDgreenON();
}
if (CurrentStop==pressed && CurrentGo==released){
EEPROM.write(EEPROMfoot, independent);
LEDredON();
delay(1000);
LEDgreenON();
delay(1000);
LEDredON();
delay(1000);
LEDgreenON();
delay(1000);
LEDredON();
delay(1000);
LEDgreenON();
delay(1000);
LEDredON();
delay(1000);
LEDgreenON();
}
//Read footswitch and aux modes, Double Go from EEPROM, store as variables available to program
FootMode = EEPROM.read(EEPROMfoot);
AuxMode = EEPROM.read(EEPROMaux);
DoubleGoWindow = EEPROMReadInt (EEPROMdoublego);
// Check previous state of Aux if in GPO mode from EEPROM, and reset current state if remote is in GPO mode
if (AuxMode==gpo){
CurrentContactState = EEPROM.read(EEPROMgpo);
if (CurrentContactState==closed){
LEDredON();
}
else{
LEDgreenON();}}
else{LEDgreenON();}
//}
*/
}
void loop() {
/*
To read buttons, first update debouncer, then read it into a variable:
debouncer.update(); <--This will optionally return a "true" if status has changed since last read
variable=debouncer.read()
*/
//Update the debouncers to see whether their state has changed since the last check (filtered by debounce time):
ChangedGo = debounceGo.update();
ChangedPrev = debouncePrev.update();
ChangedNext = debounceNext.update();
ChangedStop = debounceStop.update();
ChangedAux1 = debounceAux1.update();
ChangedAux2 = debounceAux2.update();
ChangedFoot = debounceFoot.update();
if (ChangedGo==true){ //If there's been a change of state in the Go button
CurrentGo = debounceGo.read(); //read the current state into a variable
currentMillis = millis(); //read the current timestamp into a temporary variable
if (CurrentGo==pressed && currentMillis - TimeOfLastGo >= DoubleGoWindow){
// if the current state of the button is pressed *AND* it's been longer than the Double Go Protection window
PressGo();
//update tracking variables
TimeOfLastGo = millis();
LastGoSent = pressed;
}
else{
//Otherwise, it's just been released, so...
if (CurrentGo==released && /*LastGoSent==pressed &&*/ currentMillis-TimeOfLastGoRelease >= DoubleGoWindow){
ReleaseGo();
TimeOfLastGoRelease = millis();
LastGoSent = released;
}
}
} //send the ReleaseGo Message
//Remaining buttons follow the same pattern, so I'm not going to explicitly comment them
//if (ChangedPrev==true){
//CurrentPrev = debouncePrev.read();
CurrentPrev = digitalRead(Prev);
LEDoff(); // for testing purposes
if (CurrentPrev==pressed){
//PressPrev();
LEDredON();
}
else{
//ReleasePrev();
LEDgreenON();
}
//}
if (ChangedNext==true){
CurrentNext = debounceNext.read();
if (CurrentNext==pressed){
PressNext();
}
else{
ReleaseNext();
}
}
if (ChangedStop==true){
CurrentStop = debounceStop.read();
if (CurrentStop==pressed){
PressStop();
}
else{
ReleaseStop();
}
}
if (ChangedFoot==true){
CurrentFoot = debounceFoot.read();
//This can be cleaned up by testing for DoubleGoWindow first, then footswitch mode
if (CurrentFoot!=InitialFoot){ //if Footswitch is pressed, ie opposite of initial state
if (FootMode==independent && currentMillis - TimeOfLastFootPress >=DoubleGoWindow ){ //if Footswitch input is set to have its own message
PressFoot();
TimeOfLastFootPress = millis();
} //send that message
else{ if (currentMillis-TimeOfLastFootPress >= DoubleGoWindow){ //if Footswitch input is set to mirror the Go button
PressGo();
TimeOfLastFootPress = millis();}
}
} //send the Go message
else{
if (FootMode==independent && currentMillis - TimeOfLastFootRelease >= DoubleGoWindow){
ReleaseFoot();
TimeOfLastFootRelease = millis();
}
else{
if (currentMillis - TimeOfLastFootRelease >= DoubleGoWindow){
ReleaseGo();
TimeOfLastFootRelease=millis();}
}
}
}
if (AuxMode==aux){
if (ChangedAux1==true){
CurrentAux1 = debounceAux1.read();
if (CurrentAux1==pressed){
PressAux1();
}
else{
ReleaseAux1();
}}}
if (AuxMode==gpo){
if (ChangedAux1==true)
{
CurrentAux1 = debounceAux1.read();
if (CurrentAux1==pressed){
if (CurrentContactState==open){
CurrentContactState = closed;
EEPROM.write(EEPROMgpo, closed);
ToggleB();
}
else{
CurrentContactState = open;
EEPROM.write(EEPROMgpo, open);
ToggleA();
}
}}}
if (ChangedAux2==true){
CurrentAux2 = debounceAux2.read();
if (CurrentAux2==pressed){
PressAux2();
}
else{
ReleaseAux2();
}
}
}
// END OF MAIN PROGRAM