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

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.
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!
firedancer
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!

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!
Hector
Thanks for reporting back with your findings! definitely appreciated, and I'm sure many others will find your post useful!

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.
arobose
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.

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.
arobose
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.

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.
arobose
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.

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
arobose
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

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.
Hector
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.

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
arobose
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
