Working Rotary Encoder for Arduino doesn’t work for Pico

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.

This is the code in a dev environment: sketch.ino - Wokwi Arduino and ESP32 Simulator

Can anyone help me figure out why this wouldn't work? This exact code worked on Arduino and all I did was update the pin references.

James

Can you post the code here please, in code tags?

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.

1 Like

Just pretend we know nothing about your project and start from the beginning, possibly after reading on how to use this forum

Hello,

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);
}

what does this mean? error messages? letters falling out on the foot? Pico making funny noises then smoking?

1 Like

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.

Perhaps your problem is Serial monitor rather than encoder.
Try to add some serial prints in setup to test is the serial output works or not

1 Like

Input pull up? Do you have external pull up resistors?

Try the sample code here:

1 Like

The very least when you press the button it should print

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.

EDIT: Perry beat me to it.

1 Like

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?

Yes shouldn't be the wiring as it's also in simulated environment which wouldn't have loose connections etc. I'll try the serial environment.

At the risk of asking the obvious, did you change the pin numbers for CLK and DT to whatever you are using?

...and did you connect the GND between encoder and oico board?

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

1 Like


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.

The ones I used are 14,15,16,17 which are equiv to GP10, 11, 12, 13, so I can refer to it simply as 10 to reference GP10 (pin 14) if that makes sense

Yes it does make sense. I don't know the answer!