Right now I'm working on a project that includes several rotary encoder (LPA3806-600BM-G5-24C) controlled by Arduino. I got it working and I got it reading the actual angle multiplying the reading by 360 and then dividing by 1200. The reason why I divided by 1200 is because that's the reading from the encoder performing a full revolution. My question is: why is it 1200 the value for a full revolution? I need to write a paper about the topic and I want to give a nice explanation about it.
The specs of the encoder say that this is an encoder of 600bm, which means it has a resolution of 600 pulses per rev. Therefore why do I get 1200 when I perform one revolution?
Your explanation makes sense and it's probably the case, but I set the attachInterrupt() to RISING:
class encoderClass {
public:
void getCounter(volatile unsigned int);
void getAngle();
void calculateAngle(volatile unsigned int);
int getPin1();
int getPin2();
void setPin1(int);
void setPin2(int);
void setAngle(float);
float returnAngle();
private:
int encoderPin1;
int encoderPin2;
float angle;
};
volatile unsigned int counter1 = 0.0;
volatile unsigned int counter2 = 0.0;
float encAngle;
float displacement;
//function prototypes for counter change of encoder
void counterUp1();
void counterDown1();
void counterUp2();
void counterDown2();
//defining two object (one for each encoder) and initializing values
//encoder1 is the one on the edge
//encoder2 is the one on the cart
encoderClass encoder1, encoder2;
void setup() {
Serial.begin (9600);
encoder1.setPin1(2);
encoder1.setPin2(3);
encoder1.setAngle(0.0);
encoder2.setPin1(20);
encoder2.setPin2(21);
encoder2.setAngle(0.0);
//setup for encoder on the edge
pinMode(encoder1.getPin1(), INPUT); //setting up the pins
pinMode(encoder1.getPin2(), INPUT);
digitalWrite(encoder1.getPin1(), HIGH); //setting the pin on (HIGH voltage)
digitalWrite(encoder1.getPin2(), HIGH);
attachInterrupt(digitalPinToInterrupt(encoder1.getPin1()), counterUp1, RISING); // attaching interrupt automates task
attachInterrupt(digitalPinToInterrupt(encoder1.getPin2()), counterDown1, RISING); // of reading from rotary encoder
//setup for encoder on the cart
pinMode(encoder2.getPin1(), INPUT);
pinMode(encoder2.getPin2(), INPUT);
digitalWrite(encoder2.getPin1(), HIGH);
digitalWrite(encoder2.getPin2(), HIGH);
attachInterrupt(digitalPinToInterrupt(encoder2.getPin1()), counterUp2, RISING);
attachInterrupt(digitalPinToInterrupt(encoder2.getPin2()), counterDown2, RISING);
}
void loop() {
Serial.print("Encoder 1");
encoder1.getCounter(counter1);
encoder1.calculateAngle(counter1);
encoder1.getAngle();
//uncomment for displacement
//encAngle = encoder1.returnAngle();
//encAngle = encAngle*2*3.14/360;
//displacement = encAngle * 18.942;\
//Serial.print("DISPLACEMENT -->");
//Serial.print(displacement);
//Serial.print("mm");
delay(1000);
Serial.print("Encoder 2");
encoder2.getCounter(counter2);
encoder2.calculateAngle(counter2);
encoder2.getAngle();
delay(1000);
}
//This function increases the counter when second pin in LOW
void counterUp1(){
if(digitalRead(encoder1.getPin2())==LOW) {
counter1++;
}else{
counter1--;
}
}
//This function increases the counter when first pin in LOW
void counterDown1(){
if(digitalRead(encoder1.getPin1())==LOW) {
counter1--;
}else{
counter1++;
}
}
//This function increases the counter when second pin in LOW
void counterUp2(){
if(digitalRead(encoder2.getPin2())==LOW) {
counter2++;
}else{
counter2--;
}
}
//This function increases the counter when first pin in LOW
void counterDown2(){
if(digitalRead(encoder2.getPin1())==LOW) {
counter2--;
}else{
counter2++;
}
}
//This function displays the counter in the serial port
void encoderClass::getCounter(volatile unsigned int count){
Serial.print(" Your counter is: ");
Serial.println(count);
}
//This function displays the angle in the serial port
void encoderClass::getAngle(){
Serial.println("Your angle is: ");
Serial.println(angle);
}
//This function calculates the angle from the encoder
void encoderClass::calculateAngle(volatile unsigned int count){
angle = count * 0.3;
}
//This function returns the first pin
int encoderClass::getPin1(){
return encoderPin1;
}
//This function returns the second pin
int encoderClass::getPin2(){
return encoderPin2;
}
void encoderClass::setPin1(int pin1){
encoderPin1 = pin1;
}
void encoderClass::setPin2(int pin2){
encoderPin2 = pin2;
}
void encoderClass::setAngle(float ang){
angle = ang;
}
float encoderClass::returnAngle(){
return angle;
}
You are counting the rising edges of BOTH channels. If 600 PPM resolution is enough, you only need an interrupt on one channel, the second channel can be on a non interrupt pin. When an interrupt happens, you know channel A went from LOW to HIGH, so look at channel B's pin to see which direction.