-
-
Notifications
You must be signed in to change notification settings - Fork 209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Raspberry pi pico external interrupts not working #253
Comments
You have to change the event type of the interrupt from
|
No luck unfortunately, same behavior. What library are you using? Polling works fine, but interrupts don't. Tested 2 different encoders (different design). My encoder of choice works fine with an 8-bit pro mini. Here's a minimum example - https://www.arduino.cc/reference/en/libraries/rotaryencoder/ #include <RotaryEncoder.h> #define PIN_IN1 2 RotaryEncoder encoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::TWO03); void checkPosition(){ void setup(){ // Read the current position of the encoder and print out when changed. int newPos = encoder.getPosition(); |
I use QDEC for the rotary and AceButton for the button of the rotary encoder. |
I'm at a complete loss here. Tried the library you suggested, with both HIGH and LOW 'links' to the ISR for both pins and get the same result. |
Tested the pico with micropython to make sure there's not a problem with my hardware. Was able to get working interrupts using the example provided by Raspberry pi co: `from machine import Pin p2 = Pin(2, Pin.IN, Pin.PULL_UP) It's a problem with the arduino side of things. |
Tried a simple interrupt sketch, serial port sent a single string before becoming completely unresponsive. Board now flashes "SOS" - I'm assuming thats a failure mode, but can't find anything on it. I'm using the same encoder, and it has ~3000 pulses per turn. I'm thinking this may be a problem with an interrupt interrupting the ISR itself? It's been a while since i studied computer systems architecture, but i believe that there should be things in place to prevent this as it's typically bad? In order to bring reflash another sketch to the board, i need to hold bootsel and plug it back in, like you would do the first time uploading a sketch. simple sketch for reference - `int pin = 3; //define interrupt pin to 2 void setup() { void blink() { If i remove the print bit of the ISR, it doesn't do anything when a state change is triggered. I thought maybe it's happening too fast for me to see, so i added a delay to the ISR (I know, ISR's need to run as fast as possible, but trying to figure this out). Board becomes unresponsive and blinks SOS again. I will try the pico port that was released by someone forgot his name) before the arduino guys released the official one. |
Using serial output in an interrupt handler doesn't work for me. I think that's true for all kinds of interrupts on the Pico. I will post a complete example later. |
This is the code I use to get the rotary encoder interrupts working for me. This program can be used for Pico and Arduino Nano (by changing the ARDUINO_AVR_NANO check, you could also get it to work for other platforms. #include <Arduino.h>
#include <qdec.h>
#include <AceButton.h>
#if defined(ARDUINO_ARCH_RP2040)
const int ROTARY_PIN_A = 14;
const int ROTARY_PIN_B = 15;
const int ROTARY_BUTTON_PIN = 13;
#elif defined(ARDUINO_AVR_NANO)
const int ROTARY_PIN_A = 2;
const int ROTARY_PIN_B = 3;
const int ROTARY_BUTTON_PIN = 5;
#endif
const int LED_PIN = LED_BUILTIN;
const int LED_ON = HIGH;
const int LED_OFF = LOW;
SimpleHacks::QDecoder qdec(ROTARY_PIN_A, ROTARY_PIN_B, false);
ace_button::AceButton button(ROTARY_BUTTON_PIN);
volatile int rotaryCount = 0;
volatile int _rotaryCount = 0;
int lastLoopDisplayedRotaryCount = 0;
void handleEvent(ace_button::AceButton *button, uint8_t eventType, uint8_t buttonState)
{
switch (eventType)
{
case ace_button::AceButton::kEventPressed:
digitalWrite(LED_PIN, LED_ON);
break;
case ace_button::AceButton::kEventReleased:
digitalWrite(LED_PIN, LED_OFF);
break;
case ace_button::AceButton::kEventLongPressed:
// noop
break;
}
}
void IsrForQDEC(void)
{
SimpleHacks::QDECODER_EVENT event = qdec.update();
if (event & SimpleHacks::QDECODER_EVENT_CW)
{
if (_rotaryCount < 0)
_rotaryCount = 0;
_rotaryCount++;
if (_rotaryCount == 2)
{
_rotaryCount = 0;
rotaryCount = rotaryCount + 1;
if (rotaryCount > 10)
rotaryCount = 0;
}
}
else if (event & SimpleHacks::QDECODER_EVENT_CCW)
{
if (_rotaryCount > 0)
_rotaryCount = 0;
_rotaryCount--;
if (_rotaryCount == -2)
{
_rotaryCount = 0;
rotaryCount = rotaryCount - 1;
if (rotaryCount < 0)
rotaryCount = 10;
}
}
return;
}
void setup()
{
Serial.begin(9600);
delay(2000);
qdec.begin();
attachInterrupt(digitalPinToInterrupt(ROTARY_PIN_A), IsrForQDEC, HIGH);
attachInterrupt(digitalPinToInterrupt(ROTARY_PIN_A), IsrForQDEC, LOW);
attachInterrupt(digitalPinToInterrupt(ROTARY_PIN_B), IsrForQDEC, HIGH);
attachInterrupt(digitalPinToInterrupt(ROTARY_PIN_B), IsrForQDEC, LOW);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LED_OFF);
pinMode(ROTARY_BUTTON_PIN, INPUT_PULLUP);
ace_button::ButtonConfig *buttonConfig = button.getButtonConfig();
buttonConfig->setEventHandler(handleEvent);
buttonConfig->setFeature(ace_button::ButtonConfig::kFeatureClick);
buttonConfig->setFeature(ace_button::ButtonConfig::kFeatureDoubleClick);
buttonConfig->setFeature(ace_button::ButtonConfig::kFeatureLongPress);
buttonConfig->setFeature(ace_button::ButtonConfig::kFeatureRepeatPress);
}
void loop()
{
button.check();
int newValue = rotaryCount;
if (newValue != lastLoopDisplayedRotaryCount)
{
lastLoopDisplayedRotaryCount = newValue;
Serial.println(newValue);
}
} I also needed the delay before the EDIT: I use the following libraries in this project:
|
Hi @Chick92 and @fsievers , |
@facchinm That's fixed it! Thankyou so much! the Pico is an amazing (and very nicely priced) board, i was starting to worry i wouldn't have time to wait for this to be solved before starting my design. Thanks again! @fsievers The above explains why yours worked and my didn't, thanks for helping. As well, you pasting your code has (I think) helped me out massively with another issue! - PaulStoffregen/Encoder#69 Both of you, thankyou! |
Can't get any encoder library to work using interrupts. Ones that are able to, work fine when polling the state of the pins, but this won't be suitable for my task.
Tried with a simple interrupt sketch, also no response at all.
const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}
void loop() {
digitalWrite(ledPin, state);
}
void blink() {
state = !state;
}
The text was updated successfully, but these errors were encountered: