Absolute rotary encoder 10 bit help with code needed

Hello,

I’m working on my bachelor project and i need to be able to read a rotary encoder. The rotary encoder i’m working with is the Koyo absolute rotary encoder TRD-NA1024NW.
datasheet can be found here: http://www.koyoele.co.jp/english/product/encoder/pdf/TRD_NA.pdf

It has 10 output pins. Now i’ve plugged in the pins on my arduino uno from pin 3 to 12. (see picture) And i’m trying to read the movements of the encoder on the serial monitor using this code:

#define BITS 10
#define LSB 12

int gray_decode(unsigned int n) { 
  unsigned int p = n;
  while ( n = n >> 1) p = p ^ n;
    return p;
}

int binToDec(int *inputval, int bits){
  int i;
  int val = 1;
  int result = 0;

  for (i = bits - 1; i >= 0; i--){
    result += inputval[i] * val;
    val *= 2;
  }
return result;
}

void setup(){
  int i;
  for (i = LSB; i > LSB - BITS; i--){
    pinMode(i, INPUT_PULLUP);
  }
  Serial.begin(115200);
  Serial.print("ready\n");
}

void loop(){
  int rawValues[BITS];
  int i, j;
  int result;

  j = BITS - 1;

  for (i = LSB; i > LSB - BITS; i--){  
    int readVal;
    readVal = !digitalRead(i);
    rawValues[j] = readVal; 
    j--;
  }


  result = binToDec(rawValues, BITS); 
  result = gray_decode(result); 

  for(j = 0; j < BITS; j++){
    Serial.print(rawValues[j]);  
  }

Serial.print("\t");
Serial.println(result);
delay(100);
}

when i run this i only get zero values and some random jumps in values as you can see below. Slowly turning the encoder does nothing…

0000000000 0
0000000000 0
0000000000 0
0000000000 0
0000000000 0
0000000000 0
0100000000 511
0000000000 0
0000000000 0
0000000000 0
0000000000 0
0000000000 0
0000000000 0
0000000000 0
0000100000 63
0000000000 0
1000000000 1023
0000000000 0
1000000000 1023
0000000000 0
0000000000 0
0000000000 0
0000000000 0
0000000000 0
0000000000 0
0000010000 31

I would appreciate any input/thoughts that might help me in the right direction.

Thanks

I don't immediately see anything wrong with your code so I suspect a connection problem and you have not posted a schematic of what you have done. Have you a GND connection as well as the 10 data connections? And a 12v power connection to the Encoder?

If it was my project I would disconnect all but one or two pins and just concentrate on getting reliable 1s and 0s.

...R

Hi, the spec shows that your encoder has NPN open collector outputs.
You will need to provide a resistor on each output going to positive supply.
There will be in the spec how much current can conduct through the output, this will then govern the value of pull up resistor as it is called.

Tom… :slight_smile:

put the declarations outside the loop now they are resetted each loop.

I hade the same issues. Did rewrite the code alot and many times but no result. Eventually i found out that my VCC to the Koyo encoder was too low. I hade 9,5v, set it at 12V and all the readings was perfect! Maybe same issue?

Hey There, I encountered the same problem. Koyo TRD-na1024nw-2302 and I have a Arduino Mega

http://www.motioncontrol.in.th/article/%E0%B8%AD%E0%B9%88%E0%B8%B2%E0%B8%99%E0%B8%84%E0%B9%88%E0%B8%B2-absolute-encoder-%E0%B8%94%E0%B9%89%E0%B8%A7%E0%B8%A2-arduino I've tried it, but I failed

Im not sure i understand your problem but are you aware that these coders use greycode ? They do not use sequential binary output It may just be a connection problem but reading binary outputs could give a confusing diagnosis

TomGeorge:
Hi, the spec shows that your encoder has NPN open collector outputs.
You will need to provide a resistor on each output going to positive supply.

Tom… :slight_smile:

Have you configured the input pin pullup rasistors ?

Post your circuit diagram.

These are relativley uncommon devices in arduino land, it maybe that the hardware/electronics is at fault rather than your programming

I connect pullup resistor on each output. did not happen. Then I disconnect the encoder, serial continuously monitor 682 682 682 682 says

emrekantarci: I connect pullup resistor on each output. did not happen.

Why did you "connect" a resistor on each output? Are there long cables from the encoder to the Arduino board? More than just a few centimetres?

Pullup resistors are built-in in the Atmega controller, you easily can activate them by software with INPUT_PULLUP pinMode:

  pinMode(pinNumber, INPUT_PULLUP);

Done. And that's what you did in your initial code.

But you need to connect "sensor voltage GND" with "Arduino voltage GND" as well. So that GND is at the same 0V/GND level with both.

Did you?

And I really do not understand anything about how you are trying to decode the bits:

I'd suggest something like that to show the raw bits:

for (i = LSB; i > LSB - BITS; i--)
{  
  Serial.print(!digitalRead(i));
}
Serial.println();

The datasheet doesn't tell me anything about "BCD code" and/or "Gray code".

Worked. First of all thank you for your answer. 1 The idea of each output resistance, because of the video I saw on the links https://www.youtube.com/watch?v=pwyfz4icpqo Encoder cable's length of 30 cm arduino encoder connection cable 20 cm

But you need to connect "sensor voltage GND" with "Arduino voltage GND" as well. So that is at the same GND 0V / GND level with both. [/ quote] You are very right. I connect to the Arduino GND encoder. The problem was solved immediately. Gray code and number from 0-1023, the same time displayed.

I think there is an error in the software. Does not indicate the absolute position After arriving at the zero point; 1,2,3,4,5,6 increasing as I turned right.

if not right, I turn to the left is growing as 1,2,3,4,5,6.

emrekantarci:
I think there is an error in the software.
Does not indicate the absolute position
After arriving at the zero point;
1,2,3,4,5,6 increasing as I turned right.

if not right, I turn to the left is growing as 1,2,3,4,5,6.

If the decoding is not correct, there is an error in your decoder.

So the decoding logic needs to be fixed.

First thing I’d do is: Reading and showing the raw data. Perhaps with some code like that:

#define BITS 10
#define MSBPIN 3

void setup(){
  for (int i =0;i<BITS; i++){
    pinMode(MSBPIN+i, INPUT_PULLUP);
  }
  Serial.begin(115200);
  Serial.print("ready\n");
}

char rawValStr[BITS+1], oldRawValStr[BITS+1];

void loop(){
  memset(rawValStr,0,sizeof(rawValStr));
  for (int i =0; i<BITS; i++){
    rawValStr[BITS-i-1] = '0'+!digitalRead(MSBPIN+i);
  }
  if (strcmp(rawValStr,oldRawValStr)!=0) Serial.println(rawValStr);
  strcpy(oldRawValStr,rawValStr);
}

If you’d post some example output of the decoder when at position 0000000000 and turning to right, and also some example output when turning from position 0000000000 to the left, I could look over it, how it would be possible to find out the absolute position.

As the manufacturer tells in the datasheet that this is an absolute position encoder, it should be possible to find out.

emrekantarci:
I think there is an error in the software.
Does not indicate the absolute position
After arriving at the zero point;
1,2,3,4,5,6 increasing as I turned right.

if not right, I turn to the left is growing as 1,2,3,4,5,6.

ONE year late here…

I have two TRD-NA1024NW units. Both of mine appeared to be doing something similar to yours at first glance. But closer inspection of the data reveals something different.

For my two encoder units, I start at 0000000000 (10 bits). With the top of the encoder shaft facing toward my eyes, I rotate the dial clockwise (relative to me) with my fingers, and I get 0000000001, then next value is 0000000101, then 0000000100, then 0000000110 … which are decimal counts of 0, 1, 5, 4, 6 …

Then I go back to the zero position, then rotate the dial anti-clockwise, and I get 0000000010, then get 0000000011, then 0000001011; which are decimal counts of 0, 2, 3, 11 …

Attached is a screenshot of bit value results I’m getting as I slowly turn the dial clockwise…

My spreadsheet is attached too. Even if I re-arrange the bit columns, the pattern doesn’t seem to correspond with usual gray code. Eg … if I switch the last four columns around to try get a 3 bit gray code… we get…

000
001
011
010
110
111

The next value ‘expected’ for gray code would be 101. However, for my trd-na1024 units, the next value turns out to be…
1111 (4 bits)… ie the fourth bit kicks in.

I attached my spreadsheet in a zip file as well.

Colour codes on my wires match up with the manufacturer details…

black: bit0
red: bit1
orange: bit2
yellow: bit3
green: bit4
purple: bit5 etc.

At the moment, I’m just taking my time to slowly map out the bit values … and put them in my spreadsheet… and making sure that the bits change by only 1 bit at a time, and to check if each pattern is unique.

The code I’m using is shown below as well…I’m using a MEGA2560 with b0 to b9 of the encoder unit connected to arduino digital pins 2 to 11 (in that order).

int b0=0;
int b1=0;
int b2=0;
int b3=0;
int b4=0;
int b5=0;
int b6=0;
int b7=0;
int b8=0;
int b9=0;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);        // connect to the serial port
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, INPUT);
  pinMode(7, INPUT);
  pinMode(8, INPUT);
  pinMode(9, INPUT);
  pinMode(10, INPUT);
  pinMode(11, INPUT);

  
}

void loop() {
  // put your main code here, to run repeatedly:
  b0 = digitalRead(2);
  b1 = digitalRead(3);
  b2 = digitalRead(4);
  b3 = digitalRead(5);
  b4 = digitalRead(6);
  b5 = digitalRead(7);
  b6 = digitalRead(8);
  b7 = digitalRead(9);
  b8 = digitalRead(10);
  b9 = digitalRead(11);



  Serial.print(b9);Serial.print(b8);
  Serial.print(b7);Serial.print(b6);
  Serial.print(b5);Serial.print(b4);  
  Serial.print(b3);Serial.print(b2);
  Serial.print(b1);Serial.println(b0);  
  delay(1000);

}

Anybody else here using the TRD-NA1024NW? Are you getting proper gray code bit values instead of the stuff that I’m seeing?

excel_spreadsheet.zip (6.65 KB)

Hi,

Google grey code

If you notice only one bit at a time changes with each position. There are methods to read this if you google grey code arduino

Tom... :)

TomGeorge:
Hi,Google grey code
If you notice only one bit at a time changes with each position.
There are methods to read this if you google grey code arduino

Thanks Tom! Yeah…I know how gray code works. My encoder appears to be changing by 1 bit at a time, but not in usual gray code style.

I’ve only mapped out the first 31 positions (manually, for now).

I was assuming that the 10 bit encoder would output the usual gray code pattern… such as:

(a typical gray code pattern below)
0000000000
0000000001
0000000011
0000000010
0000000110
0000000111
0000000101
0000000100
0000001100
0000001101
0000001111
0000001110
0000001010
0000001011
0000001001
0000001000
0000011000
0000011001
0000011011

…but my encoder isn’t following that pattern as far as I can see so far. But at least the patterns for my units are changing 1 bit at a time.

I will later hook up the encoder to a stepper, and do some microstepping… and see if I can map the rest automatically.

The encoders I got (two of them) are TRD-NA1024NW … meant to be 10 bit, 1024 position to cover one revolution. Manufacturer specs mention ‘gray code’, so I’m assuming the bit pattern (when wired correctly) should follow the usual gray code pattern. That isn’t the case for my two encoders.

The description of what I’m seeing with the TRD-NA1024NW 10 bit (1024 position) absolute encoder is at …click here…

Also, interestingly - my encoder pattern is following the 1-bit change pattern discussed at:

…this link here…

which is… 0000 0001 0011 0010 0110 0111 1111 1110 etc.

Southpark: The encoders I got (two of them) are TRD-NA1024NW .... meant to be 10 bit, 1024 position to cover one revolution. Manufacturer specs mention 'gray code', so I'm assuming the bit pattern (when wired correctly) should follow the usual gray code pattern. That isn't the case for my two encoders.

Where did you get the encoders from ?

Salvaged from say a printer , they may be custom pinouts which you will not find in online documentation.

Boardburner2:
Where did you get the encoders from ?

Salvaged from say a printer , they may be custom pinouts which you will not find in online documentation.

I got them from ebay. The seller has so far sold 739 items (not just encoders I think)…and got 99.6% rating.

The two units I got appear in excellent condition. Each has their own connector…

The order of pins from left to right on my connectors (that came with the unit all wired up) are:

brown (Vcc 12 or 24 V supply input)
black - bit0
red - bit1
orange
yellow
green
purple
grey
white
black/white two-colour - bit8
red - bit9
blue (0V)

The order of the colours for the bit pattern match up exactly with the manufacturer’s colour coding too.

trd-na1024nw.jpg

It does look like a Gray code, but the bit order is different than the example shown in post #15.

If all allowed 1024 bit patterns show up, then it must be possible to remap the bits to follow the pattern shown in post #15. Just swap the wires around.