Showing posts with label encoders. Show all posts
Showing posts with label encoders. Show all posts

Monday, December 12, 2016

DIY Vehicle Speed Sensor Buffer

Here's the riveting tale of how I created a Vehicle Speed Sensor (VSS) interface circuit for my Jeep Grand Wagoneer (yeah, that Jeep).

Jeep VSS
Speed sensors are used by cruise control systems and by fuel injection computers. Jeep used one for the former.

I wanted the sensor for the GM throttle body injection (TBI) system I retrofitted onto the Jeep's old AMC 360 c.i. V8.

Back when my Jeep was built, vehicle speedometers were driven by a flexible steel cable, the speedometer cable, connected by a tiny gear to the output shaft of the transmission.

Jeep, as with other vehicles of the era, split the speedo cable in half and stuck the VSS in between.

So, with insufficient hobby funds to buy an expensive, off-the-shelf Vehicle Speed Sensor/Buffer, but wanting to reap the benefits of a VSS, I created my own interface. Here's how it went down...

Thursday, January 24, 2013

555 Schmitt Trigger Circuit for Wheel Encoders

I've been playing with Schmitt trigger circuits again, this time using a 555 Timer based on a discussion on diyrovers started by Jason.

Schmitt triggers are circuits that provide hysteresis. The concept is simply that instead of one threshold for on and off, there's an upper and lower threshold.

Signal (U), no hysteresis (A), Schmitt (B) - Wikipedia
With one threshold (red line, U above) a noisy signal can trigger an action more often than intended (A). When there's an upper threshold to trigger on and a lower threshold to trigger off (green lines on U), noisy signals won't trigger falsely (B), so long as the noise doesn't cross the thresholds.

Wheel Encoder Adapters

To measure speed and distance travelled, Data Bus uses Sparkfun QRE1113 IR reflectance sensor breakout boards and wheel encoder discs printed with WheelEncoderGenerator.

On my robot, using QRE1113 reflectance sensors running at 5V, this is the waveform I get.


It looks similar to a half-rectified AC signal, about 3V peak and around 1.5V offset. Running on 3.3V, I get a 1.8V peak with 0.9V offset. Either one should be enough to trigger logic circuits.

It's not a bad idea to add hysteresis, though. If the sensor is right between encoder stripes, add a little noise and it could trigger more than intended.

555 Timer Schmitt Trigger

While you can easily find many examples of 555 timers wired to provide hysteresis triggering, and we'll look at the two common ones, a third circuit works better for the wheel encoder system on Data Bus.

In all cases, the encoder signal is ultimately wired to the Threshold and Trigger pins of the 555.


Inside the 555 timer is a 3-way voltage divider that provides the hysteresis thresholds. When the input voltage is above 2/3 Vcc, the 555's output goes low. When the input is less than 1/3 Vcc, the 555 output goes high.

555 Internals, more or less
But the 555 won't trigger for my 1.8V encoder signal which is below the 2.2V threshold. It won't work at 5V either. What can we do...?

Series Capacitor

By passing the signal through a capacitor, low frequencies (including DC) are filtered. If this high-pass signal is fed in between a voltage divider, it adds a dc offsets to the signal.


If the offset is 1/2 Vcc then the new peak voltage will be 0.9 + 3.3/2 = 2.55V, more than enough to trigger. The lowest voltage will be 3.3/2 - 0.9V = 0.75, well below the 1.1V lower threshold.

In the LTSpice simulation below, the red trace is the low threshold, the blue trace the high threshold, and the green trace is the signal with the dc offset.


So we're done. Let's build the board and move on, right? Wrong. I prototyped the circuit on a breadboard and found out it doesn't work like I want. At low wheel speeds, the 555 doesn't trigger at all. Why?


In the picture above, the red trace is the signal coming out of the high pass capacitor. Because the wheel speed is so low, most of the signal is low frequency and thus filtered and thus too small to trigger.

So, all you have to do is slap a big capacitor in place of the small one, right? With a capacitor that's large it can trigger on low wheel speeds, yes. However, it can can also get the 555 output "stuck."

Stuck? Yeah. If the robot sits with the input low too long, the 555 won't trigger for a long time after the wheels start spinning.

The reason is that, with the input voltage low, DC offset increases (the series capacitor charges) until the low voltage is now the new DC offset. When the wheels start moving again, it takes a long time for the circuit to bleed off the DC offset. This is the simulated result with a large capacitor, 220uF. It mirrors the real life experiments I did.


A smaller capacitor reduces the effect. Here's a 47uF capacitor. This also shows the output of the 555. The simulations do a good job of approximating what I'm seeing in real life.


Bottom line: you have to find the right capacitor for your needs. A small cap would work on Data Bus. It goes fast, and is only stopped at the starting and finish line. Still, I don't really like this circuit for wheel encoders. I'd prefer to fix the problem with the first circuit.

Transistor Amplifier Inverter

Using an NPN transistor to amplify (and invert) the phototransistor signal works well. It's not revolutionary although I didn't notice any similar circuits when searching for 555 Schmitt Trigger circuits. So, here it is.


Connect the base of the NPN through a resistor to the encoder board output, tie the collector to Vcc through a resistor, and the collector becomes the output for the 555. Simple, eh?

The Q1 transistor is either nearly 5V thanks to the pullup, or nearly 0V when base current is permitted to flow by the QRE1113 breakout board.

As a result, the circuit triggers at the lowest practical wheel speeds and doesn't lock up. Seems reliable enough to use. The only downside is that the duty cycle isn't even close to 50%, although no circuit is going to get it perfect. One can address this issue in software.


Encoder Imperfections and Software

With a pulse train that isn't a 50% duty cycle, calculating speed and distance is probably best done by timing either rising edges or falling edges, but not both.

The longer the robot travels on a particular leg of its journey, the less jitter affects distance calculation.

For speed, it may be wise to adjust control loop timing, encoder resolution, or robot speed ranges to adequately filter jitter and other noise. A slow robot needs more stripes, a fast robot needs fewer. A slower processor needs fewer and/or slower.

Think about how often the MCU has to sample encoder counts to adequately filter noise and calculate speed with acceptable accuracy, given the number of stripes and the robot's typical speed range.

And maybe filtering isn't even necessary. If a speed PID controller is adjusting a robot's speed at every edge, jittery speed adjustments between edges may be effectively filtered by the momentum of a fast, heavy robot.

If the robot is slow and very light, momentum won't filter jittery speed changes very well. Software can do it instead. Change speed based on a running average, leaky integrator, or other software filter. Or, the PID controller can check speed by timing many pulses instead of few.

Wheel imperfections and encoder disc mounting imperfections cause a low frequency modulation of the encoder signal. Sent through a Schmitt trigger, the output pulse width will vary.

That sort of jitter may be a problem when precisely traveling short distances at slow speeds. More precision in the assembly may help. Or increasing the encoder resolution.

Conclusion

The 555 is quite the Swiss Army Knife of ICs. Acting as a Schmitt trigger is one of its many capabilities. With all that said, it's probably just as easy to just use a Schmitt Trigger inverter instead of the 555. I'm looking into that next.

Thursday, November 1, 2012

WheelEncoderGenerator 0.2-beta


Announcing version 0.2-beta of WheelEncoderGenerator, the open source, cross-platform application for quickly generating and printing wheel encoder discs. Download here.

Friday, January 20, 2012

Encoder Board Evolution

The old encoder board I fabbed for Data Bus has failed. Rather than repairing several lifted traces on the old one, I felt that a more reliable approach was to order a professionally fabbed board via OSH Park.

I took the opportunity to redesign using SMT components so I could shrink the board.

Old board above, new SMT board below
The old design was based on an LM393 dual comparator IC configured as a schmitt trigger. So is the new board, but instead of a single IC, it was easier to route traces using individual, Texas Instruments TL331, SOT-23 comparators. All the passives are 0603 size and the LEDs are 1206 size.

I'm still working on my technique for hand soldering SMT. Here are some things that seem to work so far:
  • Push components out of their tape using the point of a small nail
  • Tin the pads then suck off the solder with solder braid
  • Use a flux pen on all the pads
  • Use a really small tip and a decent iron
  • Use 0.015" solder; I use Radio Shack silver bearing solder
  • Use non-magnetic pliers/tweezers to pick and place parts
  • Use the nail tip to gently nudge them around on the board
  • Hold the parts down with the head of the nail while you solder
  • Tack down one side of the component, add solder if needed
  • Then add solder to the opposite side while holding it
Components tend to get pulled vertical by solder surface tension if you have too much solder on the pads so that's why it seems to work better to remove some solder and to hold the component down with a nail.

It's pretty darned tedious. I ended up reflowing the SOT-23 comparators using my reflow skillet. As I have two encoder boards to populate, I will try reflowing all the parts on one of them and see if that is any easier.

Hopefully the new board will hold up better to the rigors of testing and competition than the home fabricated board. Plus, I'll have spare boards in case something goes awry.

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

Friday, October 15, 2010

Comparator With Automatic Voltage Reference

I'm working on building a circuit to adapt the output of wheel encoder sensors to a microcontroller. The output of these IR reflectance sensors is a sine wave, with some issues. Here's the general problem:

Let's say you have a sine wave, and the amplitude varies over time, and the signal is modulated by a lower frequency sine wave.  (In my head I was thinking it was kind of like if the DC offset were varying over time but of course DC doesn't vary...)  The sine wave has to be converted to a pulse train with a voltage comparator. Just pick a reference voltage and anytime the signal is higher than the reference, the comparator output is +5V (ish) and if it's below then it's 0V (ish). You can use a simple voltage divider or a potentiometer to set the reference voltage like so.

Comparator with potentiometer voltage divider for Vref

Simply using a voltage divider as a voltage reference to trigger the comparator isn't good enough. At best, the pulse width will vary as the sine wave varies. That can cause some inaccuracy in measuring speed and distance.

At best, pulse width varies and so does accuracy
At worst, you might miss pulses entirely if you can't get the voltage reference set just right or if the DC offset varies too widely.

It's possible to miss pulses with a fixed reference voltage
Wouldn't it be nice if we could automatically remove the signal component and leave behind the modulation and use that for the comparator reference voltage? Well, we can, and it's not that hard.

All we have to do is use a low pass filter. We filter out the higher frequency output of the wheel encoder sensors, and retain the modulation signal.  Basically what we're trying to do is adjust Vref to be a value between the upper and lower peak of our signal.  We take care of amplitude modulation at the same time.  This same approach can be used to automatically detect the DC offset of a signal and use that as Vref.

A simple low pass filter is more than adequate and keeps parts count low on the 1"x1" printed circuit board I'm designing. Pick a resistor in series with the signal input, and place a capacitor in parallel, and feed the output to the reference pin of your comparator. Like this:

Auto Vref using low pass filter to detect DC offset/amplitude fluctuation
You can experiment in LTSpice or in real life with different values for R and C but the formula to find the cutoff frequency is given by:


A higher value of R and C means the circuit cutoff frequency decreases, approaching but never reaching 0 (DC). You can imagine that a giant capacitor and resistor would filter out most ripple and a tiny resistor and capacitor wouldn't.

I measured the encoder frequency at approximately 100-200Hz. The slope of the frequency response curve for this type of filter is somewhat shallow so there is a tradeoff between the amount of higher frequency attenuation and how quickly the circuit reacts to changing DC offsets.

Frequency response of filter with higher cutoff frequency; -30dB at 100Hz

This first picture (above) shows a higher cutoff frequency and so it is more sensitive to changing DC offsets, but doesn't attenuate the encoder signal as much (-30dB at 100Hz). Which really isn't that big of a deal, as long as there is some attenuation.

Lower cutoff frequency attenuates the signal at 100Hz by -50dB
The picture above shows a lower cutoff frequency and so there's greater attenuation of the higher frequency encoder signal (-50dB at 100Hz). But if the DC offset fluctuates too rapidly, this circuit won't keep up. Because it's attenuating lower frequencies more, too.

In my case, a value of R=10k and C=1uF is a nice happy medium for my particular situation. More compact, low value capacitors didn't attenuate enough and higher capacitance prevented the circuit from tracking DC offset properly.

In the first video below you can make out the larger encoder waveform and the attenuated waveform that makes Vref. Notice how it tracks nicely between the peaks of the signal.



The second video shows the comparator output versus the encoder signal. Notice that the pulse width of the output remains fairly stable despite the DC offset and amplitude fluctuations in the signal.



Some of you may have noticed the phase shift introduced by the filter. This has the added bonus of adding hysteresis to the circuit making it more immune to noise.  [EDITED 11/07/2010]