I’m encountering a strange issue with my Arduino MIDI project and hoping someone can shed some light on it. I’m using an Arduino Uno, prototyping on a breadboard with hardware debounce circuits, and employing direct register programming with Pin Change Interrupts.
My code is designed to detect button presses using pin change interrupts. Specifically, when Button 2 (connected to pin D2) is pressed, the PCINT2_vect
interrupt service routine is triggered. Inside this routine, I check if pin D2 was indeed the source using PIND & B00000100
. Upon detection, I intend to print “B2_Pressed” to the Arduino Serial Printer for debugging. The code then enters a while
loop to wait for the button release, after which it should print “B2_Released” to the arduino serial printer.
#include <MIDI.h>
#include <LibPrintf.h> //Used to print registers for debugging
MIDI_CREATE_DEFAULT_INSTANCE();
void setup() {
//SECTION TO SET UP PORT REGISTERS FOR INPUT or OUTPUTS
DDRD &= B00000011; //Set D2-D7 (PD2-PD7) as an input using AND method.
PORTD &= B00000011; //Set D2-D7 (PD2-PD7) as LOW with AND method.
DDRB &= B11000000; //Set D8-D13 (PB0-PB5) as an Input using AND method.
PORTB &= B11000000; //Set D8-D13 (PB0-PB5) as LOW using AND method.
MIDI.begin(MIDI_CHANNEL_OMNI); //Enable MIDI communication on all channels.
Serial.begin(9600); //SECTION TO SET UP PIN CHANGE INTERRUPTS ON ARDUINO UNO
// Enable Pin Change Interrupt on Ports B, C and D.
PCICR |= B00000111; //Enable PCI for all Ports
// Enable Port B, Pins PB0 thru PB5 (Digital Inputs D8-D13)
PCMSK0 |= B00111111;
// Enable Port C, Pins PC1 thru PC5 (Analog Inputs A1-A5)
PCMSK1 |= B00111110;
// Enable Port D, Pins PD2 thru PD7 (Digital Inputs D2-D7)
PCMSK2 |= B11111100;
}
void loop() {
//No code here. Interrupt driven program.
}
ISR (PCINT0_vect) // handle pin change interrupt for D8-D13 here
{
Serial.println("Port B Interrupt Called");
printf("PIND: %.8brn", PIND); //For DEBUG Only
}
ISR (PCINT2_vect) // handle pin change interrupt for D2 to D7 here. Use conditional statements to determine which exact pin was pressed.
{
//Check if pin B2 (PD2) was triggered
if(PIND & B00000100)
{
Serial.println("B2_Pressed"); //For DEBUG Only
while (PIND & B00000100) { //Wait here until B2 is released
}
Serial.println("B2_Released"); //For DEBUG Only
}
//Check if pin B3 (PD3) was triggered
if(PIND & B00001000)
{
Serial.println("B3_Pressed"); //For DEBUG Only
while (PIND & B00001000) { //Wait here until B3 is released
}
Serial.println("B3_Released"); //For DEBUG Only
}
}
The perplexing behavior I’m observing is that when I press Button 2, only the first two characters, ‘B2’, of “B2_Pressed” appear on the serial monitor. It’s not until I release the button that the remaining part of the first message, ‘_Pressed’, along with a carriage return, and then the entire “B2_Released” message are printed to the arduino serial printer.
Has anyone encountered a similar issue with the Arduino serial output being delayed or incomplete within interrupt routines, particularly when using a while
loop for button debounce? Any insights into why the arduino serial printer is behaving this way and how to ensure the complete “B2_Pressed” message is printed immediately upon the button press would be greatly appreciated.