Hello,
I am trying to use some rotary encoders with Arduino 2 but I have some problem with the readings.
I am using the plain encoder without breakout board, directly connecting:
Out A --> PIN 6
GND --> GND
Out B --> PIN 7
I don't use the other two pins as I don't need the button function.
Here is the connection scheme I followed:
(I have also tried connecting directly the Out A and Out B to Arduino Pins but it works even worse).
I have tried different scripts but nothing seems to work properly: every time, for each click, my variable is increased by 4 or by 2, with all the middle values in between (screenshots later), but never only by 1.
Code 1:
int encoderPin1 = 6;
int encoderPin2 = 7;
volatile int lastEncoded = 0;
volatile long encoderValue = 0;
long lastencoderValue = 0;
int lastMSB = 0;
int lastLSB = 0;
void setup() {
Serial.begin (9600);
pinMode(encoderPin1, INPUT_PULLUP);
pinMode(encoderPin2, INPUT_PULLUP);
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);
}
void loop(){
Serial.println(encoderValue);
}
void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit
int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue--;
lastEncoded = encoded; //store this value for next time
}
For every "click" of the encoder it increments the variable by 4 (instead of 1) passing through the values in between, I attach a screenshot of the Serial.
Code 2:
#define outputA 6
#define outputB 7
int counter = 0;
int aState;
int aLastState;
void setup() {
pinMode (outputA,INPUT);
pinMode (outputB,INPUT);
Serial.begin (9600);
// Reads the initial state of the outputA
aLastState = digitalRead(outputA);
}
void loop() {
aState = digitalRead(outputA); // Reads the "current" state of the outputA
// If the previous and the current state of the outputA are different, that means a Pulse has occured
if (aState != aLastState){
// If the outputB state is different to the outputA state, that means the encoder is rotating clockwise
if (digitalRead(outputB) != aState) {
counter ++;
} else {
counter --;
}
Serial.print("Position: ");
Serial.println(counter);
}
aLastState = aState; // Updates the previous state of the outputA with the current state
}
In this case the variable is increased by 2 for every click of the encoder:
Here is a screenshot of the Serial.
Finally I have also tried to use this library (encoder_master).
Here is the example script and the resulting Serial I get for 1 click.
/* Encoder Library - Basic Example
* http://www.pjrc.com/teensy/td_libs_Encoder.html
*
* This example code is in the public domain.
*/
#include <Encoder.h>
// Change these two numbers to the pins connected to your encoder.
// Best Performance: both pins have interrupt capability
// Good Performance: only the first pin has interrupt capability
// Low Performance: neither pin has interrupt capability
Encoder myEnc(6, 7);
// avoid using pins with LEDs attached
void setup() {
Serial.begin(9600);
Serial.println("Basic Encoder Test:");
}
long oldPosition = -999;
void loop() {
long newPosition = myEnc.read();
if (newPosition != oldPosition) {
oldPosition = newPosition;
Serial.println(newPosition);
}
}
If any good sould could give me some hints about what I am doing wrong I would be very grateful, it's been two days that I am looking online but it seems like I cannot solve the mistery myself.
Thank you very much,
Alessandro
Encoder-master.zip (17.1 KB)