Hi all!
I'm making a simple button box with switches, pushbuttons and rotary encoders. I have gotten the switches and buttons working fine, but I find these rotary encoders notoriously difficult to wrap my brain around.
To try to understand I thought I would do a simple setup. I have a rotary encoder hooked up to a Pro Micro like this: (right pin (green wire) to A2, middle pin to ground, left pin (purple wire) to A3)
The code: (Note! It's not my code. I found this code on the web and modified it a bit to suit my setup.)
int clockP = A3;
int data = A2;
int count = 0;
int c = HIGH;
int cLast = HIGH;
int d = HIGH;
void setup() {
pinMode (clockP,INPUT_PULLUP);
pinMode (data,INPUT_PULLUP);
Serial.begin (9600);
}
void loop() {
c = digitalRead(clockP); // read pin A as clock
d = digitalRead(data); // read pin B as data
if (c != cLast) { // clock pin has changed value
d = c^d; // work out direction using an XOR
if ( d ) {
count++;
Serial.print ("Right: ");
Serial.println(count);
delay(20);
}else{
count--;
Serial.print ("Left: ");
Serial.println(count);
delay(20);
}
cLast = c;
}
}
This is the output when I run the code and first rotate the encoder one dent/position to the right followed by one dent/position to the left:
Right: 1
Right: 2
Left: 1
Left: 0
As you can see I get two inputs every time I turn just one dent.
I've been reading a bit about encoders and pulses and realize that they are somewhat complex in nature. I found one Youtuber explaining them more in detail: Video
He uses interrupts to handle the inputs from the encoder. Here is the code he links to.
I tried to modify that code to suit my setup but just couldn't get it to work.
Desired functionality
I'm using the joystick library to get button presses from my box. What I want to happen with the rotary encoders is that when I rotate one dent to the right then it sets a button to on then off shortly afterwards. Same for rotating to the left, only a different button obviously.
So the end code would be something like this:
#include <Joystick.h>
Joystick_ Joystick;
int clockP = A3;
int data = A2;
int count = 0;
int c = HIGH;
int cLast = HIGH;
int d = HIGH;
void setup() {
pinMode (clockP,INPUT_PULLUP);
pinMode (data,INPUT_PULLUP);
Joystick.begin();
}
void loop() {
c = digitalRead(clockP); // read pin A as clock
d = digitalRead(data); // read pin B as data
if (c != cLast) { // clock pin has changed value
d = c^d; // work out direction using an XOR
if ( d ) {
count++;
Joystick.setButton(1, 1);
delay(50);
Joystick.setButton(1, 0);
}else{
count--;
Joystick.setButton(0, 1);
delay(50);
Joystick.setButton(0, 0);
}
cLast = c;
}
}
(the "count" variable isn't really needed in this example but I kept them just to show what's happening)
That sort of works, but the behaviour is somewhat unpredictable – sometimes two button presses are registered, and sometimes both buttons are pressed when rotating only one way.
Would be great if someone could help me with this. It's the only code left to finish before my button box is complete.
Any suggestions/solutions will be appreciated.