Pages: [1]   Go Down
Author Topic: Wheel encoder interrupts  (Read 2933 times)
0 Members and 1 Guest are viewing this topic.
NS Canada
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
       I am starting to put together my first robot (Boe Bot from Parallax) My microcontroller board is an Arduino Mega(ATmega1280)
I am having problems with the wheel encoders (Boe Bot digital encoder kit from Parallax). The encoder signal lines are connected to Arduino pins 2 & 3.
My problem is that I get interrupts much faster than the slots of the wheels pass the encoders. Also interrupts often continue to come in after the wheels have stopped.Here is my code:
Code:

#include <Servo.h>
Servo servoRight;
Servo servoLeft;
volatile int Rindex = 0;
volatile int Lindex = 0;

void setup()                                 
{
  attachInterrupt(0,rtEncoderInterrupt,RISING);
  attachInterrupt(1,ltEncoderInterrupt,RISING);
  Serial.begin(9600);
  servoRight.attach(12);
  servoLeft.attach(11);
  servoRight.writeMicroseconds(1700);
  servoLeft.writeMicroseconds(1300);
}
void loop()
{   
  // stop the servos after 16 interrupts from either  encoder
  if((Rindex == 16) || (Lindex == 16))
  {
    servoRight.writeMicroseconds(1500);
    servoLeft.writeMicroseconds(1500);
  }
  // hold execution here
   while((Rindex >= 16)||(Lindex >= 16)){}   
}

void rtEncoderInterrupt()
{
  Serial.println(Rindex);
  Rindex++;
}
void ltEncoderInterrupt()
{
  Serial.print("          ");
  Serial.println(Lindex);
  Lindex++;
}

From this code I expected  to see the Boe Bot wheels turn two reolutions (there are 8 slots in each wheel), and to see the following on the serial monitor:
1
       1
2
        2
3
etc.

Instead I saw the wheels turn 1/4 to 1/2 revolution at constant speed and this on the monitor:
1
2
3
       1
4
        2
        3
5
        6
etc.
 the pattern being random. After one of the columns reached 16 ,and the motors were stopped, interrupts continued to occor sporadically.
I have been working at this little sketch for two days and I am at my wits end. Can anyone make a suggestion?
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


dont do serial prints in an interrupt. They should be as short as possible
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

some patches to your code
Code:
#include <Servo.h>
Servo servoRight;
Servo servoLeft;
volatile int Rindex = 0;
volatile int Lindex = 0;

void setup()                                 
{
  attachInterrupt(0, rtEncoderInterrupt,RISING);
  attachInterrupt(1, ltEncoderInterrupt,RISING);

  Serial.begin(115200); // why not faster ???

  servoRight.attach(12);
  servoLeft.attach(11);
  servoRight.writeMicroseconds(1700);
  servoLeft.writeMicroseconds(1300);
}
void loop()
{   
  Serial.print(Rindex); 
  Serial.print("          ");
  Serial.println(Lindex);

  // stop the servos after 16 interrupts from either  encoder
  if((Rindex >= 16) || (Lindex >= 16))  // you may just miss ==
  {
    servoRight.writeMicroseconds(1500);
    servoLeft.writeMicroseconds(1500);
  }
  // hold execution here
   while((Rindex >= 16)||(Lindex >= 16)){}   
}

void rtEncoderInterrupt()
{
  Rindex++;
}
void ltEncoderInterrupt()
{
  Lindex++;
}
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

NS Canada
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Rob,
     Both good suggestions, but alas, they made no improvement.  My ISRs are as brief as I can make them ( Rindex++ ).  I have tried eliminating the Serial.prints altogether and just observed the rotation of the Boe Bot wheels and they rotated randomly 1/4 to 1/2 revolution, sometimes running on indefinitely until I pulled the power.
Glen
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

if the ints overflow fast it can have side effects

change

volatile int Rindex = 0;
volatile int Lindex = 0;

in
volatile unsigned long Rindex = 0;
volatile unsigned long Lindex = 0;

then it will takes far longer before overflow ...

do you have pull-down resistors on the irq lines?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

NS Canada
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The values of Rindex and Lindex don't get higher than about 25 in any of my trials, but I'll change to unsigned long anyway because in practice I'll need them.

The  signal line is pulled low by the encoder when it gets a reflection and allowed to float otherwise so I have put 10K pull-up resistors on the signal lines as per the manufacturers instructions.

I don't have a logic probe but I am going to turn one of the wheels over slowly by hand while monitoring the signal line with a voltmeter. That's my next activity. I'll report back.

This is the encoder data sheet
http://www.parallax.com/Portals/0/Downloads/docs/prod/robo/DigitalEncoderDoc.pdf
     

Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The  signal line is pulled low by the encoder when it gets a reflection and allowed to float otherwise so I have put 10K pull-up resistors on the signal lines as per the manufacturers instructions.
Sounds OK,

Can you post the (partial) output of the script?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

can you disconnect the servo's and try manually?
The servo's may send noise.

What are you using to power the servo's?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

NS Canada
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I disconnected the Boe Bot from USB and put it on battery power (5 AA cells regulated to 5V)
I connected the voltmeter to the encoder signal line and ground and turned the wheel manually, slowly.
The voltage alternated between 0.00V and 4.88V as it should.
I connected the voltmeter to the servo supply line and ground.   4.87V

I then connected the Boe Bot to USB and disconnected the batteries, and measured the voltages
The encoder signal line was 4.86V and the servo  supply line was 4.86V

I then opened the serial monitor ran the script in order to get output you asked for.
To my great surpise the output was normal! 
I repeated this a half dozen times without anything abnormal showing up.

That is good news and bad news.
Good in the sense that it is working.
Bad in the sense that I didn't learn why it didn't work initially.

My only guess is that there was a poor connection on the breadboard, where the pull-up resistors are, and that it was accidentally corrected when I was manipulating the wires while measuring the voltages. (The voltage on the encoder signal lines may have been bobbling up and down, creating multiple interrupts)

Lesson learned:  If the software does not work, do not become too focused on the details of the software, the problem may be in the hardware.

Thank you, Rob, for staying with me and pushing me toward the solution.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

you're welcome,

Quote
Lesson learned:  If the software does not work, do not become too focused on the details of the software, the problem may be in the hardware.
A very good lesson learned - and it works the other way around too -
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

field road, jupiter creek
Offline Offline
Sr. Member
****
Karma: 6
Posts: 354
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Why bother with the quadrature encoders?
Just look at one of the outputs from a wheel, you already know which direction it is turning from when you send your move commands.

I was trying this with my Rover 5 chassis and gave up, looking at the 2 outputs from each wheel on the CRO the pulses where pretty close together.
Thing was actually counting pulses per distance traveled, it was no more accurate looking at both outputs than just counting on a single output.

Thing is we are talking about measuring distance traveled, not which direction the wheels are rotating.
Logged

NS Canada
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello Cyberteque,
           My encoders are actually simple ones (not quadrature) and I am using them for two purpoes; to measure the distance travelled, and to make the robot travel in a straight line by synchronizing the drive servos.  Since I presented the problem here I have found two physical causes for my problems and have corrected them.: (1)  I sometimes powered the robot by USB alone and the voltage sagged to 3.7v. Now I make sure that the batteries are plugged in at all times. (2) One of the pull-up resistors was making intermittent connection in the breadboard. This allowed the encoders signal to float rather than going high. I repaired the circuit. Now all is going swimmingly until the next inexplicable hardware problem arises. : )   I am finding robot programming much more challenging than the usual programming in which you are dealing with well-behaved abstractions . Thank you for your input.
Logged

field road, jupiter creek
Offline Offline
Sr. Member
****
Karma: 6
Posts: 354
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm thinking we all need to replace our breadboards or flush them with IPA every now and then!

Been chasing a weird problem that ended up being caused by intermittent contact with a damn pullup!!
Logged

Pages: [1]   Go Up
Jump to: