I’ve spent some time playing around the idea of using stepper or brushless motors as rotary encoders.

Stepper acts as a high impedance AC voltage source outputing sinusoidal waveform, it’s just a matter of apmlifying and converting this signal to a square wave:

schematics

R1 and R2 set up a reference voltage, R3 and C2 low-pass filter the signal from a motor - when this signal goes above the reference voltage, comparator changes it’s output producing a nice square wave.

The same effect can be obtained using a high gain noninverting op amp circuit, but as opamps are not really ment to be operated in saturation regions, I’ve decided to go with a comparator.

You have to do this to two phases of a stepper motor - one phase will lag the other - this way you can determine a direction of rotation.

Here is a piece of arduinized avr code that reads the encoder and drives a single digit 7 segment display:

void setup() {
  DDRD = 0xFF;//setup port D as ouput for 7-seg display
  pinMode(8, INPUT);//motor phase 1 on PORTC 0
  pinMode(9, INPUT);//motor phase 2 on PORTC 1
}


byte digits[] = {
  0b00000011,//0
  0b11110011,//1
  0b10000101,//2
  0b00001101,//3
  0b00111001,//4
  0b01001001,//5
  0b01000001,//6
  0b00011111,//7
  0b00000001,//8
  0b00001001,//9
};

byte t = 0; //step counter
byte lastVal = 0; //last value of motor phase inputs
byte b = 1; //segment which is displayed
byte digit = 0; //digit that is displayed

void loop() {
  //flash one segment every loop
  PORTD = digits[digit] | ~(0x01 << b);
  b++;
  if(b > 7) {
    b = 1;
  }

  //read status of motor pins  
  byte val = PINB & 0x03;

  if(val != lastVal) {
    if((val == 3 && lastVal == 2) ) {
      //t is just a step counter, we change the digit every 3 steps
      t++;
      if(4 == t) {
        t = 0;
        digit++;
        if(10 == digit) {
          digit = 0;
        }
      }
    } else if ((val == 2 && lastVal == 3) ) {
        if(0 == t) {
          t = 4;
          if(0 == digit) {
            digit = 10;
          }
          digit --;
        }
        t--;
    }
    lastVal = val;
  }
}

Published February 18 2013 by miceuz
Permalink