I'm working on a project which needs Arduino stepper motor code and uses a Pi Pico but I wanted to add a rotary encoder. I thought it would be pretty simple to find a working code segment for rotary encoder on Pico in Ardunio code but all seems to be micro python.
When I moved across a working rotary encoder Arduino script to Pico it doesn't seem to work and I can't work out why. There are no errors.
What type of Arduino was it written for? There are many types of Arduino, and Pico can be considered one of them. But different types of Arduino use different chips that have different capabilities on each pin, so the problem could be due to that.
I've tried a few rotary encoder scripts without any success. This is the one I am trying now (which as I mentioned works perfectly - in this case was for an Uno) - but completely breaks when being moved to Pico with the pins updated.
// Rotary Encoder Inputs
#define CLK 10
#define DT 11
#define SW 12
int counter = 0;
int currentStateCLK;
int lastStateCLK;
String currentDir = "";
unsigned long lastButtonPress = 0;
void setup() {
// Set encoder pins as inputs
pinMode(CLK,INPUT);
pinMode(DT,INPUT);
pinMode(SW, INPUT_PULLUP);
// Setup Serial Monitor
Serial.begin(9600);
// Read the initial state of CLK
lastStateCLK = digitalRead(CLK);
}
void loop() {
// Read the current state of CLK
currentStateCLK = digitalRead(CLK);
// If last and current state of CLK are different, then pulse occurred
// React to only 1 state change to avoid double count
if (currentStateCLK != lastStateCLK && currentStateCLK == 1){
// If the DT state is different than the CLK state then
// the encoder is rotating CCW so decrement
if (digitalRead(DT) != currentStateCLK) {
counter --;
currentDir ="CCW";
} else {
// Encoder is rotating CW so increment
counter ++;
currentDir ="CW";
}
Serial.print("Direction: ");
Serial.print(currentDir);
Serial.print(" | Counter: ");
Serial.println(counter);
}
// Remember last CLK state
lastStateCLK = currentStateCLK;
// Read the button state
int btnState = digitalRead(SW);
//If we detect LOW signal, button is pressed
if (btnState == LOW) {
//if 50ms have passed since last LOW pulse, it means that the
//button has been pressed, released and pressed again
if (millis() - lastButtonPress > 50) {
Serial.println("Button pressed!");
}
// Remember last button press event
lastButtonPress = millis();
}
// Put in a slight delay to help debounce the reading
delay(1);
}
No errors, no smoke, no letters falling out, it just doesn't react at all to the click or turning of the encoder or print any serial messages, whereas with the Arduino board it works fine. I've simulated this (link above) and also tried with physical board too and same issue.
Should these be INPUT_PULLUP? Perhaps the code was written for an encoder module with built-in pull-up resistors, and you don't have those? I have no idea how a simulator like Wokwi treats floating pins.
I've tried with the pull up as you mentioned but I'm afraid that didn't help. I also tried the tutorial linked to. This works perfectly but when I change the board to the pico it doesn't work. Seems to be an issue with pico running the code specifically.
Then I suspect a wiring problem, please post photos that clearly show the wiring. Probably a quickly drawn schematic as well (hand drawn and photographed is fine)
There is nothing "specific" in this code. It should works in Pico very well. So still search the error.
Are you tested the Serial Monitor as I suggested?
Hello, thank you all for your help. The issue was with the Serial as B707 alluded to!
Reason:
In Ardunio using "Serial" works fine, but in Pico it doesn't. In Pico if you use "Serial1" it works fine. I don't know the reason for this, but I just noticed that all the Pico example code has Serial1. I.e:
Pico: Serial1.println("Pi Pico Serial Monitor example!");
Arduino: Serial.println("Pi Pico Serial Monitor example!");
I hope this would help out someone else in same boat
Problem with that picture is that the Pico pins are not labelled. I certainly haven't memorised them! It's not obvious if those are or aren't 10, 11, 12.
The + pin on the encoder seems to the connected to pin 13, which isn't used in your sketch, so the encoder module's internal pull-ups probably won't work. But using INPUT_PULLUP should have fixed that.