The 9V motors on the T300 robot vehicle are each fitted with two hall effect sensors that act as encoders. I figured I’d take a closer look.
The two sensors are positioned to read a magnet attached to the rear of the motor’s shaft. They are quite close together so that, as the magnet rotates, one will be triggered very shortly after the other and then there’ll be a long(-ish) gap before they get triggered again. This is the secret to being able to tell which way the magnet, and therefore the motor, is rotating.
I placed Sheldon on a pedestal so that the tracks were hanging in the air and free to move. Then I hooked up the two signal lines from the hall effect sensor for the left motor to my scope. The Teensy was programmed to provide a PWM signal to the speed control using analogWrite(64). In theory, that’s a quarter of the maximum speed – a speed I’ve defined as ‘slow’. And this is what I saw (click on the image for slightly larger version).
The signal from each sensor starts high, which is what we expect because, as I mentioned in a previous post, the sensors have 10KΩ pullup resistors. Then sensor 1 goes low. A smidgen over 1ms later, sensor 2 goes low. They both stay low for about 12.6ms before sensor 2 (and not sensor 1 as I’d expected) goes high again, followed 4.2ms later by sensor 1. Then, 7.2ms later, it all happens again.
The time between falling edges with sensor 1 is a tad over 25ms. Of course, all these numbers will depend on how fast the motor is going.
I then programmed the Teensy to put the motor into reverse (with the same speed/PWM setting). This is what it looked like.
At first it looks like the same deal, but there’s a significant difference. Here, sensor 2 goes low shortly followed by sensor 1 – the reverse of the previous situation, which makes sense. But then sensor 2 is also the first to go high, again quickly followed by sensor 1. This is the regular kind of interleaving I expected, with the falling and rising edges of one sensor always slightly leading the other.
I didn’t try the right motor. But given that it’s in a mirror orientation to the left one, I presume the patterns will be reversed.
Next, with reverse direction still selected, I changed the program to nearly full speed, using analogWrite(254). This is the waveform as the motor starts up. Note how the frequency increases as the motor accelerates.
This is with the tracks hanging in the air – ie, with no resistance. With the vehicle on the ground, I’d expect to see it take longer to get up to full speed, but I don’t have long enough oscilloscope leads to test this!
Once it was up to speed, it looked more regular, like this.
How am I going to use this information? With lots of calibration, you could use it to measure the speed of the robot. That might be handy, although subject, I imagine, to a lot of error. In any case, I’m not really all that interested in this kind of precise feedback.
You can also tell whether it’s going forward or backward – although presumably you already know that having told it which way to go.
One option is to tie all four signals (two per motor) to interrupts, perhaps setting a timer going when a specified interrupt fires. But that’s an average, even at slow speed, of an interrupt firing every 5-6ms. Is that too much?
One useful application, I think, is to test whether the robot is moving at all. It would be a way to test if the vehicle has got jammed against something and switch off the motors to avoid draining the battery or overloading any electronics. You’d need to monitor only one of the sensors per motor in that case, as you’re only interested in whether the signal is changing.
Anyway, if I do decide to use these encoders, at least I have some data to work with now.
[ADDENDUM] Just before this post was about to go live, I decided to have another look at the encoders. This time I wired up all four sensors – two from each motor. I also routed the signals via a 74HC14 chip, a hex Schmitt inverter whose hysteresis definitely helped clean up the signals a bit, as you can see from the following scope screengrab.
The top two traces are for the right motor and the bottom two for the left. The robot was configured to go forward at slow speed.
This confirmed what I found before – that when the motor (in this case, the right one) turns in one direction, the edges of one hall effect sensor signal always lead the edges of the other. And the gap between edges is roughly the same regardless of whether they are rising or falling. But in the other direction, it’s very different. In this example, sensor 3 rises before sensor 4, but sensor 4 falls before sensor 3. And the gaps are different.
The Schmitt inverters have, of course, changed the logic of the signals – they are now normally low and are taken high by the sensor ‘triggering’.
So when the motors first start up, this is the result I was expecting to see.
In the code for the Teensy, I’d inserted a 3 second delay before commanding the motors to start, to ensure that everything (including hall effect sensors and the inverter chip) was powered up. When I zoomed out, I saw this:
Over to the left, where all signals are low, is where everything is switched off, so you’d expect the probes to pick up no signal. Then the motor and logic circuits are powered up and two of the sensors have, as it were, ‘triggered’ – perhaps just because of the position the magnets happened to be at the time. And then the motors started turning and we get the traces we’re expecting.
So if I do use these sensors, I’m going to have to allow for a possible random signal on power-up. A slight pause at the beginning, in the setup function, should take care of it.
[UPDATE 27/09/2018] And in case you were wondering, yes the probing got quite messy.