Differential encoder interfacing with arduino

I am using differential quadrature encoder which is having rs422 differential output. To interface with arduino I am using MC3486 line receiver IC output of MC3486 is given to arduino interrupt.

But I am getting values at arduino end even if motor is not moving.

knowledge: I am using differential quadrature encoder which is having rs422 differential output. To interface with arduino I am using MC3486 line receiver IC output of MC3486 is given to arduino interrupt.

But I am getting values at arduino end even if motor is not moving.

I see one of 4 possible serial outputs on the chip. Why are sending serial data to an interrupt pin? A schematic of your project is certainly needed.

Paul

Attached is the schematic.

Output of IC 3486-

DIFFERENTIAL INPUTS ENABLE OUTPUT
A–B Y
VID ≤ 0.2 V H H
–0.2 V < VID < 0.2 V H ?
VID ≤ –0.2 V H L
Irrelevant L Z
Open H ?
IC output is tri-state

knowledge: I am using differential quadrature encoder which is having rs422 differential output. To interface with arduino I am using MC3486 line receiver IC output of MC3486 is given to arduino interrupt.

But I am getting values at arduino end even if motor is not moving.

I don't understand the statement "I am getting values at the Arduino". You should be getting either a LOW or a HIGH the the Arduino pin. Is that what you meant? You should ALWAYS get something, low or high while the encoder is powered.

What are the voltages you are getting from the the encoder output? Are they higher than 0.2 and lower than -0.2?

How is the encoder powered?

Paul

Yes, I am getting continuously HIGH & LOW signals at arduino input. I should get values when motor is rotating but I am getting values when motor is in steady state.

+5v is given to encoder separately. All grounds are common.

Hi,
Is your project associated with this thread?
http://forum.arduino.cc/index.php?topic=543224.0

Can you please post your code?

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.

Can you please post a copy of your complete circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

What is the encoder, make, model, link to data/specs please.
Ops image.
76e827b98da2da4dc6e150e2736fca398b8a8768.png
Tom… :slight_smile:

knowledge: Yes, I am getting continuously HIGH & LOW signals at arduino input. I should get values when motor is rotating but I am getting values when motor is in steady state.

+5v is given to encoder separately. All grounds are common.

How do you know this is not correct? Perhaps the device changes frequency when rotated.

Paul

[ / code]

#include "PinChangeInterrupt.h" // PinChange Interrupt library

signed long pulses;                              //Output pulses.
int pulsesChanged = 0;


int encoderA = 2;
int encoderB = 3;
int encoderZ = 4;



void setup() {

  Serial.begin(115200);
  Serial.flush();

  pinMode(encoderA, INPUT);
  pinMode(encoderB, INPUT);
  pinMode(encoderZ, INPUT);
  attachInterrupt(digitalPinToInterrupt(2), A_CHANGE, CHANGE);
  attachInterrupt(digitalPinToInterrupt(3), B_CHANGE, CHANGE);

}



void loop() {


}


void A_CHANGE() {
  if ( digitalRead(encoderB) == 0 ) {
    if ( digitalRead(encoderA) == 0 ) {
      // A fell, B is low
      pulses--; // moving reverse
    } else {
      // A rose, B is low
      pulses++; // moving forward
    }
  } else {
    if ( digitalRead(encoderA) == 0 ) {
      // B fell, A is high
      pulses++; // moving reverse
    } else {
      // B rose, A is high
      pulses--; // moving forward
    }
  }
  pulsesChanged = 1;

  data();
}


void B_CHANGE() {
  if ( digitalRead(encoderA) == 0 ) {
    if ( digitalRead(encoderB) == 0 ) {
      // B fell, A is low
      pulses++; // moving forward
    } else {
      // B rose, A is low
      pulses--; // moving reverse
    }
  } else {
    if ( digitalRead(encoderB) == 0 ) {
      // B fell, A is high
      pulses--; // moving reverse
    } else {
      // B rose, A is high
      pulses++; // moving forward
    }
  }
  pulsesChanged = 1;

  data1();
}


void data1() {
  if (pulsesChanged != 0) {
    pulsesChanged = 0;
    int readB = digitalRead(encoderB);
    Serial.print("B  ");
    Serial.println(readB);
    Serial.println(pulses);

    Serial.flush();
  }
}

void data() {
  if (pulsesChanged != 0) {
    pulsesChanged = 0;
    int readA = digitalRead(encoderA);

    Serial.print("A   ");
    Serial.println(readA);

    Serial.println(pulses);

    Serial.flush();
  }
}
[code]

Yes, same project.

Please find attachment of schematic.[/code]

Hi, Thanks, OPs Circuit; |500x281

What is the encoder, make, model, link to data/specs please.

How long is the cable from the encoder to the 3486?

Tom.. :)

Paul_KD7HB: How do you know this is not correct? Perhaps the device changes frequency when rotated.

Paul

I can see motor is not rotating so I am definitely sure that I am not getting results. And I am not getting one or two changes in output it is continuously changing.

So I am not able to differentiate when motor is actually rotating.

Try this version. If one of the pins is pulsing even when the encoder isn't moving it may be noise in the signal.

volatile long Position = 0;                //Output pulses.
volatile boolean PinAChanged = false;
volatile boolean PinBChanged = false;


const unsigned long ReportInterval = 500;  // Display position twice per second, if changed.


const byte EncoderAPin = 2;
const byte EncoderBPin = 3;
const byte EncoderZPin = 4;


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


  pinMode(EncoderAPin, INPUT);
  pinMode(EncoderBPin, INPUT);
  pinMode(EncoderZPin, INPUT);


  attachInterrupt(digitalPinToInterrupt(EncoderAPin), A_CHANGE, CHANGE);
  attachInterrupt(digitalPinToInterrupt(EncoderBPin), B_CHANGE, CHANGE);
}


void loop() {
  static unsigned long timeOfLastReport;
  unsigned long currentTime = millis();


  if (currentTime - timeOfLastReport >= ReportInterval) {
    timeOfLastReport += ReportInterval;


    // Grab volatile data with interrupts off
    noInterrupts();
    boolean pinA = PinAChanged;
    PinAChanged = false;
    boolean pinB = PinBChanged;
    PinBChanged = false;
    long position = Position;
    interrupts();


    if (pinA || pinB) {  // If either pin changed
      if (pinA)
        Serial.print("Pin A Interrupted. ");
      if (pinB)
        Serial.print("Pin B Interrupted.");
      Serial.println(position);
    }
  }
}




void A_CHANGE() {
  PinAChanged = true;
  boolean stateA = digitalRead(EncoderAPin);
  boolean stateB = digitalRead(EncoderBPin);


  if (stateA) {     // A rose
    if (stateB) {   // B is HIGH
      Position--;   // moving reverse
    } else {        // B is LOW
      Position++;   // moving forward
    }
  } else {          // A fell
    if (stateB) {   // B is HIGH
      Position++;   // moving forward
    } else {        // B is LOW
      Position--;   // moving reverse
    }
  }
}


void B_CHANGE() {
  PinBChanged = true;
  boolean stateA = digitalRead(EncoderAPin);
  boolean stateB = digitalRead(EncoderBPin);


  if (stateB) {     // B rose
    if (stateA) {   // A is HIGH
      Position++;   // moving forward
    } else {        // A is LOW
      Position--;   // moving reverse
    }
  } else {          // B fell
    if (stateA) {   // A is HIGH
      Position--;   // moving reverse
    } else {        // A is LOW
      Position++;   // moving forward
    }
  }
}

Since the OP won't tell us if or how the encoder is powered, my guess is: it is not powered and so the pins on the encoder are floating and this is what he is seeing.

Paul

1) Are your stepper motors connected with 500 meters of cable as well?

2) At 500 meters, the cable type chosen will be a critical factor. It must be shielded, twisted pair cable specifically for RS422 use.

3) Remove the capacitors from the signal lines.

4) Are the resistors 200 ohms?

avr_fred: 1) Are your stepper motors connected with 500 meters of cable as well?

2) At 500 meters, the cable type chosen will be a critical factor. It must be shielded, twisted pair cable specifically for RS422 use.

3) Remove the capacitors from the signal lines.

4) Are the resistors 200 ohms?

Sorry cable length is 500mm & cable is shielded.

Value of resistor is 200ohms

Cables for Stepper motor is of 200mm length

The capacitors must be removed.

The need for the resistors is questionable with short cables and I would testing without them. When required for voltage reflection issues, R should be closer to 100-120 ohms, not 200.

Paul_KD7HB: Since the OP won't tell us if or how the encoder is powered, my guess is: it is not powered and so the pins on the encoder are floating and this is what he is seeing.

Paul

Externally supply is given to encoder which is denoted as +5v in schematic. This is supplied by 5v SMPS and same supply is given to line receiver IC 3486.

knowledge: I can see motor is not rotating so I am definitely sure that I am not getting results. And I am not getting one or two changes in output it is continuously changing.

So I am not able to differentiate when motor is actually rotating.

Thank you for your code. I have tested circuit with this code. I am getting same results, continuous increment in pulses.

Here is attached results:

Pin A Interrupted. Pin B Interrupted.-479
Pin A Interrupted. Pin B Interrupted.-477
Pin A Interrupted. Pin B Interrupted.-486
Pin A Interrupted. Pin B Interrupted.-496
Pin A Interrupted. Pin B Interrupted.-502
Pin A Interrupted. Pin B Interrupted.-505
Pin A Interrupted. Pin B Interrupted.-505
Pin A Interrupted. Pin B Interrupted.-505
Pin A Interrupted. Pin B Interrupted.-507
Pin A Interrupted. Pin B Interrupted.-497
Pin A Interrupted. Pin B Interrupted.-507
Pin A Interrupted. Pin B Interrupted.-509
Pin A Interrupted. Pin B Interrupted.-502
Pin A Interrupted. Pin B Interrupted.-504
Pin A Interrupted. Pin B Interrupted.-524
Pin A Interrupted. Pin B Interrupted.-539
Pin A Interrupted. Pin B Interrupted.-547
Pin A Interrupted. Pin B Interrupted.-556

You may have to accept the fact that your device is broken. Did you buy it new or did you find a used device?

Paul

If you are getting this many pin changes when the encoder isn't moving I can only guess that there is some pretty bad noise on the input pins. Put an oscilloscope on those pins to see what is happening. Also put an oscilloscope on the input pins of the IC to see if the differential inputs are behaving properly.

Hi,
From your previous thread, did you try this connection config?
4cd343b4ada1bfd607363f104de23cc558923074.png

Can you please post a link to the specs/data of your encoder please?
What is its make and part number?

Tom… :slight_smile: