rotary encoder E6A2-CW3C

Dear all

I am studying the yumo encoder e6a2-cw3c.

wiring:
brown - 5v pin
blue - GND
black - outA - pin D2
White - outB - pin D3

I am testing if it counts whell the pulses, and i am using this code

//these pins can not be changed 2/3 are special pins
int encoderPin1 = 2;
int encoderPin2 = 3;

volatile int lastEncoded = 0;
volatile long encoderValue = 0;

long lastencoderValue = 0;

int lastMSB = 0;
int lastLSB = 0;

void setup() {
  Serial.begin (115200);

  pinMode(encoderPin1, INPUT); 
  pinMode(encoderPin2, INPUT);

  digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
  digitalWrite(encoderPin2, HIGH); //turn pullup resistor on

  //call updateEncoder() when any high/low changed seen
  //on interrupt 0 (pin 2), or interrupt 1 (pin 3) 
  attachInterrupt(0, updateEncoder, CHANGE); 
  attachInterrupt(1, updateEncoder, CHANGE);

}

void loop(){ 
  //Do stuff here

  Serial.println(encoderValue);
  delay(100); //just here to slow down the output, and show it will work  even during a delay
}


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
}

and a arduino nano board.

It is a 200P/R but each revolution gives me 800 pulses why?

I am planning to fix it in a wheel car (in the center) but I need to be shure the board never looses some pulses.
What is the maximum frequency for this board or UNO?

I would to use another software (labview) to get pulses through port com. I will expect that this port does not have speed to read all pulses, but my question is if it sends the right pulses (no delays or loose position) it can be 1, 5, 8, 19, 27, 45.... but this pulses are the right pulses from number of revolutions. After calibration I would measure distance, so if I run 1000m at different speeds I will get the same length.

cpalha

By using "change" on your interrupts means you are reading both edges (rising AND falling) on both channels, 2 X 2 = 4.
If you only need the basic 200 PPR, then you only need 1 interrupt pin, and check the other channel state with another input pin (like pin 4).

attachInterrupt(0, updateEncoder, FALLING);
Then:
void updateEncoder()
{
   no interrupts;  
   If(digitalRead(pin4))
     encoderValue++;
   else
     encoderValue--;
   interrupts;
}

I'm not sure about maximum pulse rate, but there's lots of folks here who are, so keep checking back.
EDIT: Added no interrupts

Hi edgemoron

Thanks for your help. Yes it can be 200P/R

That means OUT A goes to pin 2 and output B to pin 4?

Can You please correct my code as you suggest? Sorry but I am a begginer in arduino programming.

Thanks

CPalha

Give this mod a try (but don't throw away your existing code, YET) :slight_smile:

//these pins can not be changed 2/3 are special pins
int encoderPin1 = 2;
int encoderPin2 = 4;

volatile int lastEncoded = 0;
volatile long encoderValue = 0;

long lastencoderValue = 0;

//int lastMSB = 0;
//int lastLSB = 0;

void setup() {
  Serial.begin (115200);

  pinMode(encoderPin1, INPUT_PULLUP);
  pinMode(encoderPin2, INPUT_PULLUP);

  //digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
  //digitalWrite(encoderPin2, HIGH); //turn pullup resistor on

  //call updateEncoder() when any high/low changed seen
  //on interrupt 0 (pin 2), or interrupt 1 (pin 3)
  attachInterrupt(0, updateEncoder, FALLING);
  //attachInterrupt(1, updateEncoder, CHANGE);

}

void loop(){
  //Do stuff here

  Serial.println(encoderValue);
  delay(100); //just here to slow down the output, and show it will work  even during a delay
}
void updateEncoder()
{
   no interrupts(); 
   If(digitalRead(encoderPin2))
     encoderValue++;
   else
     encoderValue--;
   interrupts();
}

/*
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
}
*/

Yes, you definitely need

  pinMode(encoderPin1, INPUT_PULLUP);
  pinMode(encoderPin2, INPUT_PULLUP);

As that model of encoder is open-collector output.

200 pulses per revolution is 800 counts per revolution. Each pulse has two edges and there are
two signals, so 2x2x200 edges to count.

Hi edgemoron

Thanks for your help

The code give me the errors below

sketch_jun02b.cpp: In function 'void updateEncoder()':
sketch_jun02b:40: error: 'else' without a previous 'if'