Conversion of absolute encoder to incremental encoder with commutation

Hi all,

I'm running into a bit of a wall. I working on a sub project in my research lab to convert the 14-bit digital output of an absolute encoder so that it behaves like an incremental encoder for the motor drive using the Arduino Mega 2560. I already have a code, untested, that I believe will convert it to behave like a deferentially wired incremental encoder with A, B, and Z channels. The issue is that I now need to simulate a UVW commutation signal and I have no idea how to approach it.

I've been unable to find any substantial reading on incremental encoders and commutation outputs. I need advice on how I should interpret the input from the absolute encoder, or reading material on the subject.

In a nutshell:
How could the output of an absolute encoder be viewed and interpreted to mimic a commutation signal?

This is the 14-bit absolute to ABZ incremental conversion code that I currently have:

//inputs
const int inputArray[14] = {27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53}; //digital read pins, most to least significant bit
const int MSB = 27, LSB = 53, upperBit = 51;  //incremental bits

//outputs
const int chanA = 22;
const int chanAo = 24;
const int chanB = 26;
const int chanBo = 28;
const int chanZ = 30;
const int chanZo = 32;

//Incremental output values
int A, B, Z, Ao, Bo, Zo;
//iterator initialization 
int i;

void setup() {
  Serial.begin(9600);
  
  //set inputs
  for (i = 0; i < 14; i++) {
    pinMode(inputArray[i], OUTPUT);
  }
  
  //set outputs
  pinMode(chanA, OUTPUT);
  pinMode(chanAo, OUTPUT);
  pinMode(chanB, OUTPUT);
  pinMode(chanBo, OUTPUT);
  pinMode(chanZ, OUTPUT);
  pinMode(chanZo, OUTPUT);
  
}

void loop() {
  gatherBits();
  writeABZ();
}

//outputs digital values for A, B, and Z and there not channels
void writeABZ () {
  if (A == 0) Ao = 1; else Ao = 0;
  if (B == 0) Bo = 1; else Bo = 0;
  if (Z == 0) Zo = 1; else Zo = 0;
  
  digitalWrite(chanA, A);
  digitalWrite(chanAo, Ao);
  
  digitalWrite(chanB, B);
  digitalWrite(chanBo, Bo);
  
  digitalWrite(chanZ, Z);
  digitalWrite(chanZo, Zo);
}


//collects output values for bits A, B, and ref
void gatherBits() {
  Z = checkZ();
  A = digitalRead(upperBit);
  B = checkB();
}

//determines if the shaft is at the reference points(all bits HIGH)
int checkZ() {
      for (i = 0; i < 13; i++) {
        if (digitalRead(inputArray[i]) == 0) return 0; 
      }
      return 1;
}

//Determines if B is HIGH or LOW
int checkB() {
  int second = digitalRead(LSB);
  if (A == 1 && second == 1) return 0;
  if (A == 1 && second == 0) return 1;
  if (A == 0 && second == 1) return 1;
  return 0;
}

Datasheet for the encoder?

Information on the brushless motor controller you are trying to interface to?

In principle this is simple, you need to interface to the absolute encoder and use an "event handler"
call into the commutation code (every time the input state changes, call to update the commutation
part). Does the absolute encoder have a multiple of 6 steps per rotation? That will likely simplify things.

Interesting problem. I'm more a hardware type then software so I won't try to determine if you sketch is a good solution or not. But here is how I would approach the problem. I would wire the 14 bits to two mega input ports (I don't recall if all ports have pin change interrupts or not, but most do I think) that have pin change interrupt capability. Then when any change of any bit on either port creates an interrupt, read the absolute value and compare it with the previous position value you saved. From that you can easily test if it's a 'forward' step or a 'backwards' step.

What do you think?

Lefty

What kind of output does the absolute encoder have? If it is a straight binary - the least significant bit will change every time the encoder value changes, there is your pin change interrupt. Absolute Encoder reads all zeros then Z=1, otherwise z = 0. Then look and the 2 lowest value bits - = will read from 0 to 3 (00, 01, 10, 11) output bits A & B will map to this pattern = 0 - 00, 1 - 01, 2 - 11, 3 -10.

You could change which 2 bits you read from the absolute encoder and change your resolution. (as long as they are consecutive bits)