Bookmark and Share

Wednesday, 28 April 2010


Power house monitoring is done on the receiver part fitted with lcd.Following parameters monitored are ,high voltage,over load, no-voltage or temperature high.,these paremeters are transmitted by transmitter .audio and visual alarm comes on both the places ,alarms have to be reset from both the places.receiver will also display the alarming condition.these conditions also logged on to pc through serial port.

Friday, 23 April 2010

Autonomous Parallel Parking RC Car

RC Car

Side View of RC Car

Arjun Nagappan (asn28)

Arjun Prakash (asp36)


We created an RC Car that can identify a parking space and parallel park by itself. The RC Car drives down a street searching for a parking space to its right using a distance sensor. When the car has identified a space, the car checks to see whether that space is large enough to park in. If it determines that there is sufficient space, the car will begin parallel parking into that space. It uses information from sensors placed on the front, right, and rear of the car to direct the car into the parking space. Once the car has parked, it will remain in that position until it is reset.

High Level Design

Rationale | Logical Structure | Hardware/Software Tradeoffs


After discussing various project ideas, we eventually stumbled onto the subject of cars. So we started brainstorming possible projects related driving. When brainstorming, we saw something in the ECE lounge that reminded us of a garage. This led us to parking. Parallel parking is something that many drivers struggle with, yet there are very few tools available to help with parallel parking. Though a few auto manufacturers have developed systems that can parallel park cars autonomously, these solutions are very expensive. We thought this would be both a fun and interesting problem to tackle using an RC Car as a proxy for a real car.

Logical Structure

Our project is broken down into two major components: the control system and the move car algorithm. The move car algorithm directs the car and the control system implements the directions of the move car algorithm.

Design Structure

Figure 1: Logical Structure of High Level Design

Control System

The control system contains all the hardware and its associated software. It allows the parking and parking detection algorithms to interface with the car. The software in this module is broken up into three major sections: the Left-Right/Front-Back (LR/FB) state machines, master state machine, and distance calculations. The LR/FB state machines determines which direction to move the car based on flags set by the detect parking space and park car algorithms. Once the LR/FB state machines decides which direction to move the car, the master state machine implements this movement by sending the correct input and enable signals to the H-Bridge. The distance calculations implemented independently every millisecond.

Move Car

Move car contains the detect parking space and parallel parking algorithms. All functions in move car interface with the control module by setting movement flags. The parking space detection and parking algorithms use information from the distance sensors to set these movement flags and guide the car.

Move car works by initializing the movement flags of the car. It sets the car on a default trajectory and then calls detect parking space. Once a parking space has been detected, the parking algorithm is called. After the car has successfully parked, it idles until it is reset.

Hardware/Software Tradeoffs:

Distance Sensors

  1. When selecting infrared distance sensors there was always a tradeoff between the sensors ability to measure close range and long range. We tried to minimize this problem by using sensors designed for varying ranges.
  2. Using accurate sensors cost significant time. Every measurement from our distance sensors is approximately 40ms delayed. This affected our ability to start and stop the motors of the car at the correct times.
  3. We used integer calculations rather than floating point to calculate distances. We decided the increased accuracy would not significantly improve our ability to park the car because we cannot control the movement of the car with that degree of accuracy.
  4. Each sensor draws a maximum of 50mA. To accommodate for this, we needed to use a 5v regulator that could source up to 1A.


  1. We decided to power our car using batteries rather than using a steady power source. This gave us increased mobility but was very inconsistent in the current it supplied to the motors. As the batteries wore out, they supplied less and less current to the motors. This made calibrating the velocity of the car very difficult.
  2. In order to best utilize the mobile power resources we have, we power the motors using four AA batteries, which are stored in the battery compartment of the RC car. These batteries supply the Supply Voltage to the H-bridge, which in turn powers the motor. We use a 9V battery to power the PCB.


  1. 1. Our code requires the motor control software, parking algorithm software, and distance sensor software to run in parallel. However, this is not possible in the Atmega644. We got around this issue by making every important task a state machine. By breaking up each function into small pieces, we can execute one piece of function one, then one piece of function two, followed by one piece of function3, and then another piece of function one, etc. This enables us to emulate a multi-tasking architecture.


RC Car | H-Bridge | Distance Sensors

Hardware consists of three main components:

  • RC Car
  • H-Bridge
  • Distance Sensors

All hardware used the following color convention:

Color Connected To
Red Vss
Green Ground
Purple Input
Yellow Output
Orange Enable

Table 1: Wire Color Convention

RC Car

The first step of our hardware design involved fully understanding the mechanics our RC car. We took apart the car and rebuilt it multiple times to fully understand how it was built, what every part in the car is used for, and how those parts contribute to the control of the car.

After understanding the mechanics of the car, we decided the easiest way to control our car would be to directly control the inputs to the DC brush motors controlling the front and rear wheels, bypassing all of the car’s internal circuitry. To do this, we scoped the control signals of the car. We found that the control signals were very simple. There is one motor for the reverse and forward movement of the rear wheels and one motor to turn the front wheels left and right. These motors are controlled by a simple 5V DC input. A +5V turns the rear wheels forward and the front wheel to the left. A -5V input turns the rear wheels backwards and turns the front wheels to the right. To more easily control the motors we soldered wires to their plus and minus terminals. This allows us to easily apply a +/-5V without opening up the car again.


We use an ST Micro L298HN H-Bridge to control the motors of the RC Car. It allows us to switch between +/-5V across the motor. It also allows us to source the power from the batteries while using the processor to control the transistors in the H-Bridge. The control algorithm turns the appropriate transistors on/off, applying the proper voltage across the brush motor. The H-Bridge is connected using the following configuration:

H-Bridge Schematic

Figure 2: H-Bridge Schematic

The first H-Bridge (to the left) is used to control the front motor of the car. This motor turns the front wheels either left or right. The second H-Bridge (the the right) is used to control the rear motor, which is used for the forward and reverse functionality of the car. The inputs and enables of the H-Bridge are connected to port B.

Front Motor (Left/Right) Rear Motor (Forward/Reverse)
Pin Connected To Pin Connected To
In 1 Port B7 In 3 Port B3
In 2 Port B6 In 4 Port B2
En A Port B5 En B Port B1
Out 1 + Motor Terminal Out 3 + Motor Terminal
Out 2 - Motor Terminal Out 4 - Motor Terminal

Table 2: H-Bridge Pin Configuration

In addition configuring the H-Bridge to control the motors, we also had to protect the H-Bridge from inductive spikes caused by turning the DC brush motors on and off. We used diodes on the output to protect from these spikes. The H-Bridge was wired as follows:

H-Bridge Current Portection

Figure 3: Inductive Current Protection on H-Bridge Outputs

Distance Sensors

We used three Sharp infrared distance sensors to determine the distance between our car and nearby objects. We placed a sensor on the front, the right side, and the rear of the car. For the front and rear, we used 4-30cm sensors. For the right side, we used we used a 10-80cm sensor. We decided to use a sensor with a larger range for the side so that we could more easily detect a parking space. However, this made aligning the parking the car more difficult, so we rely more heavily on the front and rear sensors to park the car. To slightly improve the short distance range of our sensors, we placed the sensors as far back on the car as possible.

The challenge with using these sensors is that their voltage output is nonlinear (inverse function) and each sensor varies slightly. Therefore, we scoped the output of each sensor at various distance values, linearized the plot, curve fit the line, and implemented an analog to digital conversion so that we had reliable distance values.

Measurements and Linearization

Distance (cm) Front Sensor Output (V) Rear Sensor Output (V)
4 2.78 2.6
5 2.36 2.22
6 2.06 1.92
8 1.6 1.52
10 1.32 1.26
12 1.12 1.08
15 .92 .88
18 .776 .76
21 .664 .656
24 .567 .576
27 .536 .52
30 .476 .48

Table 3: Front and Rear Sensor Measurements

Front Sensor Data Front Sensor Data

Figure 4: Front Sensor Plots of Distance vs. Voltage and Distance-1 vs. Voltage

Rear Sensor Data Rear Sensor Data

Figure 5: Rear Sensor Plots of Distance vs. Voltage and Distance-1 vs. Voltage

After taking the inverse of the distance versus voltage plots, we determined it would be best to fit the curve using two linear lines rather than one. The equations of the lines are:

Front Sensor Rear Sensor
voltage=9.759*[1/distance]+0.381, >1.5V voltage=8.963*[1/distance]+0.395, >1.25V
voltage=12.738*[1/distance]+0.057, <1.5v voltage=11.806*[1/distance]+0.09, <1.25v

Table 4: Front and Rear Distance Sensor Equations

The analog to digital conversion uses a different equation depending on the value of the measure voltage. If the measured voltage is above a certain threshold, the ADC will use the equation in the top row. If it is below a certain threshold, the ADC will use the equation in the bottom row. The threshold for the front sensor is 1.5v and 1.25v for the rear sensor.

Distance (cm) Side Sensor Output (V)
10 2.28
15 1.64
20 1.28
25 1.08
30 .808
35 .728
45 .672
50 .612
55 .556
60 .516
65 .488
70 .452
75 .432
80 .42

Table 5: Side Sensor Measurements

Side Sensor Data Side Sensor Data

Figure 6: Rear Sensor Plots of Distance vs. Voltage and Distance-1 vs. Voltage

When looking at the data for the 10-80cm side sensor plot, we determined that one linear line would be sufficient to accurately capture the output voltage vs. distance characteristics of the sensor. The equation of this line is:


Analog to Digital Conversion

For the analog to digital conversion we used the built in ADC function of the MCU. Because we had three distance sensors, we had to rotate which sensor was connected to the ADC. This was simply done by changing the value of ADMUX. One of the three sensors is sampled every millisecond.

We take the value from the ADCH register and perform the appropriate calculation to convert this value to a distance. We decided to use only the ADCH register because the value represented by the bottom two bits of the ADC is on the same order of magnitude as noise. Therefore, these two bits are not important to our calculation. To do this, the ADC is left adjusted. By using the value in the ADCH register, we are using the upper eight bits of the ten ADC bits. We use the internal reference voltage of 2.56V for comparison, so our calculation is:

ADC Calculations ADC Calculations ADC Calculations ADC Calculations ADC Calculations


Control Module | Algorithm Module

The software for this project has been partitioned into 2 files based on functionality. There are 2 files, ControlModule.c and AlgorithmModule.c.

The state machines in ControlModule control the motors, and are:

  • fbStateMachine
  • lrStateMachine
  • masterStateMachine

The state machines in the AlgorithmModule use the sensor data and various algorithms to determine what should be the next movement the car must make. They assert flags which tell the ControlModule state machines to actually move the motors. The state machines in AlgorithmModule are:

  • moveCar
  • detectParking
  • parkCar

Below we have explained the various state machines we have used in our project.

Control Module



The fbStateMachine controls the motor for Forward-Backward operations. It is controlled by the isForward and isReverse flags. These flags serve as indicators as to whether the car should be traveling forward or reverse. In order to control the velocity of the forward-backward motion we anded the enable bit with a a PWM signal.


In State 0, the motor is at rest. The corresponding FB control bits are 00. When the algorithm requires the car to go forward or reverse, the corresponding flags (isForward and isReverse) are set, and the FB state machine switches states to 1 or 3 respectively.

In State 1, the motor rotates to drive the car forward. The state machine remains in this state while isForward is equal to 1. Once isForward is de-asserted, the state machine moves to a buffer state to stop the car from moving forward due to inertia.

After isForward is set to 0, leaving state 1 and stopping the motor isn’t enough. The wheels might continue to rotate due to inertia, and so a buffer state, State 2, is required. It makes the motor go in Reverse for 1 cycle (50ms) of the FB State Machine, before going back to the rest state, State 0.

If isReverse is asserted, the state machine jumps to State 3. The state machine remains in this state while isReverse is equal to 1. Once isReverse is de-asserted, the state machine moves to a buffer state to stop the car from moving in reverse due to inertia.

After State 3, a buffer state, State 4, is needed to stop the wheels from continuing to rotate in reverse due to inertia. This is a 1 cycle Forward motion, similar in function to State 2’s reverse functionality. Once done, the FB State Machine goes back to its rest state, State 0.


The fbStateMachine is called upon every 50ms. This is enough time to evaluate the flags set in the AlgorithmModule, but at the same time fast enough to make the motor motion very accurate.


The lrStateMachine() works the same way are the fbStatemachine. A forward corresponds to a left turn and a right corresponds to a reverse. The diagram for both are:

BF/LR State Machine

Figure 7: FB/LR Motor State Machine



This uses the FB and LR control bits to call the required functions in order to send the appropriate input signals to the H-Bridge and make the motors rotate in the appropriate direction.


In this function, the 2 FB and LR control bits are combined to create 4 master control bits by left shifting the FW bits by 2 and adding it to the LR bits.

fbBits = fb.controlBits; // (FB FB)
lrBits = lr.controlBits; // (LR LR)
masterBits = (fbBits<<2)>

As a result, each of the 7 car movements (stop, forward, forward-left, forward-right, reverse, reverse-left, reverse-right) have a unique masterBits combination associated with them. The master control bits are then used in the function to decide which motor control function is to be called.


This state machine is invoked in each iteration of the infinite while loop in main. In other words, it can be considered to be executing continuously and not at intervals. This is essential because parking requires a great deal of accuracy when controlling the motors. Therefore, we want to update the motors as often as possible, which would require us to call masterStateMachine as often as possible.

Algorithm Module



This is the master state machine of the algorithm module. It decides which mode the car is in, i.e., whether the car is moving forward to detect a parking spot, aligning itself once a parking spot has been detected, or actually going through the motion of parking.


Move Car State Machine

Figure 8: Move Car Motor State Machine


This is a 5 state linear state machine, as can be seen in the diagram above.

It starts off in State 0. In this state, the car is at rest. It gives enough time for all transients in the car to stabilize. Once everything is stable, it moves to State 1.

In State 1, car moves forward till it detects a parking spot. While in this state, the car invokes the detectParking state machine each time the moveCar state machine is called in the Control Module. Details of how the detectParking state machine works are explained in the next section.

Once a parking lot has been detected, the state machine moves into State 2. It remains in State 2 until the car has parked itself. The parkCar state machine is invoked for each cycle that the moveCar state machine is in State 2. Once the car has been parked by parkCar state machine, the isParked flag is asserted, and moveCar moves onto state 3.

When we reach State 3, the car parked itself. The car will eternally remain in this state hereafter, since the car has parked itself and is at rest.

In addition to serving as a state machine as described above, moveCar also makes available 2 values – rsDist and rrsDist – to its sub-state machines, detectParking and parkCar. rsDist stores the values of the side distance in the previous clock tick of the moveCar state machine, while rrsDist stores the value 2 clock cycles earlier.


The moveCar state machine is invoked every 100ms. The moveCar state machine also serves as a clock for the detectParking and parkCar state machines. When in State 1, each clock tick of the moveCar state machine serves as a clock tick for the detectParking machine. When in State 3, each clock tick of the moveCar state machine serves as a clock tick for the parkCar machine.



The function of detectParking state machine is, as its name suggests, to detect a parking space to park in. It accomplishes this by continuously polling the distance values from the side distance sensor.


Detect Parking Space State Machine

Figure 9: Detect Parking Space State Machine


detectParking is a 6 state state machine, as can be seen in the diagram above.

State 0 serves as a start-up. This is essential because the first few cycles of the detectParking take place while the side distance sensor is still calibrating itself. Once the wait state is done, the state machine enters state 1.

State 1, essentially, searches for a sudden increase in the side distance value. A sudden increase corresponds to the beginning of a parking space. It does this by checking the (sDistance – rsDist) value. If there is a sudden depression, sDistance will increase and so it’s difference from its own previous value (rsDist) will be a large number. When this does occur, the state machine goes onto State 2.

In State 2 it attempts to confirm that it indeed is detecting a valid depression, by calculating (sDistance – rrsDist). Since State 2 is invoked 1 clock tick after the depression was last detected in State 1, rrsDist will store the value of the side distance before the depression began, i.e., from 2 clock cycles earlier. If (side distance – rrsDist) is still a large number, we can confirm that a depression has been detected, and we move to State 3.

In State 3, we keep track of how long the depression is. This is done by incrementing the detect.controlBits for each state machine clock tick that we are still in the depression. When there is a sudden decrease in the value of the side distance, we move to state 4, since it signals a probable end of the parking lot.

State 4 confirms that the possible end of the parking space, as detected in State 3, is indeed the end of the space. This is done in a manner similar to the confirmation done in State 2 using the rrsDist variable.

Once a parking space has been detected by the above states, the state machine moves into State 5 wherein it checks the control Bits (which kept track of how long the parking space was by incrementing for each cock tick while in the depression) to make sure the parking space is large enough. If large enough, then the isParkingLot flag is asserted which would direct moveCar to stop and start the parking sequence.


Each tick of the detectParking state machine corresponds to a tick of the moveCar function. When moveCar is in State 1, it calls detectParking on each of its ticks. Therefore, detectParking is called every 100ms until a parking space has been located.



The function of the parkCar state machine is to park the car once a parking spot has been identified. The algorithm to park the car continuously interacts with its surroundings through the forward, side and rear sensors.


Park Car State Machine

Figure 10: Park Car State Machine

Parking Motion

Figure 11: Parking Motion of Car, colors correspond to state of the Park Car State Machine


The parkCar function tries to simulate how a human would parallel park. It is, essentially, just the following 4 motions:

  1. Reverse Right until you are inside the parking lot.
  2. Go Forward and redo 1. if the car is not aligned.
  3. Reverse Left until the car is fairly straight and close to the back wall.
  4. Forward Right until the car is straight and close to the front wall.

The above routine is accomplished using a 7 state machine.

State 0 makes the car move forward by a certain amount. The idea is to give the car enough space to move and rotate into the parking space.

State 1 simply turns the front wheels to the right. We turn the wheel before reversing the car so as to not lose turning radius by turning as the car reverses. Once the wheel is turned, the state machine moves onto state 2.

State 2 commands the car to go reverse right for a specified amount of time until the car has passed the edge of the parking space. Once past the edge of the space, it moves to state 3.

In State 3, the car continues in reverse right until it is either a certain distance from inside of the parking space, or the rear distance is close to the edge. These conditions, as can be seen from the figure above, are checks to verify that the car is deep enough inside the parking lot to be able execute the reverse left maneuver. Once the conditions are met, the car stops and the state machine moves to state 4.

NOTE: If at any point in states 1, 2 or 3 the car’s AI decides it is not in a position to go through with the parking, it will go back to State 0, and redo the whole procedure.

In State 4, the car moves reverse left. It does this until the rear of the car is close to the side wall of the parking space, which can be judged by the rear distance sensor value. Once close enough to the rear value, it stops and moves to state 5.

State 5 commands the car to go forward right. This attempts to straighten out the car completely and to align it nicely inside the spot. It goes forward right until it is close to the side wall of the parking space, as judged by the forward distance sensor. Once aligned, the car is parked and it moves to state 6.

State 6 is a 1 cycle stop before progressing back to state 0. Also, here the isParked variable is set so that the moveCar state machine can move out of parking mode to rest mode.


Each tick of the parkCar state machine corresponds to a tick of the moveCar function. When moveCar is in State 3, it calls parkCar on each of its ticks. Therefore, parkCar is called very 100ms while the car is being parked.

Misalignment Detection

Our parking algorithm is equipped with a Misalignment Detector. Its role is to judge whether the car can park itself in the given space, and if it judges that parking is impossible, to correct the car’s position to make it possible.

Our algorithm has a provision to keep track of the values of distance from the side sensor (sDIstance) from the earlier clock (rDist) and earlier 2 clock ticks (rrDist) of the state machine. Having these 2 values is extremely important to the successful working of the misalignment detector.

The detector works by checking how much sDIstance has changed over the last 2 clock cycles. If the change in sDistance is large, it means the car is not ideally positioned and it will set the park car state machine to the forward state. It will also define how long the car should remain in this state. This can be seen in the figure below:

Misalignment Detection

Figure 12: Example of Misalignment Detection

What is beautiful about this whole setup is that this exactly how a human would park the car! If the driver realizes that he is not aligned well enough, he will go forward and try again.

Putting it All Together

If you have taken a look at the high level design described earlier in the code, and read the description of the state machines in the earlier section, you have all the information you need to understand how the software of the car works.

Essentially, the AlgorithmModule state machines are what set the flags to control the movement of the car. These flags are interpreted by the ControlModule state machines, and translate it into actual motor control.

Results of Design

Speed of Execution | Accuracy | Safety and Interference | Usability

Speed of Execution

Speed wasn’t a big issue for us. All components of the software were done as state machines.

The Motor Control state machines update at ticks every 50ms. This was ample time for the state machines to compute the necessary controlBits and assert the required inputs to the H-bridge. As a result, we were able to obtain highly accurate and sensitive responses from the motors to the control code.

The Algorithm Control state machines update at ticks every 100ms. This was enough time for the state machines to compute the necessary parameters, and to assert the necessary flags for the Control Module to interpret them and translate it into motor motion.

The response of the car to its surroundings is also very fast. The sensors have a response time of 20ms, which is quick enough for them to be processed in real time.


Distance Sensors

The sensors were very accurate within their specified range. Even with integer calculations, we were able to calculate distances with a +/- 1cm accuracy. Because we could not control the movement of the car with this degree of accuracy, the accuracy of our distance sensors are sufficient.

Parking Space Detection

The sequence to detect a parking space works very accurately. In the many trials that we performed, it always detected the parking space and stopped on detection.

Parking Algorithm

The parking algorithm we have written works very well when the car is close to a set distance from the side of the parking lot. It, however, becomes less accurate when the car is placed at larger distances from the parking space.

The parking algorithm we have written works very well when the car is close to a set distance from the side of the parking lot. It, however, becomes less accurate when the car is placed at larger distances from the parking space.

Safety and Interference

There were not many safety concerns with our project. In order to minimize disturbance to other project groups, and avoid the car colliding into students, we made a separate test area in the hallway. We used this test area for all testing purposes.

Also, since the car is completely autonomous, there was no human contact required (except for turning on the car). Therefore, there wasn’t an issue of interference with the systems in the car.


In our opinion, this project has tremendous potential. With some more work on the parking algorithm, we feel that we can develop a system for the RC car to park irrespective of its orientation and distance from the parking lot. With enough research, this can be developed for real cars!

It can also be used as a learning tool for people who want to learn driving. By observing the motion of this car, students can learn how to parallel park better.

Lastly, this project could serve as a useful reference point for future projects dealing with R/C cars. The Control Module we have implemented to control the R/C car can be used universally for any 2-wheel drive R/C car.


Standards, IP, and Legal | Ethical Considerations

Overall, we feel the project met most of our expectations, as we were able to build an autonomous car which could detect a parking space, and park in it. When we started out, we intended the car to be able to locate a parking spot, and park irrespective of its distance from the parking space and its orientation. We were, however, unable to make it robust enough to accommodate parking from different orientations and distances. However, we feel the basic algorithm would remain the same, and this algorithm can be built upon to accommodate these features.

This was also a tremendous learning experience for us, especially with the hardware. We learn a tremendous amount about motor control systems, efficient circuit design, and hardware debugging. We also learned a lot about software. Through this project, we got valuable experience in developing efficient software using memory and run-time optimizations, something that cannot be gained through routine assignments.

If we had an opportunity to start this project over, there are a few things we would do differently.

  1. Use a regulator to ensure a steady current is being supplied to the batteries despite the fluctuation in voltage across the batteries, particularly as they lose power
  2. Consider implementing an optical sensor to track the velocity of the car
  3. Build a feedback PWM loop to control the velocity of the car
  4. Consider adding a fourth sensor on the side to calculate the orientation of the car
  5. Consider building the car ourselves

Standards, Intellectual Property, and Legal Concerns

There were no standards or regulations that concerned our project because we decided not to control the car using radio signals. There are also no concerns with intellectual property because we purchased the RC car and are only using it for personal use. All the software and other hardware was designed by us.

Ethical Considerations

We adhered to the IEEE Code of Ethics throughout this project. We were very careful to consider the effects of our decisions on us, those around us, and the outcome of our project. We took significant time to plan our project before implementing it. We wanted to ensure our car was designed in the best way possible, in terms of performance, reliability, and safety. We worked cooperatively with other people, seeking and providing feedback and constructive criticism from the professor, TA's, and other groups to build the best possible design.

We also set up a safe testing environment. In an area with high traffic, people could have easily stepped on the car and been hurt. We tested our car in a highly controlled environment to ensure everyone’s safety. We did not make any decisions that would cause harm to others or the environment.

In no circumstances did we give or accept bribes. All of our parts were either bought or sampled in the appropriate manner. We have been honest regarding the results and limitations of our design. We have worked hard to create the best design possible in the given time frame, and it is safe to operate. All people involved with this project were treated fairly.


Commented Code | High Level Schematic | Parts List and Cost | Tasks | References

Appendix A: Commented Code

This link contains the source code for our project: Source Code

This link contain supplementary functions we wrote during the development of our project: Supplementary Code

Appendix B: High Level Schematic

High Level Schematic

Appendix C: Parts List and Cost

Part Number Cost
RC Car 1 $20
10cm-80cm Sharp IR Sensor (GP2Y0A21YK) 1 Free (Sampled From Sharp)
4cm-30cm Sharp IR Sensor (GP2D120XJ00F) 2 Free (Sampled From Sharp)
ST Micro H-Bridge (L298HN) 1 Free (Sampled from ST Microelectronics)
ATMEGA 644 1 Free (Sampled from Empire Technologies)
Custom PC Board 1 $4
Small Solder Board 1 $2
9V Battery 1 $2
AA Battery 4 $2
Headers 65 $3.25
Regulator (LM340T5) 1 Free (In Lab)
Screws and Spacers
Free (In Lab)


Appendix D: Tasks

Both of us contributed to all parts of the project, however we spent more time working on certain things.

  • Design of Hardware: Nagappan
  • Design of Control Algorithm: Both
  • Design of Parking Algorithm: Prakash
  • Testing of Hardware: Both
  • Testing of Software: Both
  • Compiling Report and Web Site: Both

AT90LS8515 Digital Message Machine

For my final design project I decided to design and build a digital dot matrix message device. I've seen devices similar to this before and I wanted to find out if I could build one myself. The display consists of 7 LEDs in a vertical row. By moving them fast enough back and forth over each other, I can display a message which appears to be generated by a 7*n matrix of LEDs and not a single column of LEDs.

High Level Design
My first thoughts on this project focused on the most important aspect of the project which was to get the LEDs moving fast enough and refreshing often enough for the message to be perceived as a constant display with the LEDs moving. I knew the microcontroller was fast enough, and I hoped that the LEDs could turn on and off fast enough. The major hurdle I faced was how to actuate the LEDs. My first choice was a wand that oscillated back and forth. However, when the idea of creating a spinning disc was offered, I jumped on it. I could create a disc out of aluminum and mount all of my electronics on it. The device would be completely stand-alone (which is cool) and it would be easy to spin it at a fast enough rate to meet the hardware requirements. After that, it was merely a matter of writing my code to turn the lights on and off.

Hardware Design
The hardware portion of this project presented as much of a challenge as the software portion. Once I decided on using a disc to spin the LEDs, I needed to figure out how to manufacture this disc. I decided to go with aluminum, since Upson has a metal shop and my roommate is a Mechanical Engineer who could help me out with the machining. One thing that is vital to the success of this project was the ability to spin the LEDs at a fast and smooth rate. If the disc were to wobble, it would significantly degrade the performance of the display. I choose aluminum as my material since it could be machined easily and in such a way that it was precise enough to rotate smoothly.
After talking to my roommate, the guys in the machine shop and a few others, I came up with some preliminary drawings that turned out to be relatively close to the final product.

I knew I needed a way to mount the rod and disc when it was finished so I decided to use Roller Blade bearings to mount the rod. I choose and appropriate sized rod and a disc which was 3/4" thick and 6" in diameter and I was off and running. The machining took so much longer than I anticipated. This project never would have made it to fruition without the tireless help of my roommate Greg Gombert who helped me machine the disc, which I could have never done alone. The specs show the basic design for the disc. We drilled a hole down the center for mounting the disc on the rod. We attempted to machine down the disc so the thickness was much less than 3/4" everywhere but the center, but I soon realized that this would take hours, and a couple hours of machine time is close to a day real time.

After we got the hold down the center, we needed a way to attach the disc to the rod. To do this, we made two aluminum collars. We machined collars that could be attached to the rod on either side of the disc, and then made it so that the two collars attached to the disc. After that, I built a wooden stand to hold the bearings that would support the rod and I had a spinning disc on a rod. Doesn't sound like much, but it took long enough to build.

Electronic Hardware Design
The electronic hardware design for this project was relatively straightforward. The microcontroller is very easy to make stand alone, requiring power, ground and the oscillator. The LEDs were very easy to design, requiring only a 1k RPac with one end connected to Vcc and the other end of the LEDs to PortB. The Sensor used had an LED on one side and a phototransistor on the other. I mounted this on the disc 90 degrees from the LEDs. When the LEDs were at 180 degrees and the LEDs were at 90 degrees, the plane of the photodetector was broken and a signal was read on PortC[0]. This allowed me to measure the period and to use this for the timing for the rest of the design. The only other electronic components were the battery and the regulator. A 9V battery was used for a power supply and a 5V regulator provided the necessary voltage level for the rest of the circuit. A simple switch allowed me to control conductivity between the battery and the regulator.

Software Design
There were two things necessary to getting the project working.
  • Getting the right data out of PortB to the LEDs
  • Sending that data out at the right time.
The first part required me to make a rather large data table. The table was 8*n where n equaled the number of characters I had in the table. Each letter displayed was a dot matrix 7*5 representation that the LCD data sheet was nice enough to do for me (see appendix A for table.) By looking at this table, I could convert each of the 5 columns of the character into a single byte of data for the 7 LED wand. I also made a table that was 14 bytes long, each byte holding a reference number for the rastorization table. Each character was assigned a value (equivalent to the row number or byte address/8.) It was fairly straightforward to create a state machine that would access these table correctly.

The timing worked out better than I thought it would. I had a double precision variable store the time it took for each revolution and then used that value to calculate all my timing. This means that all the timing is based on the period for the previous cycle and not the current cycle, but since they are so close, it doesn't matter and is entirely sufficient for this application. A double precision variable counting 8uSec ticks allows me to measure periods up to a little over .5sec. Since the disc needs to rotate much faster than this to display a message, this is good range for the period. By shifting this value right by one bit, I have half the period and can easily determine when the LEDs move from 90 degrees to 270 degrees. So I can start displaying the message after half the period has gone by and I can shut them off when the sensor goes off. This easily took care of the first part of the timing requirement.

After I got this first part out of the way and debugged it, I got the disc to display messages. However, as the disc slowed down, the message started moving more and more left (since the number of uSec after the wand hit 270 degrees was a constant.) Also, the length of time between displaying portions of the letter was constant, so the width of the letters continually got smaller. If only I could obtain a value which would allow me to calculate the time after 270 degrees to start displaying and to calculate a value for display spacing so the message would stay in place. Wait, the period! :) I basically used the period and shifted it right or left until I got a value that was appropriate for the spacing between wand displays. I didn't have a specific timing requirement for exactly how long to wait between sending out the rastorization portions of the letters. I could get the data fast enough, it was just a matter of waiting to send it out. So I just played with the factors until I got one that looked good. If the letters were too wide, shift the variable right. If they were too narrow, shift it left.

Robotic Car Traction Control


For our ECE 4760 Final project we have developed a traction control system that detects wheel slip and adjusts the velocity of the wheels accordingly.

Robotic vehicles are becoming increasingly complex and often need high levels of movement control. Specifically, when the wheels of a vehicle begin to slip, it is optimal to adjust their speed so that the vehicle moves towards its intended direction. Applications include vehicles traveling over rough terrain, exploratory robots, and remote controlled cars. The purpose of our project is to design and implement a four wheel drive robot that monitors the rotational velocity of each wheel and limits the amount of slip when the vehicle is accelerating.

Figure 1: Front Two Traction Control Wheels

High Level Design

An electronic limited slip differential system controls the rotational velocity of the output shafts of a vehicle using speed sensors, anti-lock brakes, and microcontrollers. By electronically monitoring slipping, the microcontroller can activate the anti-lock brakes to slow down the wheel that is moving too quickly. An electronic system has the ability to be adjusted for different applications or conditions, such as on and off-road terrain, slippery weather, or driving at different speeds. This makes it much more attractive than a mechanical system. While the dynamics of modern day traction control systems are very complex, the basic idea motivated our project. The applications for this design are very practical and universal. Any vehicle with two or more wheels will benefit from greater stability and movement control with our traction control system.

The main component of our traction control system is a feedback loop that adjusts the velocity of each individual wheel to the velocity of the slowest wheel on the vehicle. It contains both positive and negative feedback by slowing down the fastest wheel motor and speeding up the slowest. A basic schematic of our system is shown in Figure 1. This block diagram is implemented four times in software for each wheel.

Figure 2: Basic Feedback Loop Structure

Background Math

Velocity and Acceleration

To calculate the velocity and acceleration from the encoders, we need to record the time between phase changes. We also need two velocity readings to estimate acceleration and will assume a constant acceleration between adjacent phases.

To calculate velocity we use the standard formula:

Notice we are sampling and using since our changes are finite. To find we start a timer at each edge and record it at the following edge. This gives us the elapsed time between known positions. Therefore our velocities are:

We can normalize distance out of our calculations since the distance traveled between each reading is constant at 1/8th a rotation.

These velocities are the average velocities over the recorded time interval and therefore if we are going to use them to calculate acceleration we must use the velocities at the midpoints of the time intervals. The acceleration is:

We found it easier to calculate acceleration directly from the time differences using the formula:

Figure 3: Sample graph of velocity calculations

Pulse Width Modulation

Pulse width modulation of a square wave of changes its duty cycle to control the amount of time a signal is high during a single period. The average value of a square wave is defined as,

Where T is the period of the square wave and f(t) is the square wave function. This function can be described as some maximum value ymax between 0 <>min for the rest of the period, D·T < style=""> Here D (duty cycle) is the fraction of the period that the square wave is at its maximum value. Substituting this into the integral above and then solving for :

All signals generated for this project have a minimum value of zero. Therefore, the average value of each PWM signal is directly proportional to its duty cycle.

Logical Structure

Figure 4: Basic Schematic of the Traction Control System

This is a basic block diagram of our traction control system. The Mega644 microcontroller was used to generate four PWM signals to be sent to the H-Bridges and to read the rotary encoder signals. Electrical connections are shown in blue and mechanical connections are shown in red. Inputs to the microcontroller are labeled as PINxn and outputs are labeled as PORTxn. OCRnx are the PWM output registers that control the motor speed. This diagram is explained in detail in the software and hardware design sections of the report.

Hardware/Software Tradeoffs

There were many trade-offs that had to be made in our design, many of which we discovered while debugging and testing. One major trade-off was the rotary encoders we used to determine wheel velocity. There are two major classes of encoders, optical and mechanical. Optical encoders offer significantly higher accuracy, can offer much faster maximum rotational speeds and most importantly for this project, must higher pulses per revolution (easily exceeding 128 ppr). The greater the pulses per revolution, the quicker the response, and/or the more accurate the velocity reading. Unfortunately these encoders are priced outside of our budget and we were forced to use a mechanical encoder with 16 pulses per rotation. This means that we would require two full rotations of the wheel to gather as much data as 1/4 revolution of a fairly common optical encoder. The additional information could help the effectiveness of a traction control system on two accounts. First we could detect a slip quicker, apply a duty cycle change, and check the effectiveness of that change in a much shorter time frame and more importantly, a much smaller wheel rotation. Or, if there are inaccuracies in our time readings (as we see with our current encoders) we could average 16 readings in 1/8 revolution with the optical and a maximum of two readings with the mechanical encoder. We can easily see the disadvantage of so few pulses in our prototype as it takes multiple revolutions to reach the desired speed.

We also encountered tradeoffs that had to be made within the design of our software. We started out designing an edge triggered interrupt to accurately detect a phase change on the encoder signal and get an accurate time reading. Since the Mega644 only has one comparator we had to combine the pulses from the four wheels onto 1 signal wire. We found a hardware solution to implement this (by XORing the previously read data points and ORing the XOR’s outputs). But this required us to allow our edge-triggered interrupt to be interrupted. Another difficulty with our edge triggered interrupt was the significant switch bounce seen on the encoders during a phase change. This problem is described in greater detail in the software section. The combination of our re-entrant interrupt and significant bounce noise required us to switch to polling the encoders. This gives us much less accurate timing, but is significantly easier to implement.

Figure 5: Design of edge triggered interrupt external hardware
(not used in final design)

Finally, we identified a tradeoff with our threshold settings. The more we allowed wheel velocity to vary, the faster the wheels would reach the target speed. This is truly a tradeoff as both results are desired. We simultaneously want fast response as well as matched wheel speeds. Of course the solution to this problem is to implement a sophisticated algorithm and feedback control. Unfortunately we did not have the time, nor the expertise required to properly characterize the system and develop the stable and efficient algorithms needed to fully utilize the system and perfect the design.


Our project was not required to follow any standards when it is under operation. It consists of a self contained system that does not transmit or receive any external data. Additionally, our robotic vehicle obeyed all speed limits and local traffic laws. When programming and debugging our software, we followed the RS-232 standards for serial data.

Existing Patents and Copyrights

The ideas used in our project were considered to be in the public domain and we did not copy any patented designs to accomplish our goals. This project was used for educational and demonstrational purposes only. At the conclusion of our project, we are not considering to pursue any copyrights or patents on our design.

Figure 6: Complete Traction Control Vehicle

Software Design

The software can be broken up into three major sections, timers, PWM signal edge detection, and wheel torque adjustments. In combination these parts are able to accurately read each wheel’s velocity and acceleration and allocate the proper amount of torque to reach and maintain a desired speed while improving traction by reducing wheel slip.

Interrupts and Timers

Due to the relatively slow servo motor maximum speed, encoder signal noise, and difficulties with edge triggered interrupts, we decided it would be sufficient to poll the rotary encoders. Therefore we maintained a counter for each wheel that was incremented in our interrupt every 0.2ms. Placing the counters in the interrupt ensures that the few hundred to roughly two thousands increments were done consistently, and any timing accuracy lost was only during the processing of these counts. For example, during our testing we underestimated the length of time to send data to Hyper Term. Before placing the counters in the interrupt we saw a very large margin of error with our elapsed time measurements as the hyperterm task influenced each increment. After moving the counters to the interrupt we only had one delay per encoder phase instead of a delay for each additional timer increment. This gave much more consistent speed measurements (although we decided to remove Hyper Term functionality all together for the final car).

Detecting Encoder Edges and Recording Data

Due to budget constraints we were forced to use the less expensive and reliably mechanical type encoder instead of the more advanced optical encoders. During our debugging process we noticed that the edges during phase transitions were very inconsistent as the switches would make and break a connection multiple times at each transition. This variability would often continue for around 1ms (see diagram).

Figure 7: Rotary Encoder Edge Noise

In order to accurately detect a single edge we implemented the debouncing technique used in the DTMF dialer lab. We found reliable edges could be detected with ten consistent readings (at 5kHz) This limits the maximum phase of the PWM signal to roughly 3ms limiting wheel speed to about 41Hz, which is still far beyond the capability of the servo motors used. After an accurate phase reading is taken, we compare the phase with the last recorded value. Only when a change occurs is an edge detected. Once an edge was detected the elapsed time counter was stored and reset. The previous datapoint was moved but not deleted. Remember that two velocities are needed to calculate acceleration (see background math section).

Deciding torque adjustments

The main purpose of a traction control system is to maintain wheel grip. In order to do this we must detect when a wheel is moving faster than the car. We use two references to control the duty cycle of the PWMs sent to the wheels. First, the car has a desired speed. In order to make calculations as simple as possible we refer everything to the inverse of velocity, which once distance is normalized out, are simply our timed pulse widths. Our desired speed is therefore recorded as a pulse width and all wheels accelerate or decelerate in order to stay within a defined margin of the desired speed. If a wheel is moving significantly slower than the desired speed, then we ensure that no wheel is moving faster than a different pre-defined margin of this slowest wheel. This process allows the car to quickly reach its desired speed without slipping.

Below is a timing diagram for our PWM signal. We programmed the TCNT1 and TCNT2 registers to count from 0 to 256. When we wanted to increase the speed of the wheel and thus the increase the duty cycle on the PWM signal, we would increment the OCRnx register by a fixed value. This was true for the inverse. When we decremented the OCRnx register, the duty cycle of the PWM would decrease. Also note that the frequency of the pulses is identical no matter the duty cycle. We used a frequency of about 31 kHz to optimize the H-bridge functionality.

Figure 8: Mega644 PWM Output Timing Diagram

Hardware Design

The hardware was designed to create a robotic car with four individually controlled servo motors using PWM signals and H-bridge circuits. The rotation of each motor was measured with a 2-bit (gray code) rotary encoder. Additionally, the acceleration of the vehicle was measured with a z-axis 1.5g acceleration sensor. A basic schematic of the hardware setup is shown below.

H-Bridge Motor Driver

The H-Bridge circuit allows the microcontroller to run a two-terminal motor without any large noise spikes feeding back into the microcontroller circuitry. When the motor is switched on and off, there is a large change in voltage in a short period of time. Since the motor can be modeled as an inductor, the big change in voltage will cause a huge spike in current, which can destroy the input terminal of the microcontroller. This is prevented by wiring diodes across four MOSFET in the configuration shown below to stop current from flowing when the MOSFET is turned off. These devices have similar properties of a switch because they can limit or amplify the flow of current depending on the voltage across the gate to body terminals.

Figure 9: H-Bridge Motor Driver Schematic

The H-Bridge came in a 8-pin SOP package with inputs for Vcc, ground, forward pulse width modulation (PWM), and reverse PWM. There were two outputs to wire across the terminals of the motor. Since there were two separate inputs for forward and reverse PWM signals, our design was utilized only the forward PWM signal to control how the vehicle moved in the forward direction.

Figure 10: Two H-Bridges on an SOIC Header

Rotary Encoder

The rotary encoders are used to resolve wheel velocity and acceleration. The encoders output a two bit binary quadrature signal, meaning they output two pulse width signals that are 90 degrees out of phase. The pulses are generated by opening and closing switches to a common ground. Therefore, in order to generate a readable signal from the encoders, we used pull-up resistors on the signal lines. Also, since the two phases were not sufficiently accurate relative to eachother, we only use 1 signal from each encoder. This cuts the number of pulses per rotation in half, but gives us a more consistent signal for accurate timing.

Figure 11: Rotary Encoder Schematic

The specific encoders we used had 16 pulses per rotation. This means that there were four periods per rotation. The repetition would be insufficient for us to determine the position of the wheel (it is ambiguous which quadrant the wheel is in) but satisfactory for determining velocity. An example signal and rotary position is shown below. Velocity is determined by timing the difference between the rising and falling edges. Similarly, acceleration can be determined by calculating the difference in velocity between two adjacent pulses. Note the acceleration between the orange phase and green phase.

Figure 12: Pulse signal from encoder with encoder position

Servo Motors

To rotate the wheels of our vehicle, we used four continuous rotation servo motors. They run on a maximum of 6 volts DC and rotate a full 0 to 180 degrees. An image of the motor is shown below. To attach the rotary encoder, we modified each motor by removing the back plate and attaching a metal rod to the back side of the rotating gear. We then used flexible clear plastic tubing to form a connection between the metal rod and the rotary encoder. A picture of the modification is shown below.

Figure 13: Servo Motor Layout

Figure 14: Servo Motor Layout


The Atmel Mega644 was used to control and monitor the acceleration and velocity of our vehicle. The major features of the Mega644 that were used for our project included one 8-bit timer, 4 PWM output pins, one Analog to Digital converter, and four standard I/O pins. The Mega644 chip was built on a prototype board provided by Bruce Land. It features an easy way to power, attach a crystal clock, connect to a RS232 interface, and program the Atmel chip. A schematic of the board can be found here.

We chose to attach the optional interface for serial communication because it provided critical debugging features and we had extra money to budget. An image of a completed prototype board is displayed below courtesy of the ECE 4760 website.

Figure 15: Sample proto-board from 476 website


In general, the end result of our traction control was a success. The vehicle was able to ramp up its velocity uniformly without any major slipping. When the vehicle reached its desired speed, the wheels maintained their velocity and generally stayed in balance with each other. In order to test that out system was working, we performed two tests. First, we placed tightly fitting rubber bands around the outside rims of the left two wheels and kept the plastic wheels on the right side unmodified. We then started up the vehicle in the hallway on hard tile flooring. As the car started up, the velocity of each wheel was maintained a constant rate and the car moved in a relatively straight path for about 2 meters.

The results of the start-up can be seen in the plot below. When the car first starts, wheel number 4, shown in turquoise, is established as the fastest wheel and wheel number 3, shown in red is the slowest wheel. Almost immediately, wheel 4 jumps up to 14 rpm and is promptly slowed to run at the same speed as the other wheels. The wheels continue to pick up speed, until they reach a programmed desired speed. It is held at this speed for a few seconds. Looking at the region between 3 and 7 seconds, wheel number 2 naturally tries to run at a speed faster than desired. This is recognized by the microcontroller and the PWM is adjusted to make the wheel run slower. The reverse is true for wheel 3 and the microcontroller sends more power to the motor to account for this.

The second test involved pushing down on a single wheel and slowing it down to a very low velocity. The system would pass this test if the other wheels recognized that they were rotating too quickly and slowed down appropriately. The results of this test are also shown in the graph below. At about 7 seconds, the second wheel is held down and its velocity drops to about 6 rpm. The response of the other wheels 1 and 3 is pretty fast and responds to the velocity change within a couple of measurement cycles. Wheel 4 was the slowest to respond to the change, taking less than 1 second. Although there is a fast response time to the velocity change, the time it takes to actually slow the other wheels to the slowest level takes a very long time. As shown in the graph, it takes well above 2 seconds for the other wheels to drop down to 10 rpm.

Figure 16: RPM vs Time for Traction Control Start-up

Figure 17: Worst Case RPM vs Time Scenario

The results of our second traction control test are shown above. At about 1 second, the 4th wheel is held down and it slows to 20 rpm. The other wheels respond in about the same manner as the first test. Overall, we can see that it takes around 3 seconds to the wheels to completely adjust to a large change in velocity. Then, at 12 seconds the wheel is released. Since wheel 4 naturally ran the fastest of all the wheels, there was a large acceleration. The system tries to respond to the situation, but it takes over 8 seconds just for the wheels to recover about ¾ of the velocity difference. This was a worst case scenario for our traction control system.



Our prototype traction control system demonstrates how a high speed microcontroller can be used to accurately control a varying and possibly unstable system. Our controller effectively throttled wheel speed when a slip was detected as well as actively controlled wheel rotation to maintain the desired speed. Although our results demonstrated the functioning of our code, we originally hoped for a faster response ideally being able to correct wheel slip within one rotation. The slow response was mainly caused by adjusting the PWM pulses by 1% each time a measurement was recorded. We sacrificed a fast responding system for a more stable one. This is always a careful balance to choose for many engineering problems. The addition of higher accuracy encoders as well as implementing a more sophisticated control algorithm would help us achieve more desirable results. Due to our implementation of a four wheel, independent drive system, our project would require some significant overhead to be integrated with other commercial vehicle stability systems such as ABS (anti-lock breaking system) and ESC (electronic stability control) systems. This again was a trade-off as integrating with the various automotive communication standards and devices would in itself be a substantial design project.

Standards and Intellectual Property

Our project did not require the use of any public or private domain software or any proprietary hardware. Although our specific implementation of a traction control system itself would not be sufficient for a patent, it does serve as a strong baseline for further development on traction control. Traction control itself is a fairly new technology and is just now becoming main-stream in consumer automobiles. There is certainly substantial opportunity for improvement to the current algorithms and systems used today, especially if the focus is moved to include performance (most traction control systems are for safety only and can negatively affect performance).


During the design of our traction control system we had to keep in mind the use of such systems and the ethical responsibilities of design. Most traction control systems are used on consumer motor vehicles as a safety system. Our system, as well as commercial grade systems, has the ability to over-ride driver control. A malfunction of this system could significantly compromise the safety of the passengers as well as others on the road. Even if the system was not used on a passenger vehicle, it is still partially or wholly responsible for the movement of a potentially dangerous object. Therefore during our design we constantly had to keep safety in mind and try to design such that failures are minimized and will not result in an out of control vehicle. This was reflected in our decision to keep the less aggressive method of throttling up wheel speed and using small accepted margins of error. This means that our model car’s acceleration was significantly less than the motors where capable of doing, but the slower accelerating vehicle would have better slip protection favoring safety over performance.