motor rotation through incermental encoder

Hello all,

I am trying to program a uno board. Input is through a rotary (incremental) encoder(interrupt driven), output is to be visualized through motor rotation, like if the encoder is turned left, motor should rotate left(for 1 second) and vice versa. But I find that the motor is rotating only in one direction. I observed in the serial monitor as how input is got, to my surprise , input is read correctly by the serial monitor, but motor is rotating only in one direction. I am new to arduino. Please render help if possible. Thanks in advance! code is below.

//I am using L293D and DC motor

#include <rotary.h> // for library refer Buxtronix: Rotary encoders, done properly

#define E1 10 // Enable Pin for motor 1
#define I1 8 // Control pin 1 for motor 1
#define I2 9 // Control pin 2 for motor 1

Rotary r = Rotary(2, 3);
int result=0;
void setup() {
pinMode(I1, OUTPUT);
pinMode(I2, OUTPUT);
Serial.begin(9600);
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
Serial.begin(9600);
}

void loop() {

int i=0;
}

ISR(PCINT2_vect) {
result = r.process();
if (result) {
Serial.println(result == DIR_CW ? +1 : -1); //+1-right -1-left
if(result=1){
Serial.println(“right”);
digitalWrite(E1, 255);
digitalWrite(I1, HIGH);
digitalWrite(I2, LOW);
delay(1000);
digitalWrite(E1, LOW);
}
if(result=(-1))
{
Serial.println(“left”);
digitalWrite(E1, 255);
digitalWrite(I1, LOW);
digitalWrite(I2, HIGH);
delay(1000);
digitalWrite(E1, LOW);
}
}
}

I suspect typical C beginner error in your code: if(result=1) does not compare, but changes result to 1. Recommended workaround: if (1==result) //constant is first operand will give an compiler error if you ever write = instead of ==.

Also testing result twice is error prone. Consider what will happen when result is neither +1 nor -1? You may use if (cond1) ... else if (cond2) ..., and end up with another else that alerts on unexpected values. Or use switch(). If you are sure that only two values are possible, an if()...else... is sufficient.

Dear DrDiettrich,

Thanks for the reply.The code actually worked except for one thing. The delay value. I gave delay(1000) inside the if structure, but motor rotation didn’t last for a second. I tried increasing the delay value, and finally at delay(17000) the motor rotated for a while(less than 2 seconds). Is there any specific reason for such a happening?
Modified code:

#include <rotary.h>

#define E1 10 // Enable Pin for motor 1
#define I1 8 // Control pin 1 for motor 1
#define I2 9 // Control pin 2 for motor 1
int rslt=0;
Rotary r = Rotary(2, 3);

void setup() {
pinMode(I1, OUTPUT);
pinMode(I2, OUTPUT);
Serial.begin(9600);
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
Serial.begin(9600);
}

void loop() {

int i=0;
}

ISR(PCINT2_vect) {
unsigned char result;
result = r.process();
if (result) {
Serial.println(rslt=result == DIR_CW ? +1 : -1); //+1-right -1-left
if(rslt==1){
Serial.println(“right”);
digitalWrite(E1, 255);
digitalWrite(I1, HIGH);
digitalWrite(I2, LOW);
delay(17000);
digitalWrite(I1, LOW);
digitalWrite(E1, LOW);

}
if(rslt==(-1))
{
Serial.println(“left”);
digitalWrite(E1, 255);
digitalWrite(I1, LOW);
digitalWrite(I2, HIGH);
delay(17000);
digitalWrite(I2, LOW);
digitalWrite(E1, LOW);
}
else
if(rslt!=(-1)||result!=(1)){0;}
}
}

You should organize your code very differently. Take almost all of it out of the ISR and just use the ISR to detect a pulse from the encoder - such as

ISR(PCINT2_vect) { result = r.process(); }

And in the rest of your program do all the other stuff.

Specifically, you cannot / should not use delay() within an ISR. You should aim for your ISR to complete in a number of microseconds.

...R

Dear Robin2,

Thanks for the reply. I will try coding the way you suggested.