0

I'm trying to use encoders to track the movement of three wheels on a robot, but as soon as any of the motors move the robot "locks up", it stops responding to commands, stops printing to the serial monitor, and just keeps spinning its wheels until I turn it off. I cut out everything except just the code to track one encoder and tried turning the wheel by hand to sus out the problem, but it still locked up. And even more strangely, now it will start spinning one of the wheels even though I've removed any code that should have it do that, even by mistake.

I used the Arduino IDE to program the pico since I've got no familiarity with python, but I can't find any information or troubleshooting tips for using interrupts with the pico that don't assume you're using micropython.

Here's the simplified code I'm using to try to find the problem. All it's meant to do is keep track of how many steps the encoder has made and print that to the serial monitor every second. Ive tried removing the serial and having it light up LEDs instead but that didn't help.

int encA = 10;
int encB = 11;
int count = 0;
int timer = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(encA),readEncoder,RISING);
  timer = millis();
}

void loop() {
  // put your main code here, to run repeatedly:
  if (timer - millis() > 5000) {
    Serial.println(count);
    timer = millis();
  }
}

void readEncoder() {
  int bVal = digitalRead(encB);
  if (bVal == 0) {
    count--;
  }
  else{
    count++;
  }
}

2 Answers2

1

Does the mapping function digitalPinToInterrupt for the Pi Pico work? Can you try just using the interrupt number that corresponds to the pi?

attachInterrupt(9,readEncoder,RISING); //Or the number 0-25 which maps to that pin

https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__irq.html

You have the wrong pin to encoder in your example (maybe you incorrectly copy and pasted)?

attachInterrupt(digitalPinToInterrupt(**encA**),readEncoder,RISING);
void readEncoder() {
  int bVal = digitalRead(**encB**); ...}

There is similar code on GitHub that you could modify and try instead.

https://github.com/jumejume1/Arduino/blob/master/ROTARY_ENCODER/ROTARY_ENCODER.ino

It might help you find a solution.

Also, https://www.arduino.cc/reference/en/libraries/rpi_pico_timerinterrupt/

AORD
  • 176
  • 4
  • question about your ino file: what does "AttachInterrupt 0 is DigitalPin nr 2 on moust Arduino" mean in terms of the pico? Because every GPIO pin is technically an interrupt pin according to everthing I'm reading about the pico – Mike 'Pomax' Kamermans Sep 21 '22 at 17:35
1

The interrupt number corresponds to the pin (unless you have reassigned it or disabled it) so for pin 11 the code can be:

attachInterrupt(11, buttonPressed, RISING);

This works:

bool buttonPress = false;
unsigned long buttonTime = 0; // To prevent debounce

void setup() {
  Serial.begin(9600);
  pinMode(11, INPUT_PULLUP);
  attachInterrupt(11, buttonPressed, RISING);
  // can be CHANGE or LOW or RISING or FALLING or HIGH
}

void loop() {
  if(buttonPress) {
    Serial.println(F("Pressed"));
    buttonPress= false;
  } else {
    Serial.println(F("Normal"));
  }
  delay(250);
}

void buttonPressed() {
  //Set timer to work for your loop code time   
  if (millis() - buttonTime > 250) {
    //button press ok
    buttonPress= true;
  }
  buttonTime = millis();
}

See: https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__irq.html for disable, enable etc.

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
AORD
  • 176
  • 4
  • When I do this without the interrupt line, the `INPUT_PULLUP` declared pin reads 3.2V, as it should, but if I add the interrupt line, that drops to only 0.1V, and things stop working because 0.1V when high is still a digital zero. – Mike 'Pomax' Kamermans Sep 22 '22 at 15:30