Archive for January, 2006

PWM Motor Control with a ROM

Tuesday, January 17th, 2006

Here’s my next plan for motor control: Digitize the ADXL’s PWM signal into sixteen time sections (four left and four right) and use the resulting code and a PROM to generate a new PWM controlling the motor.

ADXL202 with PROM for Motor Control

More details to be added later.

Tilt Sensor and Motor Drivers, Take I and II

Sunday, January 15th, 2006

After getting the PLL locked onto the signal from my ADXL202 tilt sensor and deriving separate left and right signals from it, I hooked it to the SN754410 H-bridge driver and wired up a motor salvaged from a toy car.

My goal is to control the motor’s direction using the H-bridge and its speed using pulse-width modulation (PWM)–the same signalling technique the sensor uses to indicate the magnitude of its tilt. I’d like the speed control to be proportional to the degree of tilt, so that a small tilt results in a slow correction from the motor, and a large tilt results in a faster correction.

With PWM speed control, the power to the motor is turning on and off at a fixed frequency, high enough to be irrelevant to the motor’s motion, but low enough not to cause problems with the induction of the motor’s windings. (Mine seems to be running at about 140Hz.) To make the motor go faster, leave the power on for a longer portion of each cycle before turning it off; to make it go slower, leave the power on for a shorter portion of each cycle.

In my first attempt, I wired the motor for locked antiphase driving. This control method constantly supplies power to the motor, but rapidly reverses its direction. To make the motor go faster forward, supply forward power for more of the time and reverse power for less of the time. This obviously consumes a tremendous amount of power, but also provides strong control over the motor’s behavior. It could be useful in getting a robot to stand still on a hillside, or hold its ground in a competitive setting without specifically trying to advance.

In my case, it just makes the motor vibrate. I suspect I’m not really supplying enough power to make it work, and the motor never does more than jerk a bit as I tilt the sensor toward its extremes. It was a nice idea–had it worked, it would have meant I could wire the sensor output directly into the motor driver’s input with no additional circuitry–but it just wasn’t meant to be.

For my second attempt, I used the left and right signals that I derive from the sensor and the phase-locked, 50% duty cycle signal, and wired them to the H-bridge inputs. Theoretically, this should have worked better than the locked antiphase control–with only one input active at a time, I should get more oomph out of the motor, and it might actually turn a bit instead of just jittering. Sadly, this still wasn’t the case. Apparently with this motor and only a 9V supply, 0-25% duty cycle isn’t enough to get it going, and certainly not enough go make it ramp up speed slowly with a slowly-increasing signal.

Those two methods were essentially freebies–all of the signals were available using parts I’d already wired onto the board. For my third attempt, I added a 74LS279 S-R latch, a logic device that remembers whether it has most recently been set (S) or reset (R) and holds its output accordingly.

I didn’t get very far in my experimentation before abandoning that line of pursuit as well. My thought was that I could use a master S-R latch to remember whether the motor was supposed to be turning forward or backward, and slave S-R latches to activate from the start of the duty cycle to the end of the “rightness,” or from the start of the “leftness” to the end of the duty cycle. This would change the effective duty cycle of the motor control from 0-25% to 0|50-75%.

The first complication was that my signal (sensor) and reference (PLL) don’t seem to be exactly in phase, or that the phase delay of negating one or the other is noticeable. When I view the derived left and right signals closely on my scope, I see a tiny spike at the start of each master duty cycle. Those spikes set and reset the forward-backward latch semi-randomly, preventing me from using this method without getting my phase timing more tightly calibrated than I want to have to rely on.

So just to test whether any part of the method was viable, I set up the left-tilted slave S-R latch to set (activate) as soon as the left signal is detected (remember, the earlier it is, the further left it’s tilted), and reset (deactivate) at the end of the master duty cycle. This gave a duty cycle of 50-75% for my S-R output, which I then fed into the H driver.

It was closer to what I wanted, at least; but not there yet. At 50% duty cycle, the motor is already running pretty fast for a small correction; and at 75% duty cycle, it’s perceptibly faster, but not as much so as I’d like. The real flaw is that even if this method worked, when it was nearly level, it’d oscillate between 50% forward and 50% backward. That’s a lot of action for a rig that’s already almost balanced.

I know, I know; the easy way to deal with this is to read the sensor with a PIC and set the motor behavior however I want in software. I’ll get there eventually. For now, though, I’m really hoping I can get this to work in discrete circuitry. Partly I’m interested in doing it for the experience (like building my own H-bridge board); partly I like thinking of this circuit as a low-level reflex, and doing it in software would make it feel more like a conscious action.

I’ll keep puzzling over more ways to do it in hardware–but I’m afraid it’s going to come down to inventing a linear pulse stretcher, which wasn’t on my calendar for January.

H-Bridge Motor Drivers

Sunday, January 15th, 2006

If you want to reverse the direction of a DC motor, how would you do it? One of two ways:

  1. Change the positive voltage to a negative voltage
  2. Swap the two power leads

The first method is the simplest, but requires a dual-ended power supply–two sets of batteries, or a more complex circuit to split the voltage or generate the negative voltage from the existing positive. Either way adds overhead to the power supply.

The second method turns out to be the easiest to implement in practice, although it’s a bit tricky in an all-electronic solution. If you’re using relays to control the motor, you just use a DPDT relay with an off position, wired like so:

[insert relay schematic here]

To make the motor go forward, activate the FWD coil; to make it reverse, activate the REV coil.

The trick comes when implementing this in electronics. Most electronic switches (transistors) only pass electricity in one direction, so you can’t use a single switch to change the direction of current flow. The solution is an H-bridge, a set of four power transistors arranged like the upper and lower legs of an H, with the motor wired across the middle.

[insert H-bridge schematic here]

To make the motor turn forward, activate transistors 1 and 4. To make it reverse, activate 2 and 3. To burn out your transistors and power supply, activate 1 and 2 or 3 and 4.

On my CD-bot, I built an H-bridge from scratch out of (salvaged) small-signal, bipolar transistors. I wanted to do it from the ground up once, to know that I could. I also wanted to honor the goal that everything in the bot was made from salvaged materials, and I’ve never salvaged an H-bridge (as far as I know).

[insert picture of CD-bot motor driver board and 754410]

Since then, I’ve discovered the SN754410 quad half-H driver, which I purchased from Acroname. It’s a 16-pin DIP that provides four half-H-bridges, i.e. two complete bridges. It’s a piece of cake to use; and because one input controls an entire side of the H (transistors 1 and 2 or 3 and 4 in the diagram above), you can’t short it out with a simple mistake in the control logic. It’s a wonderful chip, I’m delighted to have found it, and I wonder why it’s not mentioned more often.

How to Make a 4046 PLL Work

Friday, January 13th, 2006

Success! I have the PLL locking onto the ADXL202 now, and my LEDs indicating tilt, all thanks to Lab 4: CMOS 4046 Phase-Locked Loop from a 1997 class at UC Boulder that I found via Google. Thank you, thank you, thank you for putting your courseware online (and leaving it there, apparently indefinitely)!

The lab explained two salient points that I hadn’t seen previously:

1MΩ ≥ [ R1, R2 ] ≥ 10kΩ
100nF ≥ C1 ≥ 100pF

and

How to test each subsection of the chip independently to building a working circuit from the ground up

So here are the values I ended up using. C1 = .1μF and R2 = 100KΩ gave fmin quite a bit slower than my sensor’s 80Hz output, but that was the closest I could do with what I had in my parts bin. Likewise, R1 = 68KΩ gave fmax quite a bit faster than 80Hz, but again, it’s what I was able to do with what I had on hand. I was able to test each of these frequencies and confirm correct operation individually by connecting VCO IN to ground (fmin) and to VDD (fmax) with no SIGNAL IN, and counting hash marks on my scope.

For the low-pass filter (R3 and C2), the cutoff frequency should be much smaller than twice the frequency of the incoming signal (sounds vaguely Nyquistish, eh?), in order for VCO IN to get the average DC component of the phase comparator output. I scratched and calculated a bit, but wasn’t really enjoying it, so picked values I knew would set the cutoff far lower than 160Hz–R3 = 1MΩ and C2 = .01μF. The price of my sin of laziness is that the circuit takes a few seconds to lock onto the input signal at powerup, but I can live with that for now. And because my input signal doesn’t have a strict 50% duty cycle, I’m using the Type II (edge-triggered) phase detector.

I also connected INHIBIT to ground. I don’t know whether it was strictly necessary, but another posting recommended doing so with unused CMOS inputs. It only cost me one more jumper to ground it, and as much trouble as I’d had already, I wasn’t going to let one more little thing stand in my way. Of course, I wired the tilt sensor’s output to the 4046′s input.

And everything worked at last! As noted above, the PLL takes a couple of seconds to lock to the input signal, but once it does, it’s rock-solid every time. It’s encouraging to see that once the capture range is set properly, the 4046 really works predictably. The scope shows the signal wiggling on power-up, but then it settles down.

I also got to use the external trigger input on my scope. I was wishing for a dual-trace scope so I could trigger off the sensor signal and compare it with the PLL signal on the same screen. Can’t do that on my single-trace, but I’m doing the next best thing–using the sensor signal as an external trigger to lock the PLL signal into position. True, I won’t be able to detect very small phase differences this way; but within the resolution of my scope, it sure looks as though they’re in phase.

I wired up a 7406 and 7400 to give me the !SENSOR & PLL and !PLL & SENSOR combinations I described earlier, hooked them up to a couple of LEDs, and voila! Visible indication of the operation of my tilt sensor. A little more wiring, and I had four LEDs indicating bidirectional tilt. (Thank goodness the ADXL202 appears to use the same frequency generator for both axes’ PWM outputs, so I didn’t have to wire up another PLL for the Y axis.)

It works great! It works so well, in fact, that it demonstrates that I have the sensor positioned not quite level. And while I was fiddling with it trying to level it, I caused some intermittent connections on its contacts to its carrier. Oh well. It mostly works, and I know how to make it work, and I’m pretty happy about that.

POSTING IN PROGRESS

Solid-State Tilt Sensor with a PLL?

Thursday, January 12th, 2006

In order to show off the ADXL202 tilt sensor, I want to hook up two LEDs that brighten and dim in response to the tilt. Because the sensor is +/- 2g, my PWM duty cycle is only varying from 25% to 75%, which isn’t enough to see the variation in brightness of my LEDs. Somehow, I have to translate that into a range that varies down to near 0%.

My ultimate plan for the tilt sensor involves controlling a motor (duh), and I expect to experiment with several different drive logic configurations. Regardless of how I end up driving the motor, though, it’d be nice to have indicator LEDs to demonstrate what decisions are being made and fed to the motor–so even if I don’t need any additional circuitry for the motor drive, I’d like to get the LEDs working.

I had previously considered, and am now looking carefully, at using a phase-locked loop (PLL) to help decode the PWM signal. A PLL locks onto the input frequency and provides an output signal of the same frequency–but with 50% duty cycle. A Type II PLL is edge-triggered, so it provides an in-phase output. (A Type I PLL’s output is nominally 90 degrees out of phase for a 50% duty cycle input.)

So if I can manage to get a PLL to work, I can use it to lock onto the fixed frequency of the tilt sensor’s output, and give me a reference signal that goes high at the same time as each pulse of the sensor, but goes low at exactly half of the signal period, while the sensor’s signal is going lower earlier or later depending on its tilt. Then instead of looking at the raw sensor data with a duty cycle range of 25% to 75%, I can compare the sensor to the reference and get “left” and “right” signals with duty cycles each varying from 0% to 25%.

ADXL202 and PLL

That means the LEDs would both be dark when the device is level, instead of each varying from dark to bright over the whole range–but I can live with that. It also means the LEDs will give a very direct representation of what I need the motor to do.

So I picked up a couple of 4046 PLL chips, and I’ve been reading the datasheets. Many, many times. After three or four readings, I understood that they were really going to do what I want with their Type II phase detectors. After another three or four readings, I think I have a pretty good idea how to select external components to set the frequency capture range I need. I don’t think I’m stupid–I’ve just never worked with these before.

I’m itching to try it out.

Solid-State Tilt Sensor, Unplugged

Thursday, January 12th, 2006

Having got the ADXL202 working, I wanted to show it off, and then get it installed in a little project that I’ve had waiting in the wings. Showing it off has the side benefit of demonstrating the accuracy of my assumptions about how it works and how it interfaces, above and beyond being able to view its signal on my scope.

So this weekend, I breadboarded some LED drivers onto the sensor. I didn’t remember how much current the ADXL202 would source or sink; plus I wanted one LED to get brighter when it tilted left and another to get brighter when it tilted right. So I plucked a 7404 hex inverter out of my parts bin and wired one of the ADXL202′s outputs to a couple of inverters, then the output of one of them into a third inverter. This gave me two buffered outputs, one inverted and one non-inverted, which I wired through resistors into a couple of LEDs.

And because I wanted it to be portable so I could show it off, I left the benchtop power supply behind and strapped on a 9V battery and a 7805 voltage regulator. I cleverly soldered the black and red leads onto the wrong terminals on the battery connector, which I didn’t discover until I had covered the solder joints with nail polish (pink coral, if you’re curious) and cleverly smeared it around the breadboard when I accidentally touched the connector before it was dry.

Since the sensor’s PWM output is dramatically visible on the scope, I figured it’d be dramatically visible on the LEDs. Wrong-uh. Even knowing what was supposed to be happening, and with the LEDs’ domes carefully aligned in the same direction, in a dark room, I could just barely tell that one brightened and one dimmed as I rotated the assembly back and forth.

Feh.

Well, the ADXL202 is a +/- 2g sensor, and tilted vertically, it’s only experiencing 1g. That means my PWM duty cycle isn’t changing from 0% to 100%; it’s changing from 25% to 75%. I would still think that’d be enough to see a difference in brightness of my LEDs!, but apparently not. So I have to get smarter.

Blue LEDs

Thursday, January 12th, 2006

In December, I was inspired by a post on the Makezine blog to search for retail LED Christmas lights, as a source of cheap LEDs. I couldn’t find any at Wal-Mart, but my wife found the Phillips LED Christmas lights at Target.

I wasn’t particularly impressed with the white ones–they looked very blue to me. But the blue ones were pretty, and bright!, so I bought a string. 60 LEDs for $12 is $.20 each, which is a pretty respectable price for blue LEDs (although you can do somewhat better on eBay buying from Hong Kong). And the review linked above doesn’t recommend these as a home lighting product (as packaged, they flicker just at the edge of perception), but they work great for cannibalizing. :-)

The LEDs have their leads stuck through little plastic bases, so they clip into and out of the plastic sockets much like other miniature Christmas lights. Happily, they also slip right out of the sockets, so they’re very easy to use.

I had an old stereo receiver with a burned out backlight on the mechanical tuner, and I’ve already soldered in a blue LED (with current-limiting resistor) to replace the original incandescent. It actually looks almost violet now, and I’ll probably replace it with a green LED the next time I have an excuse to open it–but it’s cool to have it working again.

Solid-State Tilt Sensor

Thursday, January 12th, 2006

Years ago–probably about 2000, shortly after I got my first Handspring PDA–I saw an article on adding a solid-state tilt sensor to your Palm computer. I was enchanted by the idea of playing games by tilting the PDA from side to side, but even more excited about the possibilities for walking, balancing robots.

After reading about Analog Devices’ ADXL202, a micro-machined +/- 2g accelerometer with pulse-width modulated (PWM) digital output, I filled out their sample request form and received two chips in the mail. Unfortunately, I ordered the LCC (brick with leads painted onto the surface) instead of the small-form-factor surface-mount chip, thinking I’d find an LCC socket for it. Alas, I never did locate one.

I had long thought I should make some kind of daughterboard for the chip, with DIP pins on the underside to make it easier to use for prototyping. Fast-forward to 2005. After I was no longer commuting to Pittsburg, I had much greater continuity of free time between weekday evenings and weekends. I also had all my spare junk in one place. :-) I desoldered a larger LCC socket from a scrap board and cut opposing corners out of it with a razor saw, thinking I might be able to glom something together that would work, but to no avail.

Finally, late last fall, I did what any self-respecting (or was that desperate?) tinkerer would do: I soldered leads to the chip and stuck them into the top side of a machined DIP socket. It’s gross. It’s tacky. It’s done and it works.

ADXL202 carrier

The machined pins on the DIP socket fit very nicely into another DIP socket, and it works perfectly on my solderless breadboard. After assembling the carrier, I added the supporting components and a power supply, and was at last able to confirm that the device worked! I hooked it up to my scope and tilted it back and forth, enthralled by the tidy constant-period waveform with the high region changing width as I moved the board. W00T!