Arduino Sketch for Epson DEI-P91 Optical Encoder with Mabuchi FK130SH08500R Motor for Epson XP Printers

We give detailed examples of using Epson's Optical Disc Encoder to record and control a DC motor. You can modify the code for printer DTG modification or motor recision control. Three scenarios are presented: simple rotation detection, system interruptions, and precision motor control.

Product used: Epson DEI-P91 Optical Encoder with Mabuchi FK130SH08500R Motor for Epson XP Printers

Product: Product Link

YouTube Tutorial:



Sketch 1. Optical Rotary Encoder Test

//www.bchtechnologies.com
//2020.12.26
/************************
Test Epson Optical Rotary Encoder
************************/
const int PinA=2; //From Rotary Encoder
const int PinB=3; //From Rotary Encoder   
int rotaryPosition=0;       //Rotary position for PinA
int rotaryPrevPosition=0;   //Last Reading of rotary position for PinA
void setup() {
  //Tell Arduino those pins are for input
  pinMode(PinA,INPUT);
  pinMode(PinB,INPUT);
  Serial.begin(9600);
 rotaryPrevPosition=digitalRead(PinA); //initial the previous position
 Serial.print("Start. PinA position:");
 Serial.println(rotaryPrevPosition);
 Serial.print("PinB Position:");
 Serial.println(digitalRead(PinB));
 Serial.println("Ready");
} 
void loop() {
  rotaryPosition=digitalRead(PinA); //Position now
  if (rotaryPosition !=rotaryPrevPosition) //If the position changed
  { int iB=digitalRead(PinB);
    Serial.print ("A:B= ");
    Serial.print (rotaryPosition);
    Serial.print (" : ");
    Serial.println(iB);
  }
  rotaryPrevPosition=rotaryPosition;
}

Sketch 2. Optical Rotary Encoder Test with Interrups

//Kevin W Day
//BCH Technologies
//www.bchtechnologies.com
//2020.12.26
volatile int numberOfMarks; //used by interrups
const int PinA=2;   // Generating interrupts using CLK signal
const int PinB=3;    // Reading DT signal
int rotationdirection;
// Interrupt routine runs if CLK goes from HIGH to LOW
void kevin ()  {
      //delay(4);  // delay for Debouncing
      int iA=digitalRead(PinA);
      int iB=digitalRead(PinB);
      if (iA==iB)
        rotationdirection= 1;
      else
        rotationdirection= 2;
      numberOfMarks++;
}
void setup ()  {
    Serial.begin(9600);
    pinMode(PinA,INPUT);
    pinMode(PinB,INPUT);  
    attachInterrupt (0,kevin,CHANGE); // interrupt 0 always connected to pin 2 on Arduino UNO
    Serial.println("Ready");
    numberOfMarks=0;
}
void loop ()  {
    Serial.println (numberOfMarks);
}

Sketch 3. Drive DC Motor with Optical Rotary Encoder

//www.bchtechnologies
//2020.12.25
/************************
Control Motor withL293D chip
and Epson Optical Encoder
************************/ 
volatile int rotDirection;  // Rotation Direction 1, 2 or 0 (no direction)
volatile int numberOfMarks;
volatile int numberOfTurns;
#define MOTORENABLE 11
#define MOTORDIRA 10
#define MOTORDIRB 9
//Optical
#define OPT_A 2
#define OPT_B 3
void stinkyfish ()  {
  //delay(4);  // delay for Debouncing
      int iA=digitalRead(OPT_A);
      int iB=digitalRead(OPT_B);
      if (iA==iB)
        rotDirection= 1;
      else
        rotDirection= 2;
      numberOfMarks++;
  if (numberOfMarks>180)
  {
    numberOfMarks=0;
    numberOfTurns++;
  }
}
void setup() {
  //---set pin direction
  pinMode(MOTORENABLE,OUTPUT);
  pinMode(MOTORDIRA,OUTPUT);
  pinMode(MOTORDIRB,OUTPUT);
  //-- Optical
  pinMode(OPT_A,INPUT);
  pinMode(OPT_B,INPUT);
  attachInterrupt(0,stinkyfish,CHANGE);
  Serial.begin(9600);
  Serial.println("Ready");
  //
  digitalWrite(MOTORDIRA,HIGH); 
  digitalWrite(MOTORDIRB,LOW);
}
void loop() {
  // TEST 1 Test for speed
  int ii=255;
  while (ii>125)
  {
  Serial.print("PWM Speed: "); //~
  Serial.println(ii);
  analogWrite(MOTORENABLE,ii); 
  ii-=10;
  delay(2000);
  Serial.print("number of turns:");
  Serial.println(numberOfTurns);
  }
  digitalWrite(MOTORENABLE,LOW); //all done
  Serial.println("Motor stopped");
  delay(10000);
  // TEST 2
  Serial.println("TEST PRECISION");
  for (int iX=1; iX<=10;iX++)
  {  Serial.print ("Testing Mark: ");
     Serial.println(iX*10);
    numberOfMarks=0;
    analogWrite(MOTORENABLE,LOW);
    while (numberOfMarks<iX*10)
      {analogWrite(MOTORENABLE,255); 
      }
    analogWrite(MOTORENABLE,LOW);
    Serial.println(numberOfMarks);
    delay(3000);
  }
}