Yesterday I asked a question about de-bouncing this rotary encoder and Jsotola suggested that I should use a method like This to detect the previous state and then do the counting. using that method each turn is counting twice in one turn so I came up with my version of de-bouncing the rotary encoder:
int s1, s2;
int count = 0;
boolean right = 0;
boolean left = 0;
int rotary = 0;
unsigned long timer = 0;
unsigned int bounce = 50;
void setup() {
Serial.begin(9600);
pinMode(6, INPUT);
pinMode(7, INPUT);
}
void loop() {
s1 = digitalRead(6);
s2 = digitalRead(7);
if (s1 == 1 && s2 == 1) {
right = 0;
left = 0;
rotary = 0;
}
if (s1 == 0 && s2 == 1) {
left = 1;
}
if (left == 1 && (s1 == 0 && s2 == 0)) {
rotary = 2;
}
if (s1 == 1 && s2 == 0) {
right = 1;
}
if (right == 1 && (s1 == 0 && s2 == 0)) {
rotary = 1;
}
if (rotary == 1) {
if ((millis() - timer) > bounce) {
count++;
}
right = 0;
left = 0;
timer = millis();
}
if (rotary == 2) {
if ((millis() - timer) > bounce) {
count--;
}
right = 0;
left = 0;
timer = millis();
}
Serial.print(s1);
Serial.print(s2);
Serial.print(", ");
Serial.print(count);
Serial.println(" ");
delay(15);
}
The code is working just fine. When turning the rotary this are the steps that I get:
10-00-01 < (11) > 10-00-01
problem is if I turn the knob quickly rotary encoder will skip one or two steps like: 01-01-01 < (11)
or 10-00-00 < (11)
.
This problem exist in all methods/libraries (I tested them all), is there anyway to fix this with software/hardware or this rotary encoder is just junk and I should get a better one?
Another method of de-bouncing as Jsotola requested:
int pinA = 3; // Connected to CLK on KY-040
int pinB = 4; // Connected to DT on KY-040
int encoderPosCount = 0;
int pinALast;
int aVal;
boolean bCW;
void setup() {
pinMode (pinA,INPUT);
pinMode (pinB,INPUT);
/* Read Pin A
Whatever state it's in will reflect the last position
*/
pinALast = digitalRead(pinA);
Serial.begin (9600);
}
void loop() {
aVal = digitalRead(pinA);
if (aVal != pinALast){ // Means the knob is rotating
// if the knob is rotating, we need to determine direction
// We do that by reading pin B.
if (digitalRead(pinB) != aVal) { // Means pin A Changed first - We're Rotating Clockwise
encoderPosCount ++;
bCW = true;
} else {// Otherwise B changed first and we're moving CCW
bCW = false;
encoderPosCount--;
}
Serial.print ("Rotated: ");
if (bCW){
Serial.println ("clockwise");
}else{
Serial.println("counterclockwise");
}
Serial.print("Encoder Position: ");
Serial.println(encoderPosCount);
}
pinALast = aVal;
}
delay()
and serial prints too, no difference what so ever...