Right wheels comes to stop ~75ms after left wheels in 4-wheel rover

Description of problem: When the program attempts to stop all four wheels (to stop the rover), the right wheels stop a split-second after the left wheels. There is a noticeable deceleration with the right wheels whereas the left wheels appear to stop almost instantly. If I were to guess, I would say that the right wheels come to a stop somewhere between 50-100 ms after the left wheels, as though both sides get the command to stop at the same time but the right wheels take longer to do so (longer deceleration curve). The left wheels stop at the same time as each other (almost instantly) and the right wheels stop at the same time as each other as well (albeit at a slower rate than the left wheels).

The issue this causes: When the rover is moving at full speed and then is commanded to come to a full stop, the direction the rover is facing once stopped is about 10 degrees to the left (or counter-clockwise rotation, if you prefer). The rover does drive in a fairly straight line, despite the fact that no calibrations have been made yet. But since the left wheels stop instantly and the right wheels keep moving a bit afterwards, the robot pivots on its left side and ends up facing slightly off its original path.

Things I've tried: I tried reversing the order in which I call digitalWrite() so that the right side is stopped first. Well, that's all I've done so far!

Possible workarounds: One idea is to use PWM to decelerate the rover more slowly rather than telling it to come to a sudden stop. PWM could also, of course, allow for calibrations specifically to the right wheels. I know in the real world this sorts of gizmos aren't made perfectly to spec and the physics involved are further complicated by unforseen/unaccounted for variables, but in this case I find it very interesting that the left wheels stop at the same time as each other just like the right wheels do. That fact coupled with how the motors are wired together (left side / right side) tells me there is either something wrong with the physical connections to the H-bridge or the H-bridge itself.

Hardware: * SainSmart mobile car chassis * SainSmart L298N Dual H Bridge DC Motor Driver * (3) Pololu 47:1 25Dx52L mm HP motor * (1) Pololu 47:1 25Dx52L mm HP motor with encoder * (4) Pololu 70x8 mm wheels (item 1428) * 7.4 V LiPo battery

Code snippet (simplified):

void motor_forward()
{
    digitalWrite(PIN_MOTOR_LEFT_1, LOW);
    digitalWrite(PIN_MOTOR_LEFT_2, HIGH);
    digitalWrite(PIN_MOTOR_RIGHT_1, LOW);
    digitalWrite(PIN_MOTOR_RIGHT_2, HIGH);
}

void motor_stop()
{
    digitalWrite(PIN_MOTOR_LEFT_1, HIGH);
    digitalWrite(PIN_MOTOR_LEFT_2, HIGH);
    digitalWrite(PIN_MOTOR_RIGHT_1, HIGH);
    digitalWrite(PIN_MOTOR_RIGHT_2, HIGH);
}

Hope that's enough info to stir curiosity! Or better yet, produce an answer! Thanks!

Answer snippet (simplified)

Post your code.

Motors don't behave the same clockwise vs anticlock.... motors on opposite sides rotate in opposite directions to give the same direction to the vehicle. That could explain why the two on each side behave the same as each other, but differently from their opposite numbers.

Cute. Here is a complete sketch that reproduces the issue.

#define PIN_MOTOR_RIGHT_1    6
#define PIN_MOTOR_RIGHT_2    7
#define PIN_MOTOR_LEFT_1      8
#define PIN_MOTOR_LEFT_2      9 

void motor_forward()
{
    digitalWrite(PIN_MOTOR_LEFT_1, LOW);
    digitalWrite(PIN_MOTOR_LEFT_2, HIGH);
    digitalWrite(PIN_MOTOR_RIGHT_1, LOW);
    digitalWrite(PIN_MOTOR_RIGHT_2, HIGH);
}

void motor_stop()
{
    digitalWrite(PIN_MOTOR_LEFT_1, HIGH);
    digitalWrite(PIN_MOTOR_LEFT_2, HIGH);
    digitalWrite(PIN_MOTOR_RIGHT_1, HIGH);
    digitalWrite(PIN_MOTOR_RIGHT_2, HIGH);
}

void loop(){}

void setup()
{
  pinMode(PIN_MOTOR_RIGHT_1, OUTPUT);
  pinMode(PIN_MOTOR_RIGHT_2, OUTPUT);
  pinMode(PIN_MOTOR_LEFT_1, OUTPUT);
  pinMode(PIN_MOTOR_LEFT_2, OUTPUT);
  
  motor_forward();
  delay(5000);
  motor_stop();
}

JimboZA: Motors don't behave the same clockwise vs anticlock.... motors on opposite sides rotate in opposite directions to give the same direction to the vehicle. That could explain why the two on each side behave the same as each other, but differently from their opposite numbers.

That may be it; excellent piece of information right there. The first time I connected the motors to the H-Bridge I was using an 18 gauge cable that was somewhat difficult to bend and organize inside the chassis. That time I also wired up the right side differently from the left side such that the function move_forward() posted previously would be written as:

void motor_forward()
{
    digitalWrite(PIN_MOTOR_LEFT_1, LOW);
    digitalWrite(PIN_MOTOR_LEFT_2, HIGH);
    digitalWrite(PIN_MOTOR_RIGHT_1, HIGH); // different polarity from left side
    digitalWrite(PIN_MOTOR_RIGHT_2, LOW);  // different polarity from left side
}

I didn't test the rover for an extended period of time with that configuration, but I did do some start/stop tests and I didn't notice the issue I described in the first post-- but to be clear, I wasn't specifically looking for it either.

I decided to change out the wiring to a smaller gauge cable (22 AWG) and I also used the opportunity to invert the polarity of the right side so that the code could be written as shown in the first post.

How you wire your H-bridge is wired may be important. Some H-bridges have braking functions. One of your H-bridges may be wired for braking while the other isn't. Check the data sheet for your H-bridge.

Brake is also sometimes called “shunt” - it simply shorts the motor through the bridge.

zoomkat:
How you wire your H-bridge is wired may be important. Some H-bridges have braking functions. One of your H-bridges may be wired for braking while the other isn’t. Check the data sheet for your H-bridge.

I can’t find the datasheet online, however it isn’t wired according to the instructions they provided (it was originally but then I upgraded the motors, which SainSmart’s instructions were written for, and ultimately ended up changing the wiring around as mentioned previously).

I’m going to revert the wiring change, however before I do, if your suspicion is correct, and if what Jimbo said is correct, then I should observe the same behavior when moving the rover in reverse, only the left side will be affected and I want to confirm that before rewiring.

Thanks for your excellent advice guys!

Its indeed true that some DC motors aren't completely symmetrical, since the commutation angle can be set to be optimal in the forwards direction (the armature current changes aren't instanteous, they lag in time slightly due to inductance of the coils), making it sub-optimal in the reverse direction.

However this only affects efficiency when running fast, not the stopping which will probably be mainly affected by mechanical friction differences. (Or different H-bridge settings as has been suggested). Ramping up and down drive levels is a good thing anyway as it reduces max currents and can control wheel-spin if that's an issue.

However most small motors are reasonably symmetric in behaviour, and many are designed to be symmetrical - the effect isn't huge.

can’t find the datasheet online,

Figure 6 in the below data sheet has some info.

Thanks again for all of your help everyone. Jimbo was right in that motors must work a bit differently with respect to forward movement and backward movement. Once I rewired the motors things began working as they should be.

However now the rover no longer drives straight. ...time to calibrate! I wish the wheels were produced better, because one can plainly see the imperfections when they rotate.

Thanks zoomkat for your help and link to the chip's datasheet.

robertanthony02:
Jimbo was right

It’s been known to happen 8)

Why use software to instruct right motors to rotate opposite direction to left. All you need to do is reverse the actual electrical connections on the motors themselves. Then when you instruct all motors to rotate 'forwards", the two motors reverse-wired rotate in the appropriate direction to produce a forwards motion.