Robot turns on itself after 1 m because one motor is faster

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 xthe 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?

void loop() {
  // put your main code here, to run repeatedly:
  // Move the servo from left to right and from right to left
  ultrasonic.DistanceMeasure2(4, 11);// get the current signal time
  int cm1 = ultrasonic.microsecondsToCentimeters();//convert the time to centimeters
  Serial.print("cm1: "); Serial.println(cm1);
  ultrasonic.DistanceMeasure();// get the current signal time;
  int cm2 = ultrasonic.microsecondsToCentimeters();//convert the time to centimeters
  Serial.print("cm2: "); Serial.println(cm2);
  if (cm1 <= 30 || cm2 <= 30) {
    Serial.println("Turning left");
    //stopMotors();
    turnLeft(65);
  } else {
    setMotorsSense(forward);
    setMotorSpeed(40, top_left);
    setMotorSpeed(45, top_right);
  }
}

I created my own library for L298N and it’s very complicated to understand because I pretend to do it generically and still looping hardly to understand. But here are the method I declared for this case, which is the testing code.

void setMotorSense(MotorSense sense, MotorLocation location) {
  if (sense == forward) {
    motors[location].IN1.value = HIGH;
    motors[location].IN2.value = LOW;
  } else if (sense == backward) {
    motors[location].IN1.value = LOW;
    motors[location].IN2.value = HIGH;
  } else if (sense == deadpoint) {
    motors[location].IN1.value = LOW;
    motors[location].IN2.value = LOW;
  }
  digitalWrite(motors[location].IN1.pin, motors[location].IN1.value);
  digitalWrite(motors[location].IN2.pin, motors[location].IN2.value);
}

void setMotorsSense(MotorSense sense) {
  setMotorSense(sense, top_left);
  setMotorSense(sense, top_right);
}

void setMotorSpeed(int _speed, MotorLocation location) {
  motors[location].EN.value = _speed;
  analogWrite(motors[location].EN.pin, _speed);
}

void turnLeft(int _speed) {
  setMotorSense(backward, top_left);
  setMotorSense(forward, top_right);
  setMotorsSpeed(_speed);  
}

void setMotorsSpeed(int _speed) {
  setMotorSpeed(_speed, top_left);
  setMotorSpeed(_speed, top_right);
}

Thanks in advance.

I think it will be almost impossible to get a robot to move straight only by controlling the wheel speeds. It needs an external reference, such as a compass, that can tell it when it is going off course and allow a correction to be made.

...R

One thing you could possibly try is to tinker with motor offset voltage. This means adding a constant level (or equivalent level) of DC voltage to the slower motor. Hopefully it evens up the speed of the two motors. This can be done in the software.

Not perfect... but better than nothing.

You need to measure each motors rotational speed, not its volts or amps. To get a dual motor arrangement to run straight it obviously requires both motors to run at the same speed, hence the requirement to measure rotational rate and then alter the drive signals to compensate.

One motor's rotational speed is the reference, used to determine forward velocity and the other is then adjusted about this reference speed to determine direction

Wheel encoders and a feedback loop is how this is normally done. You can't get away with
your current open-loop approach, any more than you can get away with shutting your eyes
when driving.

MarkT:
Wheel encoders and a feedback loop is how this is normally done.

Wheel encoders etc should enable you to run the two wheels at the same speed. But I don't think that will be sufficient to get the robot to move in a straight line. There is likely to be some slippage between the wheels and the ground.

That is why I suggested the need for a compass or similar external reference

If you have an external reference I doubt if you would need the wheel encoders.

...R

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

Motors are not linear resistive devices so you cannot use Mr Ohm's standard equations to describe their parameters.

Variation in friction with small motors is not something you can compensate for
without measuring the response. If you get a 5% discrepancy that's not suprizing.
Also many brushed DC-motors have a prefered direction of rotation, the brush timing is
advanced for more efficient full speed operation, so some form of adjustment is needed,
and feedback is required to prevent longer term drift.