LPA3806-600BM-G5-24C Rotary Encoder Output

Hey guys,

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.

Thanks in advance.

The first image on this optical encoder tutorial page shows a "code wheel". The number of pulses per rev is the number of divisions on the code wheel.

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?

I would have to see your program to be sure, but it seems that you are counting both edges of the pulses (ie. interrupt on change).

Post your code (in code tags, please) and I can tell for sure.

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.

void ISR ()
{
  if(digitalRead(channelBpin))
    counter++;
  else
    counter--;
}