Tuesday, June 29, 2010

The tank drive RC motor driver

I started working with electronics about a year ago. Most of the things I created during that time were simple learning exercises, such as blinking a light with a PIC chip, or with a radio transmitter. Recently I completed the first working build of my first real electronics project. It is a board that interprets the signal from a radio receiver for an RC servo set and generates a corresponding motor power output, two of them actually.

First there was the development of the code, I used a PIC 18F1320. I mainly chose this chip because I had experience with it, and I knew it was just powerful enough without being excessive. Most of the time on this went into making the PWM signal interpretation code. The signal that is output by the servo for the receiver is pulse width modulated, that means it sends pulses of various lengths to the servos to indicate the desired position. For most servos the standard is that a 1 ms pulse is all the way to the left, and 2 ms is all the way to the right, 1.5 being the center. To make it as precise as possible I use the capture module on the chip so that instead of checking the ports on regular intervals, I could have it check the time when the logic level at the port changed. The problem with that is that there is only one CCP (capture, compare and pwm) module on this chip, and I wanted to capture atleast two servo signals.
Eventually I learned that most RC receivers output their signals for each servo with a given space in between, I figured I could use this gap to differentiate between them with just one pin, but that didn't work. Eventually I hooked it up to an oscilloscope and found out why: on my receiver the pulses had no space between them, furthermore if I connected any two adjacent channels to the same pin they shorted out the receiver and the whole thing shut down. Fortunately the two problems can solve each other, since the signals are stacked together, and my receiver has three channels, I can just capture the first and third, and the gap between them is the length of the second. Here's the code I came up with, it's kind of long to re-post here.
After that adding the motor PWM features was fairly easy. I added a button to calibrate the board (turn the transmitter high, press, leave it neutral, press, turn it low, press, so on for the next channel) and two lights to indicate the calibration state.

Next was designing the board, I used an L298n H-bridge chip to amplify my pwm signal to actually power the motors, and drew the whole thing up in eagle. Note the filtering diodes on the signal in, this is to keep the thing from shorting itself out, oddly it usually works without them, but not always.

After that I soldered the prototype board, to my surprise it worked in the first try. My only other practice at circuit board soldering was when I made my Junebug kit to start programming PICs. For that I just watched some youtube videos on how to solder perf boards and I got a 30W soldering iron from sears.

With that made and tested I made some adapter wires using some old lego wires of mine that had come loose. They have pins made from snapable headers at one end and lego plugs at the other, I figured a versatile testing medium for the RC controller would be legos and here is the resulting robot:

just the body

with the driver board and receiver

The next step in this project is a more solid version, I'm working on the schematic to create an actual board. I've built a gearbox, and I plan to make a solid works model for a simple frame, then fabricate it out of aluminum. It will be a bit more compact than the prototype, I've ordered some L293D chips, which are smaller than L298s and drive about half as much current (the dual gearbox uses 800ma motors), they also have built in clamp diodes which should save some space on the board.

For now I'm having fun driving the lego version around, I stuck on the wireless camera and a flashlight and drove it around from the TV like a space probe.