Controlling speed of 2 motors using encoder

consider the black disks with slot mounted on the inboard motor shafts and an optical sensor that can count fractions of a motor turn

how would you use that information to control the motors so that they turn equal amounts at some reasonable speed

bear in mind that the motors may accelerate at different speeds so that just controlling the speed may not make the platform go straight

Use ratio (adjust for forward, left, right, reverse)
If a:b > 1, b += 2;
If b:a > 1, a += 2;
Else a++, b++;

Count the fractions of a turn of both motors using interrupts. Speed up or slow down one or other (or both) of the motors when the fractional rotations get out of step until they are back in step again. The proper way to do this is by using a PID

Note that whether the bot moves in a straight line also depends on the tyres being the same diameter and that no slippage occurs. You can allow for different diameters in the code but not for slippage

What type of motors?

assume 12V DC motors

assume same wheel type on both sides, can't do anything about slippage

how would you used PID? what are the inputs?

don't understand what this means. seems that a and b monotonically increase

OK, just generic motor. Not stepper or BLDC that need controller?

Using a PID you could use one of the wheels as the master. The inputs to the PID would be the outputs from the two encoders, the error would be the difference between them and the output would be the PWM signal to reduce the error

They do when a = b, but if a:b != 1, one or other is changed.

so the user controls the pwm to one motor. the encoder count from that motor is used as the PID target for the other and the PID output controls the pwm of the other motor.

that sounds like it would work

what are a & b? position, speed?

Either, because position and speed are scalar.

so the speed can never decrease?

Speed increases in the negative direction.

x + (-1)

Think of it as the phase difference between the two. If you keep track of countA and count B, then the simple difference between the two would need to be held constant to keep the positions/rotations/RPMs the same. You could use that difference as the input to a PID and get the bias/trim you need to apply to the PWMs. You could keep that difference with simple math by adding one with every RHS forward count and subtracting one with every LHS count.

If there is strange ratio that the two need to stay at, say you have a 47/53 smaller wheel on the RHS vs the LHS, you could do something bit Bresenham-like and add 53 for one and subtract 47 for the other and use the running sum to drive the PID.

In either case, you do turns by changing the slewing setpoint of the PID.

(and reverse is just subtracting)

1 Like

a:b (ratio, division) is another form of a-b (difference, subtraction).

1 Like

That would make the PID's target set point a constantly-increasing value (i.e. Distance Traveled). Perhaps you should make the set point be the difference in distance traveled between the two wheels? Thus, the PID would work to drive that value to zero.

Yes, that's the key behind the Bresenham algorithm: multiplication and division by successive addition and subtraction.

1 Like

Why ?

Depending on whether the error was positive or negative the correction value would be positive or negative

Correct, if you use the difference value. But, @gcjr's reply to use said:

I took that to mean actual counts (i.e. distance), not the difference between them. The counts be continually increasing while in motion.

Since the phase difference between the encoders gives you the bias/trim, you could also use a throttle input to give you an ideal count/second virtual encoder, and use that to control the base PWM value to which you would apply the LHS/RHS biases.

Here's a pot-variable 2-axis control of two motors:

...but you'd add encoders and use PIDs instead of the pots to set the PWMs. Repurposing the pots to set the ideal count/sec forward/backward rate and phase change slew rate between the encoders.