Hi there,
I have 3 tactile buttons going to separate input pins- A1, A2, A3. Using a Particle Argon.
When the code digital reads all three buttons, and prints when HIGH, everything works as expected. Each button prints separately when they are pressed.
When the code has 3 interrupts for each of the 3 buttons, all of the interrupt callbacks are called regardless of which button is pressed.
When I comment out 2 of the interrupts, pressing any of the 3 buttons still results in that 1 interrupt firing and the callback being called.
This is not the expected behaviour, because each individual button works for polling, but the buttons do not work individually for interrupts.
Is there something that I did wrong? Any ideas on how to fix this?
Hi Erin,
I think someone will ask to see your code.
I’m just anticipating them
Cheers
2 Likes
Polling button test:
#include "Board.h"
void setup() {
Serial.begin(9600);
pinMode(PLAY_PIN, INPUT);
pinMode(REV_PIN, INPUT);
pinMode(FWD_PIN, INPUT);
}
void loop() {
if(digitalRead(PLAY_PIN) == HIGH) {
Serial.println("play");
}
if(digitalRead(REV_PIN) == HIGH) {
Serial.println("rev");
}
if(digitalRead(FWD_PIN) == HIGH) {
Serial.println("fwd");
}
delay(100);
}
Interrupt button test:
#include "Boards.h"
uint8_t button_pins[] = { PLAY_PIN, REV_PIN, FWD_PIN };
volatile uint8_t button_val[] = { 0, 0, 0 };
volatile uint8_t prev_button_val[] = { 0, 0, 0 };
volatile long button_debounce_start[] = { 0, 0, 0 };
enum buttons { PLAY, REV, FWD };
void buttonCallback(uint8_t i);
void playButtonCallback();
void revButtonCallback();
void fwdButtonCallback();
void setup() {
Serial.begin(9600);
// pin init
pinMode(PLAY_PIN, INPUT);
pinMode(REV_PIN, INPUT);
pinMode(FWD_PIN, INPUT);
// interrupt init
attachInterrupt(PLAY_PIN, playButtonCallback, RISING);
attachInterrupt(REV_PIN, revButtonCallback, RISING);
attachInterrupt(FWD_PIN, fwdButtonCallback, RISING);
}
void loop() {
for(uint8_t i=0; i<3; i++) {
if(button_val[i] == 1) { // 1 set from interrupt callback
Serial.print(millis());
Serial.print(" button val = 1: ");
Serial.println(i);
button_val[i] = 0; // reset val
}
}
}
// callback from interrupt functions
void buttonCallback(uint8_t i) {
//Serial.print("button callback: ");
//Serial.println(i);
if(button_val[i] == 0) { // only set the time if the flag was cleared
button_debounce_start[i] = millis();
button_val[i] = 1;
}
}
void playButtonCallback() {
buttonCallback(PLAY);
}
void revButtonCallback() {
buttonCallback(REV);
}
void fwdButtonCallback() {
buttonCallback(FWD);
}
Boards.h
#define KNOB_PIN A0
#define PLAY_PIN A1
#define REV_PIN A2
#define FWD_PIN A3
#define FREE_PIN A4
#define DIP1_PIN 2
#define DIP2_PIN 3
#define DIP3_PIN 4
#define LED1_PIN 5 // right hand side. for step. has pwm.
#define STEP_PIN 6
#define DIR_PIN 7
#define LED2_PIN 8 // left hand side. for direction. has pwm.
Ah! Beat me to it by 20 seconds! The code is posted in the previous comment now.
2 Likes
I guess you have no external pull-resistors in place.
In that case you should use INPUT_PULLDOWN
to prevent the pins from floating when no button is pressed (for digitalRead()
too).
BTW, your button_debounce_start
should be unsigned long
- although you don’t seem to be using it for debouncing
Hello,
Thanks for having a look.
In that case you should use INPUT_PULLDOWN
to prevent the pins from floating when no button is pressed (for digitalRead()
too).
I have changed the pinMode to this:
pinMode(PLAY_PIN, INPUT_PULLDOWN);
pinMode(REV_PIN, INPUT_PULLDOWN);
pinMode(FWD_PIN, INPUT_PULLDOWN);
It did not solve the problem for the interrupts.
I guess you have no external pull-resistors in place.
There are 1k ohm pull down resistors for each button on the pcb. There is also a 0.1 uF cap for hardware debouncing for each button on the pcb.
BTW, your button_debounce_start
should be unsigned long
- although you don’t seem to be using it for debouncing
Button debouncing is in the full system code
The problem still exists
robotgrrl:
buttonCallback(PLAY);
Maybe your enum declaration is missing an = 0 before being used as int?
This is what I would try after reading a bit :
enum buttons { PLAY = 0, REV, FWD };
1 Like
Can you show us your wiring? (diagram and hi-res photo)
BTW, when I try your interrupt code with my Argon and a mere push button closing to 3v3 it works as expected.
slightly altered code
#define B_ISR_NAME(_para) isr_ ## _para
#define B_ISR(_para) void B_ISR_NAME(_para) (void){ buttonCallback(_para); }
uint8_t button_pins[] = { PLAY_PIN, REV_PIN, FWD_PIN };
volatile uint8_t button_val[] = { 0, 0, 0 };
volatile uint8_t prev_button_val[] = { 0, 0, 0 };
volatile long button_debounce_start[] = { 0, 0, 0 };
enum buttons { PLAY, REV, FWD, btnCount };
char btnName[btnCount][12] = { "PLAY", "REV", "FWD" };
void buttonCallback(uint8_t i);
B_ISR(PLAY);
B_ISR(REV);
B_ISR(FWD);
void setup() {
Serial.begin(9600);
// pin init
pinMode(PLAY_PIN, INPUT_PULLDOWN);
pinMode(REV_PIN, INPUT_PULLDOWN);
pinMode(FWD_PIN, INPUT_PULLDOWN);
// interrupt init
attachInterrupt(PLAY_PIN, B_ISR_NAME(PLAY), RISING);
attachInterrupt(REV_PIN , B_ISR_NAME(REV ), RISING);
attachInterrupt(FWD_PIN , B_ISR_NAME(FWD ), RISING);
}
void loop() {
for(uint8_t i = 0; i < btnCount; i++) {
if(button_val[i]) { // 1 set from interrupt callback
Serial.printlnf("%s pressed\t(%lu)", btnName[i], millis());
button_val[i] = 0; // reset val
}
}
}
// callback from interrupt functions
void buttonCallback(uint8_t i) {
//Serial.print("button callback: ");
//Serial.println(i);
if(!button_val[i]) { // only set the time if the flag was cleared
button_debounce_start[i] = millis();
button_val[i] = 1;
}
}
2 Likes
The issue comes back to: it works as expected for polling, but does not work as expected for interrupts.
For me it works both ways so it hasn't got anything to do with the code nor the Argon's default behaviour.
Consequently the next step would be to investigate the specifics of your HW setup.
Hence the above request for a hi-res photo of your setup.
Check out my comment above where I sent the photos of the setup as requested
Tore everything apart to test on a breadboard. Confirmed hardware problem. 1k ohm likely too weak. My interrupt code runs fine.
1 Like
@ScruffR Check out this comment. (The one that this comment is replying to.)
My code works. Hardware problem. Thanks for the help anyway.
robotgrrl:
Check out this comment.
I had seen that, but experience has taught me that a schematic often lacks the physical details of the actual setup
3 Likes
system
Closed
September 9, 2022, 1:14am
16
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.