Thursday, March 10, 2011

AVC Bot: Wheel Encoders

My AVC robot and Pokey my firefighting robot have some things in common. Right before I started working on the AVC robot, I was installing wheel encoders on Pokey and had...
I used the lessons learned on Pokey to implement wheel encoders on Data Bus.

Design

Since I don't have enough spare pins to read a separate counter IC's value, and rather than complicate the overall design with a separate microcontroller communicating over SPI or I2C, the mbed microcontroller will interrupt for each individual encoder trigger from each of the rear wheels. I may even add front wheel encoders, but I doubt it.

What resolution to pick?  On the one hand, I don't want to overload the processor. It's got plenty to do: gyro, compass, and ranger sensors have to be updated in near real time at a fairly high rate, around 20-50Hz. On top of the fact that a lot of computation will be happening to estimate heading, position, bearing to waypoint, and so on.

On the other hand, to improve navigational accuracy, the robot will be incorporating distance data traveled at a given heading to estimate vehicle position (supplemented by GPS).

If I update the gyro heading at 50Hz, then it makes sense to update the distance data just as often. So I need enough stripes to offer reasonable resolution at 20ms intervals, but not too many that servicing the interrupts takes away from other processing. I haven't determined what that balance is, yet.

My Wheel Encoder Generator java application hard at work
Just for testing, I arbitrarily chose 8 stripes. With a 4.1" diameter wheel traveling at 20mph (unlikely) that's a maximum of 8 interrupts per revolution on rising and falling edges, or one interrupt every 4.6ms. That should barely tax the processor.

The current revision of the encoder discs use 16 black stripes for 32 edge triggers per revolution.

Pokey's encoder interface
Electronics

The IR Reflectance sensors are breakout boards from Sparkfun using the QRE1113 SMD sensors. They work fine on the 3.3V that powers most of the electronics on board.

I started by using the circuit and board I designed for Pokey, initially, but found it woefully unsuitable. At low speeds and standstill it would tend to give many false readings.

I implemented a schmitt-trigger circuit using the same LM393 comparator. (Schematic and Board here)

It seems to work more reliably at all speeds now.

Schmitt trigger encoder interface installed
Encoder Discs

I used foam core, cut to friction fit inside the 2.8" RC truck wheels. I didn't have to be very precise in my cutting and I wasn't. Hopefully no one will notice and make fun of me on race day.

The encoder disc pattern was generated with my handy Wheel Encoder Generator (soon to be released to the world in beta) application. I printed the patterns on self-adhesive paper and stuck them to the foam core and inserted them into the wheels after some trimming.


Sensor Mounting

There aren't a lot of places to mount the reflectance sensors on the ElectrixRC Circuit. The best place I could come up with was the rear bearing carriers.


They have a flat spot with enough material present that I felt I could drill another hole, mount a bracket securely, but not compromise the part's strength too much.

The brackets are made of brass strip, 1" long with a 90 degree bend at the end for mounting the sensors.



I probably don't have to do much about tuning their clearance or aligning them radially to the wheel. They seem to work fine in this location, triggering the interface board, even at faster wheel speeds as you can see below.

Electronics Testing

To make sure the interface board was sending out a good pulse train, I did some testing on the oscilloscope and it looks like the signal is coming in cleanly to the board, and from the board.

Raw encoder signal
Signal out of the schmitt trigger interface board
Software

For distance, I set up pin interrupts on the mbed for the input pins rising and falling and then counting the number of pulses from each wheel encoder. One can compute speed by dividing by the sampling time and taking the average.

Even with 32 ticks per revolution, this isn't the best way to compute speed if you are checking the counter frequently and your robot is going slowly. Another option is to count the time between pulses to compute speed. It's best to compute time between the rising edges of the signal in case the on time and off time don't quite match.

It's also possible to estimate heading rate based on the difference in the distance traveled by each wheel if you know the track width and have precisely calibrated each wheel's encoder system.

The encoder sensors installed

A later version of the wheel encoders

3 comments:

  1. You keep em coming and coming, all those posts!!! Great work man.

    Your java application looks neat. What is the gui class you used for it?

    Cheers

    ReplyDelete
  2. Thanks! I've been pretty busy working up to Saturday! :D

    The application is Java-based. Want to play with it? I'll shoot you the download link.

    The posting pace will slow down again after Saturday...

    ReplyDelete
  3. hello, i used some 0711 and the signal i get is like a 1V sine wave, i wanted to use a schmitt trigger, but it does'nt react to the signal, the output is aways 0 or 5v any idea? best is use comparators, dont know why people use schmitt trigers, it cant work with such tiny signals, maybe i am missing someting

    ReplyDelete