Notifications
Clear all

My robot drives like a drunk toddler

49 Posts
7 Users
2 Reactions
634 Views
(@scott)
Member
Joined: 5 years ago
Posts: 19
Topic starter  

I bought two of these motors: https://thepihut.com/products/tt-motor-with-encoder-6v-160rpm-120-1 from the

image

Pi Hut some time ago and added them to a standard robot chassis similar to the one in this video:

They have a 120:1 gearing ratio and two hall effect sensors on the motor. Should be more than enough to keep a robot in a roughly straight line and turn sometimes. 

They're plugged into an arduino with a L298N Dual H-Bridge Motor driver as you would expect. It all "works", I can drive, get signals from the encoders, count them.

 

I wanted to create a simple differential drive robot for my niece to program to drive forward, turn right 90, etc. 

Simple coding fun for her I thought...

Months later I'm baffled and wondering if it's possible to get a reliable count off these encoders at all. It's not that they're hopeless, but they're inconsistent enough to have the robot consistantly veer off to one side or turn by much too much. The unreliability isn't quite reliable enough to just compensate for either. 

Has anyone out there ever got reliable movement from a robot equipped with these? I notice that although these robot car chassis with encoders often appear in videos, I've never yet seen one demonstrate controlled movement. 

If you have succeeded with encoders of this design (ideally exactly like mine) I'd be very grateful to know how you did it. Having given myself months to get this prepared I'm now down to weeks.

A great many thanks in advance. 

 



   
Quote
TFMcCarthy
(@tfmccarthy)
Member
Joined: 2 years ago
Posts: 502
 

Posted by: @scott

They have a 120:1 gearing ratio and two hall effect sensors on the motor. Should be more than enough to keep a robot in a roughly straight line and turn sometimes. 

What do you think the hall effect sensors are measuring? Speed or direction?

How are you controlling direction? Are you measuring the difference between the hall effect sensors to calculate direction?

I haven't built one of these, so I have no empirical support. It just sounds like you're looking in the wrong place.


The one who has the most fun, wins!


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 7 years ago
Posts: 2491
 

@scott

Although I don't have this exact motorized wheel with encoders I have an equivalent. Firstly they are not optical encoders as in the Dronebot Workshop example rather they use hall effect sensors. Each encoder has two hall effect sensors A and B out of phase with each other which can be used to determine the direction of rotation if that is unknown. However it is known by the motor controller code so you only need one sensor per motor which can be either A or B.

https://www.aliexpress.com/i/32665572840.html

So if you choose sensor A on one motor's encoder output it can be attached to say pin 3 and the other motor's encoder sensor A to pin 2 to enable interrupt code on the Aduino Uno which you need for reliable results.

Having given myself months to get this prepared I'm now down to weeks.

I am away until Saturday so I don't have access to my code or connections until then but might still be able to help if you give sufficient information such as the actual code and connections you are using.

 



   
ReplyQuote
noweare
(@noweare)
Member
Joined: 6 years ago
Posts: 211
 

Maybe you can count the pulses out each channel (A,B) on each encoder for a full rotation. They should be equal then compare it to the specification. I have not used is part.



   
ReplyQuote
(@scott)
Member
Joined: 5 years ago
Posts: 19
Topic starter  

Thanks everyone, I've tried other methods but counting just one of the sensors per motor has the best results so far. 

By this method one rotation of the motor will yield 8 counts if all is well, so 960 for a wheel rotation. My experiments show that in say, four rotations, the 32 expected counts will actually amount to somewhere between 29 and 36-ish, and unfortunately this accumulates in motion. 

 

 



   
ReplyQuote
TFMcCarthy
(@tfmccarthy)
Member
Joined: 2 years ago
Posts: 502
 

@scott 

I rewatched the video and I think I see the issue. The motors don't behave identically given the same settings. You can see it in the first test of the motors.

motor RPM

Notice that the RPM is different for each motor. This will cause the car to drift. How much it drifts will vary with the speed setting.

The sensor accuracy will affect this as well, i.e., the optical encoder vs. hall effect.

Unfortunately, using just one encoder to measure distance won't eliminate the drift. In Bill's code, he waits until both encoders have reached the desired count. Hence, one motor will continue moving beyond the distance, resulting in the drift. Using just one encoder and waiting until it reaches the desired count doesn't really work if you pick the wrong motor. You can wait for the first motor to reach the count and then stop both motors, but the drift will still be there.

To do it properly you need to calibrate for the motors and then synchronize them with a differential. But that's more complicated than you need, I think.


The one who has the most fun, wins!


   
ReplyQuote
noweare
(@noweare)
Member
Joined: 6 years ago
Posts: 211
 

If its a constant offset then one motor can be driven faster/slower than the other one.

 

 



   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 7 years ago
Posts: 2491
 

@scott

Months later I'm baffled and wondering if it's possible to get a reliable count off these encoders at all. It's not that they're hopeless, but they're inconsistent enough to have the robot consistantly veer off to one side or turn by much too much. The unreliability isn't quite reliable enough to just compensate for either.

So you are saying that the number of pulses required for any degree of wheel turn is inconsistent?

Count 1000 pulses and the wheel turns x degrees and then count another 1000 pulses and the wheel doesn't turn by the same amount? 

Regardless of the PWM value the number of sensor pulses should mean the wheel has turned a known amount.

 



   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 7 years ago
Posts: 2491
 

@scott

This is ChatGPT's response although I cannot vouch for its accuracy.

This particular motor explains your symptoms almost perfectly.

The DFRobot TT Motor with Encoder 6V 160RPM 120:1 has a very low-resolution encoder + a big gearbox, and that combination is the root of your “1000 pulses ≠ same angle” issue.


⚠️ Key detail most people miss

  • The encoder itself is only 8 pulses per motor shaft revolution (DFRobot Electronics)

  • But it’s mounted before the gearbox

  • Gear ratio = 120:1

So at the wheel output, you get roughly:

That means:

  • 1 pulse ≈ 0.375° at the wheel

  • 1000 pulses ≈ ~375° (~1.04 rotations)

So far so good—but here's the catch 👇


🚨 Why your 1000 pulses don’t match angle each time

1. Gearbox backlash (big one)

These yellow TT gearboxes are not precision gear trains.

  • They have significant backlash and play

  • Internal gears can “take up slack” differently each run

  • Especially bad if:

    • You reverse direction

    • You stop/start between measurements

👉 Result: same encoder count, slightly different wheel angle


2. Encoder is measuring the motor, not the wheel

The encoder is on the motor shaft, not the output shaft.

So:

  • Any gear slop, elasticity, or wear is invisible to the encoder

  • The motor might rotate the same amount…

  • …but the wheel doesn’t follow perfectly


3. Low resolution = quantization error

960 pulses per wheel revolution is actually pretty coarse.

So:

  • 1000 pulses ≈ just over 1 turn

  • Small counting differences (miss 1–2 pulses) → noticeable angle change


4. Missed pulses (very common)

If you're using interrupts or polling:

  • At higher speed → you can miss edges

  • Noisy signals → false or dropped counts

Even a 1% error = 10 pulses ≈ 3.7° error


🧪 Quick sanity checks

Try these and you’ll likely see the cause immediately:

  • Always rotate in one direction only

  • Run the motor slowly

  • Mark the wheel with a pen

  • Do:

    • 0 → 1000 pulses

    • Reset

    • Repeat

If results vary → mechanical (gearbox/backlash)

If results drift over time → counting issue


🧠 Bottom line

Your expectation is the problem—not your setup.

With this motor:

  • Encoder ≠ precise wheel position sensor

  • It’s good for speed + rough distance

  • Not good for repeatable absolute positioning


✅ If you need consistent angles

You’ll need one of these:

  • Encoder on the output shaft

  • Higher resolution encoder (e.g. magnetic or optical >1000 CPR)

  • Or add:

    • PID control + always approach position from same direction


If you want, tell me how you’re reading the encoder (Arduino? interrupts? polling?), and I can help you rule out whether you’re also losing counts on top of the mechanical issues.



   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 7 years ago
Posts: 2491
 

@scott

Been doing some more reading on that motorized wheel with encoder. There are issues to do with translation of number of motor turns with number of shaft output turns from gear box when it comes to exact positioning. Your motor control code has to take them into account. The research also gave me insight into positioning issues I also had. My robot project is different so with your simpler setup I would need the same hardware to test code solutions out. Vacuum robots supplement the encoders with other sensors to keep on track including monitoring the swivel wheel at the back (or front).

But again the more detail you give the better the responses such as the code you are using.

 



   
ReplyQuote
(@scott)
Member
Joined: 5 years ago
Posts: 19
Topic starter  

Posted by: @robotbuilder

Count 1000 pulses and the wheel turns x degrees and then count another 1000 pulses and the wheel doesn't turn by the same amount? 

Yes, afraid so. 

 

 

Yeah, 960 pulses per turn sounds wonderful but any slight inaccuracy is multiplied by 120X. 

That said, mine is not an atypical use case, everyone who buys motors of this type must face this problem or overcome it.

My most successful code is attached below:

 

 



   
ReplyQuote
noweare
(@noweare)
Member
Joined: 6 years ago
Posts: 211
 

I could be out in left field here. In the code if the difference between counts is less than 3 you  make the error between motor counts 0. That's in a while loop so I if you make it 0 your not really correcting for the speed difference between the two motors as your heading for your target.  



   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 7 years ago
Posts: 2491
 

@scott 

Your code can be greatly improved!!

There is an upper limit to how much you can overcome the limitations of the motorized wheels you are using without adding a gyro like the MPU6050 but you can improve the code greatly and this can be done in working stages. Like I wrote I am away from home until late Saturday and don't have access to my own code to make sure any code I post actually works.

In the meantime unless someone else jumps in with working examples you might like to google PID and Odometry for Arduino based robots.

I wanted to create a simple differential drive robot for my niece to program to drive forward, turn right 90, etc.

Simple coding fun for her I thought...

So is she actually interested in coding?

It is all up hill unless it is something you want to do yourself as if she is interested she will do it herself.

The simple coding you imply would be writing what amounts to turtle code like:

forward(1000); // move forward for 1 second
turnRight(2000); // turn right for 2 seconds

So I would start there in the main loop()

Those examples move for a fixed time period so results would be crude to start with until you refine the functions to use the encoders and more advanced control software solutions but it sets the framework.

Using time periods for travelling straight (sort of) you would adjust the PWM value of each motor until it sort of drives straight and turns around on the spot. Later work on giving a distance to move and an angle to turn.

 



   
ReplyQuote
(@davee)
Member
Joined: 5 years ago
Posts: 2042
 

Hi @scott,

  This comment is probably a red herring for your problem, but as I don't have any identical equipment to test it on, all I can do is flag it as a possible warning.

I note in your code:

  // Hall sensors NEED pull-ups
  pinMode(encLeft, INPUT_PULLUP);
  pinMode(encRight, INPUT_PULLUP);

which to me a 'red flag' situation.

INPUT_PULLUP means that a high value resistance within the microcontroller is internally connected between Vdd and the GPIO pin. The value of the resistance depends upon the specific microcontroller family, and random silicon process effects during manufacturer, and typically has a very wide tolerance. It is intended for a circuit in which that particular pin is not connected to anything, but good electrical hygiene practice requires it to be held high, and saves the designer adding an external resistor.

When the pin is being used to monitor a switch that 'rapidly' changes between open circuit and connecting to ground, a pull up to Vdd is required to show when the switch is open circuit, so that the GPIO will read 'high' (1). The internal pull up resistor typically has a higher resistance value than would be recommended for reliable operation, although it may be low enough to appear to work.

When the switch opens, the pull up resistor must provide the current to charge up the stray capacitance, plus supply any current flow to ground, to accomplish the transition from low to high. If the resistance is 'too high', then this will take an appreciable time, and this time will be further extended if the switch has a conductance path to ground. This applies regardless of whether the 'switch' is a mechanical switch, or an electronic switch, such as one based on Hall effect.

Unfortunately, for your circuit, I cannot determine the value of the internal pullup resistor, the effective capacitance of the circuit, or the extent of any current flow draw by the Hall Effect sensor. The 'ideal' solution would be to monitor the pin input with an oscilloscope, to check whether the waveform in operation. I would expect that to show that an external pullup resistor, possibly about 5k Ohms, would result in a much cleaner and robust waveform for the GPIO input to sample.

However, it is feasible that the job that the internal pullup is 'good enough', and adding an external resistor has no apparent effect to the counting operation.

Theoretically, it is also feasible, though I suspect very unlikely, that the resulting current flow after adding the 5k Ohm resistor, exceeds the Hall Effect sensor current rating, as I do not have a specification for the device.

If Vdd is 5V, and the total pullup resistance is 5k Ohm, then the current will only be 1 milliAmp, which I would guess to be comfortably with the Hall Effect sensor's capability, but in the absence of a data sheet, this can only a guess.

Best wishes, Dave



   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 7 years ago
Posts: 2491
 

@davee 

https://www.aliexpress.com/i/32665572840.html

If you go to the above link the image didn't show the use of external resistors.

You can click show more and also download a manual although that didn't resolve the question.

The author wrote:

In my experience, the most common issue was the encoder signal being too noisy, causing the robot to jitter. I solved this by adding a small 100nF capacitor across the encoder signal lines and ensuring the motor driver had a clean ground path. Once these issues were resolved, the robot moved with remarkable smoothness, demonstrating the effectiveness of the arduino dc motor with encoder setup.

 



   
ReplyQuote
Page 1 / 4