Interrupt and Serial communication

Hi,

I am trying to read the encoder of a motor (Pololu - 75:1 Metal Gearmotor 25Dx66L mm LP 6V with 48 CPR Encoder (No End Cap))
I don't have any problems on reading it with interrupts, however when I use Serial communication to print the encoder position on the Serial monitor. The code just stops working. Is there any problem on using interrupts with Serial communication?

Here is the working code:

#define EncoderA 2
#define EncoderB 3
#define LED1 13
#define LED2 11
boolean A_set;
boolean B_set;

unsigned long time;
int encpos=0;
int interval = 100;
byte prevA=0;
byte prevB=0;
byte EncA=0;
byte EncB=0;
long previous=0;
void setup(){
pinMode(EncoderA,INPUT);
pinMode(EncoderB,INPUT);
pinMode(LED1,OUTPUT);
pinMode(LED2,OUTPUT);
attachInterrupt(0,doencA,CHANGE);
attachInterrupt(1,doencB,CHANGE);
}

void loop(){
time =millis();

if (abs(encpos)==900){
if(encpos>0){
{digitalWrite(LED1,HIGH);
previous=time;
encpos=0;
}
}
else if(encpos<0)
{digitalWrite(LED2,HIGH);
previous=time;
encpos=0;
}
}
if(time-previous>interval)
{digitalWrite(LED2,LOW);
digitalWrite(LED1,LOW);
}
}

void doencA()
{
if (digitalRead(EncoderA) == HIGH) {
A_set = true;
if (!B_set) {
encpos += 1;
}
}
if (digitalRead(EncoderA) == LOW) {
A_set = false;
}

}
void doencB()
{
// Low-to-high transition?
if (digitalRead(EncoderB) == HIGH) {
B_set = true;
if (!A_set) {
encpos -= 1;
}
}

// High-to-low transition?
if (digitalRead(EncoderB) == LOW) {
B_set = false;
}

}

and here is the one not working:

#define EncoderA 2
#define EncoderB 3
#define LED1 13
#define LED2 11
boolean A_set;
boolean B_set;

unsigned long time;
int encpos=0;
int interval = 100;
byte prevA=0;
byte prevB=0;
byte EncA=0;
byte EncB=0;
long previous=0;
void setup(){
pinMode(EncoderA,INPUT);
pinMode(EncoderB,INPUT);
pinMode(LED1,OUTPUT);
pinMode(LED2,OUTPUT);
attachInterrupt(0,doencA,CHANGE);
attachInterrupt(1,doencB,CHANGE);
Serial.begin(9600);
}

void loop(){
time =millis();

if (abs(encpos)==900){
if(encpos>0){
{digitalWrite(LED1,HIGH);
previous=time;
encpos=0;
}
}
else if(encpos<0)
{digitalWrite(LED2,HIGH);
previous=time;
encpos=0;
}
}
if(time-previous>interval)
{digitalWrite(LED2,LOW);
digitalWrite(LED1,LOW);
}
Serial.println(encpos);
}

void doencA()
{
if (digitalRead(EncoderA) == HIGH) {
A_set = true;
if (!B_set) {
encpos += 1;
}
}
if (digitalRead(EncoderA) == LOW) {
A_set = false;
}

}
void doencB()
{
// Low-to-high transition?
if (digitalRead(EncoderB) == HIGH) {
B_set = true;
if (!A_set) {
encpos -= 1;
}
}

// High-to-low transition?
if (digitalRead(EncoderB) == LOW) {
B_set = false;
}

}

Here is the working code

Explain what this code does that makes it "work" and then explain what you mean by "The code just stops working".

Pete

Two LED's are connected to arduino and the code reads the encoder of the motor and make the LED's blink according to the direction. They blink on every full rotation.

But when I try to print the encoder data to Serial monitor by using Serial.print the LED's dont blink and normally encoder value called "encpos" becomes zero after every turn but when I watch the value on serial monitor it doesnt become zero.

Hi,

You might be sending too much data to Serial in too short a time. To test this try -

if(time-previous>interval)
{digitalWrite(LED2,LOW);
digitalWrite(LED1,LOW);
}

if(time-previous>1000)
{
Serial.println(encpos);
}

Now you only print the data once a second, this will at least prove that your program logic is correct.

Also check that you are not using the serial pins for your program as well as for serial data, on my UNO I think serial uses the pins marked rx,tx which from memory are digital 0 and 1, I dont have the board to check.

DuaneB

I guess the problem is on the length of loop cycle. The value encpos gets higher than 900 before it enters to if-statement. I guess serial communication makes the cycle longer. Just a theory though.

My suggestion is in setup() right after Serial.begin(9600) insert a new line right below that that says Serial.println("Hello from setup") . This will tell us that setup is working and that the serial interface is working. If that all works you can start putting Serial.println statements into your code to see where the stop working.

Do it step by step. It's not a good idea to put a bunch of them in because side effects, what I think is happening, will kill you.

P.S.
Don't use hello from setup after you are out of setup. Make the statement meaningful to the location. I don't know if I needed to add that but you never can tell.

And you might want to change:
#define EncoderA 2
#define EncoderB 3
to
#define EncoderA 5
#define EncoderB 6
just for fun. I don't think it will make a difference but it's easy to do.

My suggestion is in setup() right after Serial.begin(9600) insert a new line right below that that says Serial.println("Hello from setup") . This will tell us that setup is working and that the serial interface is working. If that all works you can start putting Serial.println statements into your code to see where the stop working.

My suggestion is to quit using a stone-age speed. Bump the speed up to 115200. The data will take 1/12th the amount to time to be sent.