Go Down

Topic: One motor faster than the other?? (Read 5351 times) previous topic - next topic

Wasd9595

Hi guys

Im trying hard to make my first robot. It should be wireless remote controlled using two Arduinos, some switches and RF links. At this point the communication and everything is fine. But as I set the motor to go forward with the same speed, one motor spins faster than the other one? I am using Arduino UNO with the official motor shield R3. The Arduino is powered with a 9v battery. The shield is powered by its own 9v battery. Im using two standard DC motors which are attached to the chassis using Tamiya Twin Gear motor box.

Can anyone tell me why one motor spins faster than the other? And maybe how to solve it?

Here is the code:

Transmitter:

Code: [Select]
#include <VirtualWire.h>

const char *forward = "f";
const char *backward = "b";
const char *right = "r";
const char *left = "l";
const char *zero = "0";


const int rightButton = 2;
const int forwardButton = 3;
const int backwardButton = 4;
const int leftButton = 5;

void setup()
{
  Serial.begin(9600);  
  Serial.println("setup");

  //Button pin setup
  pinMode(rightButton, INPUT);
  pinMode(forwardButton, INPUT);
  pinMode(backwardButton, INPUT);
  pinMode(leftButton, INPUT);

  // Tranmitter setup
  vw_setup(4000);
  vw_set_tx_pin(7);
}

void loop()
{

  if (digitalRead(leftButton) == HIGH){
    digitalWrite(13, HIGH);
    vw_send((byte *)left, strlen(left));
    vw_wait_tx();
    delay(200);
  }
  else if (digitalRead(backwardButton) == HIGH) {
    digitalWrite(13, HIGH);
    vw_send((byte *)backward, strlen(backward));
    vw_wait_tx();
    delay(200);
  }
  else if (digitalRead(forwardButton) == HIGH){
    digitalWrite(13, HIGH);
    vw_send((byte *)forward, strlen(forward));
    vw_wait_tx();
    delay(200);
  }
  else if (digitalRead(rightButton) == HIGH){
    digitalWrite(13, HIGH);
    vw_send((byte *)right, strlen(right));
    vw_wait_tx();
    delay(200);
  }
  else{
    digitalWrite(13, LOW);
    vw_send((byte *)zero, strlen(zero));
    vw_wait_tx();
  }
}


Receiver: (The code that controls the motors)
Code: [Select]
#include <VirtualWire.h>
// Højre motor
int hRetning = 13;
int hHastighed = 11;
int hBremse = 8;

//Venstre motor
int vRetning = 12
int vHastighed = 3;
int vBremse = 9;

void setup()
{
  Serial.begin(9600);
  Serial.println("Setup");

  //Højre motor
  pinMode(hRetning, OUTPUT);
  pinMode(hBremse, OUTPUT);

  //Venstre motor
  pinMode(vRetning, OUTPUT);
  pinMode(vBremse, OUTPUT);

  //Modtager modulet
  vw_set_rx_pin(7);
  vw_setup(4000);
  vw_rx_start();       
}

void loop()
{
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  int i;
  char c = (buf[i]);


  if (vw_get_message(buf, &buflen))
  {
    for (i = 0; i < buflen; i++)
    {
      Serial.print(c);
      Serial.print("");

    }
    Serial.println("");
  }


  if (c == 'f'){
    //Højre motor forward
    digitalWrite(hRetning, HIGH);
    digitalWrite(hBremse, LOW);
    analogWrite(hHastighed, 100);

    //Venstre motor forward
    digitalWrite(vRetning, HIGH);
    digitalWrite(vBremse, LOW);
    analogWrite(vHastighed, 100);
  }
  else {
    STOP ();
  }
  if (c == 'b'){
    //Højre motor forward
    digitalWrite(hRetning, LOW);
    digitalWrite(hBremse, LOW);
    analogWrite(hHastighed, 100);

    //Venstre motor forward
    digitalWrite(vRetning, LOW);
    digitalWrite(vBremse, LOW);
    analogWrite(vHastighed, 100);
  }
  else {
    STOP ();
  }
  if (c == 'r'){
    //Højre motor forward
    digitalWrite(hRetning, HIGH);
    digitalWrite(hBremse, LOW);
    analogWrite(hHastighed, 20);

    //Venstre motor forward
    digitalWrite(vRetning, HIGH);
    digitalWrite(vBremse, LOW);
    analogWrite(vHastighed, 120);
  }
  else {
    STOP ();
  }
  if (c == 'l'){
    //Højre motor forward
    digitalWrite(hRetning, HIGH);
    digitalWrite(hBremse, LOW);
    analogWrite(hHastighed, 120);

    //Venstre motor forward
    digitalWrite(vRetning, HIGH);
    digitalWrite(vBremse, LOW);
    analogWrite(vHastighed, 20);

  }
  else {
    STOP ();
  }
  if (c == '0'){
    STOP ();
  }
}

int STOP (){
  digitalWrite(hBremse, HIGH);
  digitalWrite(vBremse, HIGH);
}

johnwasser


Can anyone tell me why one motor spins faster than the other? And maybe how to solve it?


Welcome to the real world.  No two motors are ever identical.  You will have to add code to send slightly different PWM values to the two motors to get then to run at (very nearly) the same speed.
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

steinie44

You have to modify analogWrite(hHastighed, 100); and analogWrite(vHastighed, 100); values.
The 100 is the speed, try something like 100 and 110 or 110 and 100.
You will have to play with the values.
Later, If you want to add a pot or 2, then you can sync them in setup.

Wasd9595

Thanks for reply - so this is completely normal? Two motors will never drive with the same speed? I will have to adjust the speed in the code until I think the motors drive with the same speed?

johnwasser


Thanks for reply - so this is completely normal? Two motors will never drive with the same speed? I will have to adjust the speed in the code until I think the motors drive with the same speed?


Yes.  The Arduino robot platform makes it easy by using a trimpot connected to an analog input pin to set the offset value.  The trim can be set +/- 30% as shown in the library code below:

Code: [Select]

void RobotMotorBoard::motorsWrite(int speedL, int speedR){
/*Serial.print(speedL);
Serial.print(" ");
Serial.println(speedR);*/
//motor adjustment, using percentage
_refreshMotorAdjustment();

if(motorAdjustment<0){
speedR*=(1+motorAdjustment);
}else{
speedL*=(1-motorAdjustment);
}

if(speedL>0){
analogWrite(IN_A1,speedL);
analogWrite(IN_A2,0);
}else{
analogWrite(IN_A1,0);
analogWrite(IN_A2,-speedL);
}

if(speedR>0){
analogWrite(IN_B1,speedR);
analogWrite(IN_B2,0);
}else{
analogWrite(IN_B1,0);
analogWrite(IN_B2,-speedR);
}
}

void RobotMotorBoard::_refreshMotorAdjustment(){
motorAdjustment=map(analogRead(TRIM),0,1023,-30,30)/100.0;
}
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

oric_dan

Not only is there always a slight difference between any 2 motors of the same type, but even more important to robotics is that the 2 motor-geartrains will normally be running in 'opposite' directions, due to mirror-symmetry mounting, so the differences will be even greater than when they are running in the same direction.

You can get some relief via calibration, but if you need close operation, it's best to use wheel encoders. 

abeltomillo

I don't want to start another thread, but I read this one and I still having the same issue: one motor is faster than the other. In the way that after 1 meter running straight away, the bot starts to loop turning into left.

I guess that one motor is more rpm than the other, because I've measured the motorA and motorB outputs with voltimeter and amperimeter and finally the resistance of the motors.

Motor Top Left is 4.3 Ohm = R
Motor Top Right is 4.6 Ohm = R

The motorA Vout with the value 60 in analogWrite is about 5.02 volts
MotorB Vout with same analog value written is about 5.7 volts

So I deduce the Power of any motor was different, so I decied to variate in `x`the analog values.

By measuing the same voltage it's not working, when the bot is on the floor it spins left.
So I started to try and recode, try and recode and finally I got it to go about 1 meter straight away but I don't know why it starts to spin left.

This is the code

And Im using L298N pcb with ENA, and ENB connected to PWM. Using 5V supply from regulator directly to vin of arduino. I power the pcb on VMS and Gnd with a lipo 1.3Ah of 3 cells, about 14.6V. So I can not write very high analog values because motors are 6V max.

Is the L298N broken maybe?

Rupert909

Perhaps you should consider using completely rotating servos, or stepper motors? Alternatively optical reading of motor or wheel speeds and adjust accordingly.

Even if you managed to calibrate two motors to perform almost identically on hard floor, they need not work that way on other surfaces, such as carpets.

Another solution is to use a single motor and differential between two wheels, and leave control of direction to a steering wheel, controlled by a servo.

The internet is a great thing. Use it.
:s/internet/mind/g
Real Programmers use ++C

Go Up