I'm having odd phantom interrupts being fired on a single buttonpress. I have hardware pullups (10k) in place on 2 of the pins (22 and 23) and INPUT_PULLUP on the other (pin 2). I have only seen the behaviour on pins 22 and 23, and I THINK I have only observed pin23 interrupt firing when I press 22, not vice versa. This is the example code. (Teensy 4.1 @ 528Mhz)
And this is an example output when it happens - the timestamp is just from the serial monitor - Note the identical timestamp at 32.313.
16:05:30.674 -> START PRESSED IN INTERRUPT
16:05:31.139 -> FINISH PRESSED IN INTERRUPT
16:05:31.799 -> DNF PRESSED IN INTERRUPT
16:05:32.313 -> START PRESSED IN INTERRUPT
16:05:32.313 -> FINISH PRESSED IN INTERRUPT
16:05:33.330 -> DNF PRESSED IN INTERRUPT
This is doing my head in. I can't see how this is a SW issue and I have tried with and without "INPUT_PULLUP" on 22 and 23. My only theory at the moment is the wires to the pushbuttons are functioning as aerials and somehow there's not enough noise rejection. Can I safely use a much stronger resistor for the physical pullup? What would be a safe value?
I don't think I can use bounce or polling. In the full program the button presses are actually from a beam input and need to be at least millisecond accurate - The interrupt routine only checks for bounce, saves a timestamp and sets a flag for the main loop to process the timestamp later.
Cheers - Neil G
Code:
volatile uint32_t startlastfired, finlastfired, dnflastfired;
volatile uint32_t beamdebounce = 1000;
#define DEBUG_CS Serial // Debug to USB serial console, can change to Serial6
void setup() {
DEBUG_CS.begin(115200);
pinMode(22, INPUT_PULLUP); // sets the digital pin as input for START beam
attachInterrupt(22, isrStartBeam, FALLING); // interrrupt on light beam input
pinMode(23, INPUT_PULLUP); // sets the digital pin as input for FINISH beam
attachInterrupt(23, isrFinBeam, FALLING); // interrrupt on light beam input
pinMode(2, INPUT_PULLUP);
attachInterrupt(2, isrDNFbutton, FALLING); // Interruptt for the local DNF button
}
void isrStartBeam()
{
cli();
if (millis() - startlastfired > beamdebounce) {
startlastfired = millis();
DEBUG_CS.println("START PRESSED IN INTERRUPT");
}
sei();
}
// FINISH Light beam trigger generates this interrupt
void isrFinBeam()
{
cli();
if (millis() - finlastfired > beamdebounce) {
finlastfired = millis();
DEBUG_CS.println("FINISH PRESSED IN INTERRUPT");
}
sei();
}
// This is a hardware interrupt for the DNF button. Overkill but easy
void isrDNFbutton()
{
cli();
if (millis() - dnflastfired > beamdebounce) {
dnflastfired = millis();
DEBUG_CS.println("DNF PRESSED IN INTERRUPT");
}
sei();
}
void loop() {
// put your main code here, to run repeatedly:
}
And this is an example output when it happens - the timestamp is just from the serial monitor - Note the identical timestamp at 32.313.
16:05:30.674 -> START PRESSED IN INTERRUPT
16:05:31.139 -> FINISH PRESSED IN INTERRUPT
16:05:31.799 -> DNF PRESSED IN INTERRUPT
16:05:32.313 -> START PRESSED IN INTERRUPT
16:05:32.313 -> FINISH PRESSED IN INTERRUPT
16:05:33.330 -> DNF PRESSED IN INTERRUPT
This is doing my head in. I can't see how this is a SW issue and I have tried with and without "INPUT_PULLUP" on 22 and 23. My only theory at the moment is the wires to the pushbuttons are functioning as aerials and somehow there's not enough noise rejection. Can I safely use a much stronger resistor for the physical pullup? What would be a safe value?
I don't think I can use bounce or polling. In the full program the button presses are actually from a beam input and need to be at least millisecond accurate - The interrupt routine only checks for bounce, saves a timestamp and sets a flag for the main loop to process the timestamp later.
Cheers - Neil G