ArduinoGeneral

Romeo All-in-One v1.1 + 2WD Mobile Platform + wheel encoders

userHead arobose 2012-07-14 07:43:58 9581 Views9 Replies
Hello All,

I'm encountering a problem with the encoder reading on the following configuration: Romeo All-in-One v1.1 + 2WD Mobile Platform + wheel encoders.

I've used the sample provided in the wiki page of the Romeo motor controller and the encoders one gathered.
When I turn the wheel manually , the encoders increase their value correctly. 20 pulses/revolution for each wheel. But when I use the motor with the simple advance function advance(255,255), for each revolution, one of the encoder shows 50 pulses and the others 130 pulses.... So,they are not equals and do not correspond to the value obtained manually...
I also tried to test with only one motor: advance(255,0) for example and the encoder of the motor stopped still moving.
I have changed the motors and the enoders and I have the same problem. I think there is a problem with the interrupts and perhaps on the timer.

Could Anyone of you help me please ?

Thanks a lot,

Arobose.
2013-07-13 07:58:42 [quote="arobose"]
Hi all,

I finally find the issue and solve the problem. As I supposed it can occure to other people, and I'm really surprised nobody experimente and communicate on this before, here... Moreover, this problem can occur for any digital or analog input, not only on the encoders. Anyway, here is the solution.

First, the issue came from the motors. The motors radiate noises in the circuitry and outside the circuitry(electromagnetism). So to avoid that, three mandatory points:

1- As I told in previous post, it's mandatory to activate the pull-up resistors on the input pins.
So add the following code in your setup() function:
[code]pinMode(2, INPUT);
digitalWrite(2, HIGH);      // turn on pullup resistor
pinMode(3, INPUT);
digitalWrite(3, HIGH);      // turn on pullup resistor
[/code]

2- As recommended in the wiki page of the motor controllers and Romeo, separate the power supply of the Arduino board and shields and sensors with the motors. The Romeo and Shields are designed for this and you should take the advantage of this well design.

3- You have to decrease the interference caused by the motors.
To do so, you have to solder 3 capacitors on each motors. Be careful, the capacitors mustn' be polarized, the perturbation can be positive or negative... So choose mylar or ceramic or polypropylene but above all forget electrolytic..
For the motors proposed on the Turtle and Pirate platform, I give you the values.
a- Solder a 470 nF capacitor between the two pins of each motor
b/c- Solder a 47 nF between each pin and the metal part of the motor body.

Hope this helps.

Arobose.
[/quote]

Thanks dude! This post was really helpful!

I would like to add, for any other users, that I succeeded with using ceramic capacitors with 0.10 uF (100 nF) between the two pins, and 0.047 uF (47 nF) between each pin and the motor metal body.

So the difference is that I used a 100 nF instead of 470 nF capacitor between the pins. The reason was that I didn't have any capacitors with any higher value :-)

Thanks again Arobose!
userHeadPic firedancer
2012-07-19 00:17:28 Arobose,


Thanks for reporting back with your findings! definitely appreciated, and I'm sure many others will find your post useful!
userHeadPic Hector
2012-07-18 23:42:48 Hi all,

I finally find the issue and solve the problem. As I supposed it can occure to other people, and I'm really surprised nobody experimente and communicate on this before, here... Moreover, this problem can occur for any digital or analog input, not only on the encoders. Anyway, here is the solution.

First, the issue came from the motors. The motors radiate noises in the circuitry and outside the circuitry(electromagnetism). So to avoid that, three mandatory points:

1- As I told in previous post, it's mandatory to activate the pull-up resistors on the input pins.
So add the following code in your setup() function:
[code]pinMode(2, INPUT);
digitalWrite(2, HIGH);      // turn on pullup resistor
pinMode(3, INPUT);
digitalWrite(3, HIGH);      // turn on pullup resistor
[/code]

2- As recommended in the wiki page of the motor controllers and Romeo, separate the power supply of the Arduino board and shields and sensors with the motors. The Romeo and Shields are designed for this and you should take the advantage of this well design.

3- You have to decrease the interference caused by the motors.
To do so, you have to solder 3 capacitors on each motors. Be careful, the capacitors mustn' be polarized, the perturbation can be positive or negative... So choose mylar or ceramic or polypropylene but above all forget electrolytic..
For the motors proposed on the Turtle and Pirate platform, I give you the values.
a- Solder a 470 nF capacitor between the two pins of each motor
b/c- Solder a 47 nF between each pin and the metal part of the motor body.


Hope this helps.


Arobose.
userHeadPic arobose
2012-07-17 13:08:13 Well well!

I've tested with one motor moving with its encoder unplugged and the other motor stopped but with its encoder plugged on the Romeo. And the plugged encoder but with the motor stopped increased....WTF!!!  ???

So I unscrewed the encoder and moved it around the robot and what a surprise... The encoder increasing in positions closed the other encoder wheel is moving... The sensor of the encoder is it too sensitive ?  :o

But I thought about the EMC.. And had the idea to protect the cable puting all of it in my closed hand and the encoder did not increase anymore... So it's probably electromagnetism the responsible of the problem...

Perhaps a ferrite on the encoder cables can solve the problem.


Arobose.
userHeadPic arobose
2012-07-17 10:59:18 Dear Hector,

I've found one thing is wrong.
The pull-up resistors of encoder input pins (pin2 and pin3) should be turned on.

The encoder doesn't influence anymore the other if I add in the setup functions:

[code] 
pinMode(2, INPUT);
digitalWrite(2, HIGH);      // turn on pullup resistor
pinMode(3, INPUT);
digitalWrite(3, HIGH);      // turn on pullup resistor
[/code]

I think  it would be great if you modify the example proposed for the encoder tests adding this in the setup() function.

But it doesn't solve yet the problem of the too much pulses. I continue to work on.

Thanks all for help

Regards,

Arobose.
userHeadPic arobose
2012-07-17 09:55:15 Hi Hector,

Thanks a lot for your reply.

First sorry for my sentence: [quote]I also tried to test with only one motor: advance(255,0) for example and the
encoder of the motor stopped still moving.[/quote]
I tried to say: I also tried to test with only one motor: advance(255,0) for example and the encoder of the stopped motor still moving.

Then, considering your points:
1.
[quote] You forgot to clear the buffer:
coder = 0;                //clear the data buffer
coder = 0;[/quote]

In fact, I want to calculate the travelled distance, is the reason why I didn't reset them.

2. Ok, I will try with the Array and let you know.

Thanks a lot for your help.

Kind regards,

Arobose
userHeadPic arobose
2012-07-17 00:15:46
Hi Arobose,


I did not understand one of your statements:
[quote]I also tried to test with only one motor: advance(255,0) for example and the encoder of the motor stopped still moving.[/quote]

Could you clarify?
Have you tried to manually move both wheels and compare? have you checked your wiring to make sure there are no loose wires?


Ok, I found something that might be a bit of a problem:

1. You forgot to clear the buffer:
coder = 0;                //clear the data buffer
coder = 0;

2. you are printing the values of both encoders separately. This allows for more interrupts to go through before it reports back the value of the second encoder.

you should store the values of both encoders in an Array. such as "speed" which is not being used in your sketch even though it is declared. The values should be stored immediately one after the other. So to not allow the encoders to cause more interrupts between data storage...

You might end up with some difference between encoder values, but definitely should not be so large of a difference as what you are experiencing now.
userHeadPic Hector
2012-07-15 01:28:49 Hi VennaMike,

Thanks a lot for your answer.

Here is my code

[code]#define LEFT 0
#define RIGHT 1

long Encoder[2] = {
  0,0};
int Speed[2] = {
  0,0};

//Input value
char val = 0;
char prev_val = 0;

//Standard PWM DC control
int E1 = 5;    //M1 Speed Control
int E2 = 6;    //M2 Speed Control
int M1 = 4;    //M1 Direction Control
int M2 = 7;    //M1 Direction Control

void setup(){
 
  int i;
  for(i=4;i<=7;i++)
    pinMode(i, OUTPUT);
  Serial.begin(19600);                            //init the Serial port to print the data
  Serial.println("Run keyboard control");
  attachInterrupt(LEFT, SpeedRightWheel, CHANGE);    //init the interrupt mode for the digital pin 2
  attachInterrupt(RIGHT, SpeedLeftWheel, CHANGE);  //init the interrupt mode for the digital pin 3
  //initialize the variables we're linked to
}
void loop(){
 
  static unsigned long timer = 0;                //print manager timer
 
  if(Serial.available())
  {
    prev_val = val;
    val = Serial.read();
    if (val == -1)
      val = prev_val;
   
    switch(val)
    {
    case 'w'://Move Forward
      advance (100,100);  //move forward in max speed
      break;
    case 's'://Move Backward
      back_off (255,255);  //move back in max speed
      break;
    case 'l'://Turn Left
      turn_L (100,100);
      break;     
    case 'r'://Turn Right
      turn_R (100,100);
      break;
    case 'z':
      Serial.println("Hello");
      break;
    case 'x':
      stop();
      break;
  }
  }
  if(millis() - timer > 100){                 
    Serial.print("Encoder");
    Serial.print(Encoder[LEFT]);
    Serial.print("[Left Wheel] ");
    Serial.print(Encoder[RIGHT]);
    Serial.println("[Right Wheel]");
    timer = millis();
  }
 
}

void stop(void)                    //Stop
{
  Serial.print("Stop");
  digitalWrite(E1,LOW); 
  digitalWrite(E2,LOW);   
}

void advance(char a,char b)          //Move forward
{
  Serial.print("Forward");
  analogWrite (E1,a);      //PWM Speed Control
  digitalWrite(M1,HIGH); 
  analogWrite (E2,b); 
  digitalWrite(M2,HIGH);
}

void back_off (char a,char b)          //Move backward
{
  Serial.print("Backward");
  analogWrite (E1,a);
  digitalWrite(M1,LOW); 
  analogWrite (E2,b); 
  digitalWrite(M2,LOW);
}

void turn_R (char a,char b)            //Turn Right
{
  Serial.print("turn right");
  analogWrite (E1,a);
  digitalWrite(M1,LOW); 
  analogWrite (E2,b); 
  digitalWrite(M2,HIGH);
}

void turn_L (char a,char b)            //Turn Left
{
  Serial.print("turn left");
  analogWrite (E1,a);
  digitalWrite(M1,HIGH); 
  analogWrite (E2,b); 
  digitalWrite(M2,LOW);
}

void SpeedLeftWheel()
{
  Encoder[LEFT]++;
}


void SpeedRightWheel()
{
  Encoder[RIGHT]++;
}[/code]


Thanks a lot for any help you can provide me.

Arobose
userHeadPic arobose
2012-07-14 14:13:19 In order to help, we need to see your code.  Can you post it? userHeadPic ViennaMike