For our final project, we decided to enhance the controls of a Hummer RC truck. Our main objective was to demonstrate that an Atmel microcontroller together with basic hardware building blocks can replace all of the car's original circuitry. Improving the RC truck's handling involved adding analog control over steering and speed. The original construction of the car hindered this idea and forced us to resort to some mechanical engineering (mounting a servo) to resolve the problem! Overall, the project was a great deal of fun and involved a lot of tinkering with hardware (including dangerous flirtations with nearly exploding power transistors!)

High Level Design:

In order to emulate the functionality of the original RC car, we had to use 2 microcontrollers; one at the transmitter end to process user input and transmit data and one at the receiver end to pick up that data and control the car's motors. We found a cheap but reliable way of establishing wireless communication between the two microcontrollers in the form of a receiver transmitter pair by Ming Microsystems.

We wanted to run the dc motor at the rear at variable speeds. Two options were available to us: One is to switch it on and off so fast that it appears to be running at an intermediate speed. By modulating the width of the pulse to the switch we could achieve various duty cycles. The other approach is to limit the current to the motor so as to slow it down. This requires an analog input to the motor and therefore a digital-to-analog converter. We ended up trying both ways and our results are documented below.

The car's front wheels were originally driven by a magnet. By flipping its polarity, the wheels are repelled all the way to the left or right. This didn't suit our needs. The other disadvantage of the electromagnet is that it constantly draws current from the battery (~400 mA). By using a servo, power consumption is significant only during transitions of the servo arm. The mini ball bearing FMA servo we used allowed us to have three different steering angles. More steering angles were not conceivable because of the design of the axial for the front wheels of the car.

Sampling user input is straightforward. All that is required is an ADC hooked up to the two variable voltage dividers controlled by the user.

Program/Hardware details:


The receiving MCU lies at the heart of the truck's circuitry. Two capacitors are used on the voltage regulator (LM78) to stabilize the input/output voltages. Communication between the MCU's is at 1200 baud and because of noise there is a possibility that the chips can lose synchronization. The receiver could be receiving the correct code but shifted or distorted by noise. To help correct this issue the transmitter must send an initialization byte signaling that the next byte is the appropriate opcode and that the transmitter is the source of the message. The receiver waits to receive this initialization code first, de-bounces to make sure it's not random noise and then takes action on the next received opcode. The receiver uses a timeout mechanism to turn off the motors if an initialization code is not received for 500 milliseconds.

When an opcode is received the byte is parsed based on the following format:

  Right(1)/Left(0) Steering Magnitude Forward(1)/Reverse(0) Speed Magnitude
opcode: X XX X XXXX

The receiver first checks the magnitude and steering/speed directions to determine if the signal lights need to be turned on as shown below:

  Forward Reverse Magn = 0
  Right Left Magn = 0
Steering Light GREEN RED OFF

PORTA was used to drive the LEDs.

Two DAC's are used; they share the same 5-bit input from the MCU but PORTC6 (reverse) and PORTC7 (forward) control their outputs. When a forward opcode is received the forward pin is set to an input and the reverse as an output to ground, which forces the reverse input to the motor to ground. This also allows for full speed to be achieved at 5 volts by setting all other outputs to zero except for the speed direction pin (6 or 7).

In order to run the dc motor in both directions a 4-switch network driven by control signals from the mcu is needed. This circuit is called an H-Bridge. By turning on two transistors on opposite branches of the bridge, the motor is driven in different directions. Turning on two transistors on the same side will create a low resistance path between Vdd and ground and will quickly lead to a colorful display of fireworks. The motor draws anywhere between 300mA to 2A depending on the resistance encountered. In order to minimize consumption at the 9V alkaline battery powering the mcu, we resorted to using power transistors to achieve high gain. A first stage amplifier (QN3904) is needed to turn on the bases of the TIP power transistors.

To control the speed of the motor, we first envisioned using PWM as described above. The timer code was written for this setup and the result did not match out expectations. The motor either stayed on most of the time at high frequency pulses or turned on and off in a jerky motion at lower frequencies. We then decided to use a different strategy; by varying the base voltage, instead of having logical 1's and 0's, we could deprive the motor of current and slow it down. The base resistors were chosen to minimize current sourced from the mcu pins and to achieve the biggest variation in speed over the range 0-5V.

The control signal to the servo is set by doing a table lookup and adjusting the timer1 compare B register. The 1-2 millisecond pulses to control the servo are generated by timer1. On a compare B interrupt the pulse is set high and on compare A it is set low. The servo voltage source is provided from the 9.6-volt nickel battery and a different voltage regulator because of the amount of current drawn by the servo.


The transmitting MCU uses timer1 to start ADC conversions from the potentiometers. The spacing between samples is set to 500 milliseconds and the ADC sampling rate is set to 125khz. Once one conversion is done the ADC channel is switched. When both values are done they are transformed into our opcode format. Before the opcode is transmitted an initialization byte is sent.


The analog control is a big leap over what the car originally had to offer. The speeds that can be achieved range all the way from a snail's pace to a speed nearly faster than the original car. Steering control is less reliable because of the rickety front wheels. Even with the bulky breadboards, the entire assembly fits inside the spacious case and the final product has a polished look to it. Unfortunately, the same is not true for the user interface (the controller) which consists of two shabby looking potentiometers stuck in a board.

The communication between the mcu's is nearly foolproof. The receiver responds without a hitch. The redundant parity bits we use prevent the car from going off on its own when it's out of touch with the transmitter.

What Next?

One obvious thing we should have done was to beautify the user interface. The potentiometers are both hard to turn and liable to pop out of the board. A dual-axis spring centered joystick would have been a much more aesthetic alternative. The real next big thing was to add sensors to the truck! Using an ultrasonic ranger, the truck can estimate how far it is from obstacles on one or more sides and react to that based on a simple AI routine. We thought about this option when we were coming up with a project proposal but decided to defer it until we had everything else working properly. Unfortunately, by then, very little time was left for any meaningful work on that idea… Maybe that's something for the next generation of EE476 students to do!


Receiver Code
Transmitter Code



- Nikko 1/14 9.6V Hummer RC Truck
- RE-99V3/TX-99V3 Ming Microsystems Receiver/Transmitter (318Mhz)

- Two ATMEL AT90S8535 MCU's
- LM78L05 and LM340T5 5V regulators
- 4Mhz Crystal Oscillator
- FMA S200 Mini Ball Bearing Servo