Drucker Optical Encoder auslesen

Hallo zusammen,

ich versuche mich gerade daran einen alten Inkjet-Drucker in einen Flachbrettdrucker umzubauen. Da ich den Drucker nicht speziell ansteuern kann, ist mein Plan das Signal vom eingebauten Rotary Optical Encoder auszulesen und damit parallel zum originalen Motor für den Papiereinzug einen Steppermotor anzutreiben. Der originale Motor ist dann quasi nur ein Phantom, was nur den Feedback-Loop für den Drucker aufrecht erhält. Mir ist bewusst, dass das Timing, etc. mit meinem Stepper vorerst nicht passend sein wird, aber es scheint generell so möglich zu sein (siehe: https://www.youtube.com/watch?v=OYe5iC8Qe3E&t=251s ab 4:11).

Ich habe den Encoder bereits durchgemessen und die beiden Signalpins ausfindig gemacht sowie die vom Drucker aus anliegenden Spannungen notiert:

Außerdem habe ich Kabel an die beiden Signalpins (grün und lila) gelötet und diese mit Pin 8 und 9 meines Arduino Uno Rev3 Boards verbunden. Die Signale (zwischen 0V und 3,22V) möchte ich mit folgendem Code auslesen:

#include <avr/interrupt.h> // AVR interrupt handling
#include <Arduino.h>       // Arduino core library
#include <stdint.h>        // Standard integer types
#include <stdbool.h>       // Standard boolean types

volatile uint8_t OldState = 0;           // Store the previous state of the encoder pins
volatile int32_t Position = 0;           // Store the current position value
volatile bool InvalidInc = false;        // Flag indicating an invalid increment
const int8_t IncArray[4][4] = {
  {0, -1, 1, 2},  // Lookup table for valid increments based on state transitions
  {1, 0, 2, -1},
  {-1, 2, 0, 1},
  {2, 1, -1, 0}
};

void setup() {
  Serial.begin(9600); // Initialize serial communication
  pinMode(8, INPUT);  // Configure digital pin 8 as input
  pinMode(9, INPUT);  // Configure digital pin 9 as input
  
  cli(); // Disable interrupts
  PCICR |= 0b00000001; // Enable Pin Change Interrupt for PORT B (PCIE0)
  PCMSK0 |= 0b00000011; // Enable interrupt for PCINT0 (D8) and PCINT1 (D9)
  sei(); // Enable interrupts
}

void loop() {
  delay(100); // Delay for readability
  Serial.println(Position, DEC); // Print the current position in decimal
  
  if (InvalidInc) {
    Serial.println("LOST COUNT"); // Print a message indicating a lost count
    InvalidInc = false; // Reset the invalid increment flag
  }
}

ISR(PCINT0_vect) {
  uint8_t State = PINB & 0b00000011; // Read the state of the encoder pins
  int8_t Inc = IncArray[OldState][State]; // Get the increment value from the lookup table
  OldState = State; // Update the previous state
  Position += Inc; // Update the position value
  
  // Set the InvalidInc flag if the increment is 2
  InvalidInc |= (Inc == 2);
}

Den Code habe ich in folgendem Beitrag gefunden: Using a Canon Printer Incremental Encoder + Datasheet - #6 by snuffwooter
Dort habe ich dann auch herausgefunden, dass es sich bei dem Encoder um ein Modell vom Hersteller Kodenshi handelt (die genaue Modellnummer habe ich nicht gefunden) und er anscheinend eine Auflösung von 360 LPI hat.

Nun zum eigentlichen Problem: Im Gegensatz zum Ersteller des Codes funktioniert dieser bei mir nicht korrekt. Ich bekomme alle möglichen verrückten Zustände in der State Variable - auch wenn gar keine Spannung anliegt. Nach ein bisschen Recherche habe ich dann herausgefunden, dass das wahrscheinlich an Floating Pins liegt und ich kein definiertes LOW habe. Also habe ich einen 10k Pulldown-Widerstand eingebaut mit dem Effekt, dass zwar keine falschen Signale mehr ankommen, ich aber auch keine Signale bekomme, wenn sich die Encoder-Scheibe dreht. Meine Schaltung sieht ungefähr so aus:


Dabei sind die beiden langen Verbindungen von rechts die beiden Signalpins vom Encoder.

Als jemand der sich nicht wirklich mit Elektrotechnik auskennt bin ich hier mit meinem Latein am Ende und hoffe, dass jemand mehr Ahnung hat, was ich falsch mache. Eventuell muss ich den Drucker und meinen Arduino auch irgendwie mit mehr als nur den beiden Signalpins verbinden, aber da bin ich sehr unsicher.

Viele Grüße
Nico

1 Like

Du musst den GND des Arduino mit dem GND des Encoders verbinden.

Das ist ja im Prinzip das gleiche, als würde ich den GND des Arduino mit dem GND des Druckers verbinden, oder? Das habe ich einmal versehentlich gemacht und dann hat sich der Motor wie verrückt gedreht. Kam mir nicht ganz richtig vor, deswegen habe ich das lieber gelassen. Sollte ich das denn zusätzlich zu meinem obigen Diagramm machen, oder ist daran sonst noch etwas falsch?

Das war schon richtig. Der Arduino wird an den Pins des Encoders dann vermutlich den Eingang des zuständigen Controllers belasten, was nicht gewollt ist.
Nimm mal die beiden 10K R'S aus Deiner Schaltung.

Super, vielen vielen Dank. Ohne die Widerstände, aber dafür mit der GND zu GND Verbindung klappt es einwandfrei. Jetzt kann ich mir endlich überlegen, wie ich damit synchron einen Stepper Motor antreibe.

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