Hello everyone !
I am new here, glad to found this place !
It's been 4 days i am trying to use an optical wheel encoder (incremential i think), with a DCmotor, both took apart from my useless Canon Pixma Printer. My encoder has a red Led and photoresistor. What i am trying to do is to read the encoder datas in order to drive the motor like a stepper one, knowing its speed, position and direction.
I found out the pinout of my encoder by testing its pins with a multimeter in diode mode like explains here : https://reprap.org/wiki/Optical_encoders_01
My encoder pinouts is: A=Led - , B=Led+, C=gnd , D=output 1 , E=+5V , F=output 2. Where the Output 1 is attached to Led- pin (same wire), and Led+ attached to +5V pin (same wire too), so i have 4 wires; 5V(+), Gnd, Output1, Output2.
I am using an arduino Uno with a L293D driver for the motor.
I have tested a dozen different wiring and codes from several forums, but each time the encoder return nothing or zero. Below, some wiring&code that i've tried out.
1/ DC motor + Driver L293D + OpticalEncoder + arduinoUno + 9V powerSupply(for the motor)
wiring (https://andrewjkramer.net/motor-encoders-arduino/):
Mine is a bit different cause i am not using the same driver, and my encoder has 4 pins.
code:
Results: The motor behaviour is good according to the code, but the encoder returns only 0 0 0... I tried it without the DCMotor, turning the wheel by hand, but the results are the same...
2/ Simple code and wiring to test only the encoder. OpticalEncoder + arduinoUno +wires.
Wiring:
A(+5V) pin ─> 5V on board
B(Gnd) pin ─> Gnd on board
C(Output1) pin ─> D2 on board (i read somwhere that is interrupt pins)
D(Output2) pin ─> D3 on board (i also tried C pin on D3 and D pin on D2)
Code: (found here: https://forum.arduino.cc/index.php?topic=537859.0)
Result: Sometimes 0 0 0, sometimes nothing in the serial monitor
3/ with the same components and same wiring
code:
Results: only 0 0 0
more photos:
I hope some of you could help me figure out what's my mistake(s)
Should i make hardware interrupts to set the home of my encoder, how to do so ?
Thanks for reading all this guys !
;:—)}
I am new here, glad to found this place !
It's been 4 days i am trying to use an optical wheel encoder (incremential i think), with a DCmotor, both took apart from my useless Canon Pixma Printer. My encoder has a red Led and photoresistor. What i am trying to do is to read the encoder datas in order to drive the motor like a stepper one, knowing its speed, position and direction.
I found out the pinout of my encoder by testing its pins with a multimeter in diode mode like explains here : https://reprap.org/wiki/Optical_encoders_01
My encoder pinouts is: A=Led - , B=Led+, C=gnd , D=output 1 , E=+5V , F=output 2. Where the Output 1 is attached to Led- pin (same wire), and Led+ attached to +5V pin (same wire too), so i have 4 wires; 5V(+), Gnd, Output1, Output2.
I am using an arduino Uno with a L293D driver for the motor.
I have tested a dozen different wiring and codes from several forums, but each time the encoder return nothing or zero. Below, some wiring&code that i've tried out.
1/ DC motor + Driver L293D + OpticalEncoder + arduinoUno + 9V powerSupply(for the motor)
wiring (https://andrewjkramer.net/motor-encoders-arduino/):
Mine is a bit different cause i am not using the same driver, and my encoder has 4 pins.
code:
C++:
// Motor connections
int enB = 5;
int in3 = 6;
int in4 = 4;
// Encoder Output connections
// from https://scidle.com/how-to-use-mouse-scroll-wheel-encoder-with-arduino/
byte AInput = 2;
byte BInput = 3;
byte lastState = 0;
byte steps = 0;
int cw = 0;
byte AState = 0;
byte BState = 0;
byte State = 0;
void setup() {
Serial.begin(9600);
// Set all the motor control pins to outputs
pinMode(enB, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
// Turn off motors - Initial state
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
// set the Encoders pins to Input
pinMode(AInput, INPUT_PULLUP); //tried with 'INPUT'
pinMode(BInput, INPUT_PULLUP); // tried with 'INPUT'
}
void loop() {
//directionControl();
//delay(1000);
//speedControl();
//delay(1000);
encoderRead();
delay (2000);
}
// this function is for encoder
void encoderRead(){
// read the input pin:
AState = digitalRead(AInput);
BState = digitalRead(BInput) << 1;
State = AState | BState;
if (lastState != State){
switch (State) {
case 0:
if (lastState == 2){
steps++;
cw = 1;
}
else if(lastState == 1){
steps--;
cw = -1;
}
break;
case 1:
if (lastState == 0){
steps++;
cw = 1;
}
else if(lastState == 3){
steps--;
cw = -1;
}
break;
case 2:
if (lastState == 3){
steps++;
cw = 1;
}
else if(lastState == 0){
steps--;
cw = -1;
}
break;
case 3:
if (lastState == 1){
steps++;
cw = 1;
}
else if(lastState == 2){
steps--;
cw = -1;
}
break;
}
}
lastState = State;
Serial.print(State);
Serial.print("\t");
Serial.print(cw);
Serial.print("\t");
Serial.println(steps);
delay(1);
}
// This function lets you control spinning direction of motors
void directionControl() {
// Set motors to maximum speed
// For PWM maximum possible values are 0 to 255
analogWrite(enB, 255);
// Turn on motor A & B
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
delay(2000);
// Now change motor directions
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
delay(2000);
// Turn off motors
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
}
// This function lets you control speed of the motors
void speedControl() {
// Turn on motors
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
// Accelerate from zero to maximum speed
for (int i = 0; i < 256; i++) {
analogWrite(enB, i);
delay(20);
}
// Decelerate from maximum speed to zero
for (int i = 255; i >= 0; --i) {
analogWrite(enB, i);
delay(20);
}
// Now turn off motors
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
}
2/ Simple code and wiring to test only the encoder. OpticalEncoder + arduinoUno +wires.
Wiring:
A(+5V) pin ─> 5V on board
B(Gnd) pin ─> Gnd on board
C(Output1) pin ─> D2 on board (i read somwhere that is interrupt pins)
D(Output2) pin ─> D3 on board (i also tried C pin on D3 and D pin on D2)
Code: (found here: https://forum.arduino.cc/index.php?topic=537859.0)
C++:
define encoderPinA 2
define encoderPinB 3
volatile int counter = 0;
volatile boolean flag;
void setup() {
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
Serial.begin (9600);
attachInterrupt(encoderPinA, isr_2, CHANGE);
}
void loop() {
if(flag == true){
Serial.println(counter);
flag = false;
}
}
//Interrupts
void isr(){
flag = true;
int channel_A = digitalRead(encoderPinA);
int channel_B = digitalRead(encoderPinB);
if(channel_A == HIGH && channel_B == HIGH){
counter++;
// Serial.println("BOTH HIGH = " + counter);
}
else{
counter--;
// Serial.println("ELSE counter = " + counter);
}
}
void isr_2(){
flag = true;
if(digitalRead(encoderPinA) == HIGH){
if(digitalRead(encoderPinB) == LOW){
counter = counter -1; //COUNTER CLOCK WISE
}
else{
counter = counter +1; //CW
}
}
else{
if(digitalRead(encoderPinB) == LOW){
counter = counter + 1; //CW
}
else{
counter = counter - 1 ; //CCW
}
}
}
Result: Sometimes 0 0 0, sometimes nothing in the serial monitor
3/ with the same components and same wiring
code:
C++:
//these pins can not be changed 2/3 are special pins
int encoderPin1 = 2;
int encoderPin2 = 3;
volatile int lastEncoded = 0;
volatile long encoderValue = 0;
long lastencoderValue = 0;
int lastMSB = 0;
int lastLSB = 0;
void setup() {
Serial.begin (9600);
pinMode(encoderPin1, INPUT);
pinMode(encoderPin2, INPUT);
digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
digitalWrite(encoderPin2, HIGH); //turn pullup resistor on
//call updateEncoder() when any high/low changed seen
//on interrupt 0 (pin 2), or interrupt 1 (pin 3)
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);
}
void loop(){
//Do stuff here
Serial.println(encoderValue);
delay(1000); //just here to slow down the output, and show it will work even during a delay
}
void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit
int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;
lastEncoded = encoded; //store this value for next time
}
more photos:
I hope some of you could help me figure out what's my mistake(s)
Should i make hardware interrupts to set the home of my encoder, how to do so ?
Thanks for reading all this guys !
;:—)}