The Brick Bakery: Advice on the Rotation Sensor.

It is reasonably well known that the Lego rotation sensor (at least in conjunction with the standard RCX firmware) loses counts at some times. This behaviour is reported to be very much better when using the LegOS firmware - but I have been unable to test that.

I wanted the facts - so it's time for the rigerous scientific approach. Well - OK - the half-assed semi-scientific Steve Baker method :-)...

Experiment 1:

Connect two rotation sensors to a motor, run for 10 seconds, write down the counts for each sensor as reported by the RCX. Repeat the experiment four times:
   Sensor 1    Sensor 2
     792         792
     790         790
     788         788
     784         784

Well, at standard 'new Mindstorms' motor speeds (about 300 rpm), we can conclude that either no counts were lost at all or the lossage happens identically for both sensors.

Experiment 2:

I did one ten minute run - and the two sensors still returned identical counts even after such a large amount of time.

Experiment 3:

We can test for the theory that somehow the system firmware always drops counts on both sensors simultaneously. If that were true then if I run two sensors at different speeds one will drop a different number of counts from the other.

OK - change the setup so that the first rotation sensor is on the motor shaft - and the other is on another shaft that's geared down 5 times. The second sensor is now rotating exactly five times slower than the motor. If counts are dropped for both sensors at the same time then we'll be able to tell because the number of counts for the second sensor will not be exactly one fifth of the count for the first sensor:


   Sensor 1    Sensor 2   Sensor2 * 5
     778         156        780
     774         155        775
     772         154        770
     771         154        770

Although the numbers for Sensor1 and Sensor2-multiplied-by-five are not exactly the same, this is fine. We are using integer math, and dividing by five (in the gear train) and then multiplying by five again would produce an error of up to 4 units even if the system never loses a count. Since (sensor2 * 5) was always within two units of sensor1 - that's as good as it gets. We didn't lose any counts in the experiment.

First Conclusion:

At the speeds I tested (~50 to ~300 RPM), we don't lose any counts.

Experiment 4:

It's said that when the shaft speed is too high, the software will eventually lose counts for sure. So, let's speed up one shaft and keep the other at the 'known good' speed of the Lego motor.

I swapped the gears so that the second sensor is now geared up 5 times. The second sensor is now rotating exactly five times faster than the motor.


   Sensor 1    Sensor 2   Sensor2 / 5
     752         2517       503
     749         2494       498
     749         2499       499
     748         2480       496

Woah!! BIG TIME Lossage. It's pretty clear that the rotation sensor doesn't work at 1,400 RPM without losing data. The good news is that it's pretty consistent in that it loses about one count in three. This could be useful to know in some applications. The number of lost counts will vary as a function of speed in some manner - but the result is clear - I don't recommend cranking the rotation sensor faster than the motor.

Experiment 5:

So, I wondered about the slow speed lossage (which is a commonly reported 'phenomenon'). I geared down the motor by 25:1 and ran again. Sensor 2 is now running 25 times slower than the motor:

   Sensor 1    Sensor 2   Sensor2 * 25 
     790         32         800
     785         32         800
     784         29         725  <===== Oops!
     779         31         775

As with experiment 3, we can expect an error of one count in the second sensor because of integer math - but an error of two or more would indicate inaccurate counting.

And on the third run, you can see that Sensor2 should have read 30,31 or 32 counts. It only read 29 and that MUST mean an error in reading the sensor.

So at slow speeds (about 12 RPM in this case) we lost at least one count over about 40 seconds of testing.

Conclusions:

You can run your sensors directly on the motor shafts of the standard Mindstorms motor - and you can run it 5x slower than that and still not lose counts. However, don't run 25x slower or 5x faster than the motor or you will lose counts.

Try to stick to rates around 50 to 300 RPM - the range may be a little higher - but we know that <12 RPM or >1400 RPM are definitely bad news.

Future Work:

This needs to be tested under LegOS to confirm the ranges that it can cope with.

Someone (not me!) should probably figure out a bunch of gear trains and motor loadings to check the actual limits - and run the tests over MUCH longer periods than 10 seconds to get some measure of reliability.

I also wonder if it's possible to make the thing lose more counts by giving the firmware more work to do. If I run 6 threads all doing lots of sensor and motor work - and run the light sensor at the same time - and play lots of beeps on the speaker...would that load the firmware down enough to make it drop counts at all speeds? That's an open question.

Implications for Robot Design

One common use for a rotation sensor is to measure how straight a robot is moving. Many robots work by applying one motor to each of two drive wheels - but as I explain here, motors are not equally powerful so one wheel will try to spin faster than the other and your robot will probably gradually veer off to the left or right.

The 'obvious' way to correct this is to place a rotation sensor on each wheel and count the revolutions of each. Whichever wheel is running fastest can be slowed down a little (typically by 'floating' the motor output) until the counts are again equal and unless the wheels are slipping, you will be going in a nice straight line.

That design is OK - but knowing what we learned from these experiments, it might be better to place the rotation sensor on the motor output shaft where the speed is likely to be in the 'sweet spot' of 50 to 300 RPM where the sensor is accurate - rather on the wheel axle where the speed will probably be much lower and into the 'danger zone' where the rotation sensor loses counts.

Obviously, you'll still lose counts when the robot starts or stops - or if you steer by completely stopping or reversing one motor - fixing that would be very hard.

One commonly suggested improvement on this design is to insert a differential gearbox between the two drive wheels and place a single rotation sensor on the output. This saves a sensor input on the RCX and in theory allows you to correct for speed mismatches by looking to see whether the sensor is rotating clockwise or anticlockwise. That works because the output of the differential is half the sum of the speeds of the two wheels. Since one is rotating clockwise and the other anticlockwise, the sum of their speeds is zero when the robot is going straight, positive if it's turning one way and negative if it's turning the other way.

On paper, that design is quite clever. You lose the ability to measure the overall speed that the robot is travelling - but saving a valuable RCX input is well worth the sacrifice in many cases!

However, the rotation sensor will be spinning VERY slowly - if at all. Since we know that the sensor will lose counts at such low speeds, we can tell that this approach isn't a good one. Every time the sensor loses a count, the robot will veer a little off-course without the RCX knowing about it.

Probably the best design for a robot like this is to use two motors via a pair of differentials so that one controls the average speed of the two wheels and the other controls the difference in their speeds. This 'adder-subtractor' drive doesn't need a sensor at all. If the 'difference' motor is using active braking then the robot will go in a straight line for sure. You may still want to use rotation sensors to calculate the rate of turn or the forward speed - but in each case, they can measure the motor speed with reasonable precision.


RETURN TO TOP
Steve Baker <steve@sjbaker.org>