Absolute Encoder Reading Discrepancies

Hi there. I was wondering if anyone have insight on how I can deal with this issue. So far, I have a RE22SC absolute encoder of D320 (having 320 positions per revolution). I was able to get reading from the encoder, but the values are wrong after a few turns. For example, at position A = value should be 120, if I manually spin the encoder shift, it will read 120 at position A. But using a drill and rotating it for a few rounds, position A will read 77 or some very off value. It appears that there is a discrepancy per revolution with the encoder reading.

I think it would be:

  1. The code is reading is bit by bit and under 8 bits when it is "decimal", which I have no idea what it is. And I have no idea if the encoder is 8 bit.
  2. There is a reading issue with delays and timing and clocking. And I have double checked and played with the numbers but not too sure.
  3. Mechanical system design issue... which is a bigger problem...

Anyways, any guidance and help will be much appreciated.

The encoder data sheet: https://www.rls.si/eng/fileuploader/download/download/?d=1&file=custom%2Fupload%2FRE22D01_06EN_data_sheet.pdf

The code:

//Updates March 28, 2020
//V2 focus on fixing the cycle issue 

//Note: use 356 instead of 360
//Using 1602 A, which is 16 characters and 2 lines


//Include libraries 
#include <Wire.h>

//Magnetic Encoder 
const int CLOCK_PIN = 12;
const int DATA_PIN = 13;
const int BIT_COUNT = 9; // this's the percision of rotary encoder.
const int TDC_Angle = 162; //310
int previoussensorAngle;
int offset = 10;

//////////////////=======================
//SOLENOID WHERE? 
const int SOLI_PIN = 5;
const int SOLE_PIN = 6; 

//export to data file 
//import processing.serial.*;
//Serial mySerial;
//PrintWriter output;

void setup() {
  pinMode(DATA_PIN, INPUT);
  pinMode(CLOCK_PIN, OUTPUT);
  digitalWrite(CLOCK_PIN, HIGH);
  Serial.begin(115200);
  Wire.begin();
  Serial.println("Magnetic Encoder Set Up Completed");
}

void loop() {
  int count=0;
while (count<2) {
  byte sensorAngle = readPosition();
  Serial.println(sensorAngle);
  if (sensorAngle<previoussensorAngle) {
  count=count+1;
  //Serial.println(count);
  }
  
  previoussensorAngle=sensorAngle;
  }
}


////////////////////
float readPosition() {
  byte BYTE = shiftIn(DATA_PIN, CLOCK_PIN, BIT_COUNT);
  delayMicroseconds(12.5);  // Clock must be high for 12.5-20.5 microseconds before a new sample can be taken, (12.5 = 9-12 deg per increment, 20.5 = 13-14 deg per increment)

  return (BYTE); // ouptut value from 0 to 360 with two point percision
}

//read in a byte of data from the digital input of the board.
byte shiftIn(const int data_pin, const int clock_pin, const int bit_count) {
  byte data = 0;

 for (int i=0; i<bit_count; i++) {
    data <<= 1;
    digitalWrite(clock_pin,LOW);
   // delayMicroseconds(3);
    digitalWrite(clock_pin,HIGH);
   // delayMicroseconds(3);

    data |= digitalRead(data_pin);
  }

  return data;
}```

As I understand it, SSI devices can be controlled by the SPI library of arduino. That should work reliably and not suffer from delay, timing and clocking problems. Also it ensures that your clock is at a consistent frequency.

If your problem is related to mechanical design, you should ask the manufacturer.

Defining BIT_COUNT as 9 could be an issue here :wink:

Why is that? I have also tried every value from 7 to 15.

A byte only had 8 bits. If you shift in 9 bits, then the first bit in will be lost.

It is still not working. There is still a discrepancy. And the discrepancy is not constant either.
At revolution #10 the discrepancy is about 10 degrees
but after revolution #20, the discrepancy is about 15 degrees.

An absolute encoder should never lose position.

You are probably violating some communications specification. According to the data sheet, the RE22SC is RS-422. What are you using for the interface, which normally has positive and negative voltage swings?

Yeah I agree. But I am not sure what’s going wrong. We are using Rs422.

NOYITO RS422 to TTL UART MCU Serial Port Signal Mutual Conversion Module with Over-Voltage Over-Current Protection (5V).
Link: https://www.amazon.com/dp/B07BJJ6C88?ref=ppx_pop_mob_ap_share

I see the spec calls for BOTH the data and the CLOCK to be RS-422 type signals. Are the Arduino SSI signals RS-422? I don't think so.
Paul

Hi Paul, how would I go about doing that. I am not familiar with SSI.

Same way you did the data connection.
Paul

PS: You have converted the data from RS-422 to TTL for the Arduino. You also need to convert the clock from RS-422 to TTL for the Arduino.

Please post a complete wiring diagram (hand drawn, not Fritzing), showing the Arduino, the encoder and all the RS-422 adapter, power and ground connections.

The clock should be TX on the TTL Arduino side/RX on the RS-422 encoder side, while data should be TX on the RS-422 encoder side and RX on the TTL Arduino side.

Do you have the recommended termination resistor and capacitor on the data line? See encoder data sheet.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.