Optical encoder

I am trying to get an optical encoder working. It is out of an inkjet printer. Here is my test code.

// Encoder pin configuration
const int encoderPinA = 6;   // Encoder pin A
const int encoderPinB = 7;   // Encoder pin B

volatile int encoderPosition = 0;   // Current encoder position

void handleEncoder() {
  // Read the state of the encoder pins
  int pinAState = digitalRead(encoderPinA);
  int pinBState = digitalRead(encoderPinB);

  // Update the encoder position based on the change in pins
  if (pinAState != pinBState) {
    encoderPosition++;
  } else {
    encoderPosition--;
  }

  // Print the current encoder position to Serial Monitor
  Serial.print("Encoder Position: ");
  Serial.println(encoderPosition);
}

void setup() {
  // Initialize Serial Monitor
  Serial.begin(9600);

  // Set encoder pins as inputs
  pinMode(encoderPinA, INPUT);
  pinMode(encoderPinB, INPUT);

  // Attach interrupt to encoder pin A
  attachInterrupt(digitalPinToInterrupt(encoderPinA), handleEncoder, CHANGE);
}

void loop() {
  // Do other tasks here if needed
}




If I attach a meter (I don't have an oscilloscope) and spin the motor the voltage of the sensors (with reference to ground) lowers so this suggests there is ouput. The colored lines on the back of the sensor shown are what I assume is the pinouts. Could be wrong.

Try INPUT_PULLUP or install pullup resistors for an NPN output.

Even though they are pulled up on the circuit board?

You didn't mention that. Pulled up to what voltage?

BTW what's your question?

For a encoder you need to compare the last pin state with the current state to decide how it was rotated. I probably messed up the look up table but it should be something like this:

#define PIN_A 6
#define PIN_B 7

uint8_t readPins() {
  uint8_t ret = digitalRead(PIN_A);
  ret |= digitalRead(PIN_B) << 1;
  return ret;
}

#define STATE_COUNT 4
int8_t lookup[STATE_COUNT][4] = {
  // 0   1   2   3
  {  0, -1,  1,  0},
  {  1,  0,  0, -1},
  {  0,  1, -1,  0},
  { -1,  0,  0,  1}
};

int8_t pos = 0;

uint8_t state = 0;
void update() {
  uint8_t pins = readPins();
  auto dx = lookup[state][pins];
  state = (state + STATE_COUNT + dx) % STATE_COUNT;
  pos += dx;
}

void setup() {
  pinMode(PIN_A, INPUT);
  pinMode(PIN_B, INPUT);

  Serial.begin(115200);
}

void loop() {
  update();

  if (Serial.availableForWrite() > 8) {
    Serial.println(pos);
  }
}

On the board they appear to be pulled up to VCC (5v)

This actually ended up being a poor decoding of the pinout of the encoder (I got +ve and -ve around the wrong way) Once I fixed this it started to work. @Rintin code works great and also counts the steps.

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