LED-Following K'NEX Car Using atmega644

Introduction

In a Nutshell

Our ECE 4760 final project was a car made of K’NEX that follows a LED strip.

What We Did

For this project we made a K’NEX car that follows a path made by a LED strip. We used two phototransistors to detect the lights from the LED, while considering ambient light. The voltage generated by the phototransistors were sent to an A-to-D converter so that we could calculate the car’s relative position compared to the LED strip and decide when to turn in software. We then controlled the car by sending the appropriate signals to the motors.

Why We Did It

The initial inspiration for this project came from the movie TRON: Legacy. In the movie, there are trains called “Solar Sailers” whose destinations are directed by a beam of light. Here is an image of a solar sailer:
After some brainstorming, we came up with the idea of a car that could drive by itself by following a path of light. We thought this could be a practical and cool project. We initially envisioned the road to be made of two LED paths: one on the left and one on the right of the car. This would be like the lane markers on a road that we see today. A transportation system like this has several benefits:
For example, LEDs consume much less power than lightbulbs. Therefore, we can save power by switching to LED lit roads from regular streetlamps. We an also implement traffic systems by having multicolor LEDs. Green LEDs mean the car can go at the speed limit. Red LEDs mean the car will stop. The lights can change to yellow to make the car slow down. The lights can dynamically change so that a certain distance before and after a car is yellow. This could prevent bumper-to-bumper accidents. This system can also combat drunk driving and other traffic accidents, since the driver is no longer a human.Back to top

High Level Design

Background Math

For our project, we used an Emitter-Follower (or Common Collecter) setup for the phototransistors. We set up the circuit as shown on this page. We desired a circuit that generated an output that “moves from the low state to a high state when light is detected.” When light was not detected, we wanted the ADC to output a lower number, and a higher number when light was detected. The emitter-follower circuit will output approximately Vout=Ie*Re, where Re is the emitter resistor and Ie is the emitter current.

Logical Structure

In our project, the phototransistors sent their outputs to the ATMEL Mega644 microcontroller. The MCU then calculates which motors should move based on the phototransistors and sends a signal to the optoisolators telling which motors to turn on. Depending on which optoisolator is turned on, the motor control will tell which motor to move. We used optoisolators to separate the MCU from the motor circuitry. Optoisolators isolate the LED side of the circuit from the phototransistor side of the circuit, ideally protecting the MCU from any unknown outputs from the motor controller.

Hardware/software Tradeoffs

Snce we used K’NEX to build our car, we had to deal with an imperfect steering system. This steering system had a very limited turning angle. However, since the parts were preowned, it was free, as opposed to buying a toy car.
Another tradeoff we had to make was the LED strip color and photodetector. In our project description, we talked about how we wanted green LEDs to mean go and red LEDs to mean stop. We found that multicolor LEDs were more expensive than single color LED strips. We also had trouble finding LED strips that were sideways flexible, long, and cheap. We did not want orange LEDs, but orange LEDs were the cheapest available option. Additionally, there were phototransistors in stock that were sensitive to the dominant wavelength of the LED strip. Therefore, we chose the orange LED strip.

Patents, Copyrights, Trademarks

Hardware Design

K’NEX Car Design

We wanted to make a car out of K’NEX because we owned a lot of K’NEX that we could use for free in our project. The K’NEX car motors and motor controller came from the Cyber K’NEX Ultra 2.0 Robot Kit which goes for $350 on Amazon at the time of this report. This is because the set is no longer sold. Therefore, reproducing our project is probably not viable. Also, we customly built our K’NEX car, meaning there is no instruction set for the car. However, if one has the correct parts, it is probably possible to rebuild the car from the pictures.

Motor Circuitry

Our project used two motors, which were encased in a K’NEX fitting and were connected to a motor controller (also from K’NEX). Since the motors were from a set that had three motors, the motors are numbered on the K’NEX fitting. We used motors 2 and 3, because they are connected to the same controller (motor 1 has its own controller). The motor controller had 6-pin port which one could use to drive the motors. This is because the K’NEX set has a parent controller that sends instructions to the motor controller through these pins. We experimented with low voltages to see how we could interact with the pins to make the motors turn. The following diagram shows the pin diagram of the motor controller:
The following table maps the motor control pins to their function:

Motor Cotroller Pin #

Voltage Required (V)

Function

1

Unknown

Unknown

2

3

Turn Motor 3 Clockwise

3

3

Turn Motor 3 Counter-Clockwise

4

Ground

5

3

Turn Motor 2 Counter-clockwise

6

3

Turn Motor 2 Clockwise

To tell if a motor is spinning clockwise or counter-clockwise, we put the wire on the left side and position the motor casing so that we can read the number on it.
Our initial tests found that Pin 1 is ground, and a voltage of -1.5V was required on Pin 4 for the motors to turn in the opposite direction. However, when we raised the pin voltages to 3, we found that we did not need Pin 1 to drive the motors. Thus, we left Pin 1 empty, since we were able to control the motors fine using only pins 2-6.
The circuitry for the motor control is in the appendix. We measured the resistance of the motor controllers and it turned out to be around 47kOhms. To be safe, we used an optoisolator (4N35) to separate the microcontroller from the motor controller. We used 330Ohm resistors in series with the input of the optoisolator to prevent the microcontroller side of the circuit from shorting when the internal LED was on. The actual resistor values were 331Ohms, 328Ohms, 326Ohms, and 324Ohms. We drove the optoisolators from Port B0 to B3 on the microcontroller. If we put an active high on the port, the motor would spin.
On the motor control side of the optoisolator, we connected the collecter to a 3V battery source and the emitter of each optoisolator to the motor control pin. We did not bias the base, because the light from the internal LED was enough to drive the optoisolator.
Motor 2 controls the front steering wheels and motor 3 controls the back driving wheels.

Sensor Circuitry

The circuitry for the phototransistor is in the appendix. We got two phototransistors that were sensitive around the 615nm wavelength our LED strip was emitting. We used an emitter-follower setup to amplify the current that was produed by the phototransistor when it was turned on. The datasheet stated that the current when turned off was around 0.5 microAmps at most, and when turned on, would range between 0.25 to 0.6mA at Vce=5V. Since our MCU Vcc is 5V, we could simply use the numbers from the datasheet. The ADC reference voltage was set to 2.56V, so we had to find a resistor that was between 4266.6 to 10240 Ohms. We tried a resistor of 10kOhms, which worked well so we decided to stick with it. The actual resistor values were 10.2kOhms and 9.86kOhms. We connected the output of the emitter-followers to Port A0 and A1 so that we can use the ADC on the MCU.

Microcontroller

Since our project was a car, we could not use the STK500 for our final design. Therefore, we built the cutom PC board, which can be seen here. However, we left out the MAX233 and RS232 because we did not need a serial interface on our final board. This posed some difficulties in debugging in the later phases, but saved money, since our final design did not need a serial interface.
We used an ATMEL Mega644 with a 16MHz crystal because this is what we used throughout the semester. Although we probably could have used a less-powerful MCU, we decided to stick with what we knew best.
For the project, we used ports A0 and A1 for analog inputs from the phototransistor circuit. We used ports B0 to B3 to control the motors, and port D2 to control the test LED on the custom PC board.

Test track

We made our test track using the LED strip and some cardboard boxes we had lying around in our dorm. We flattened the cardboard and put the LED strip in the center. To make sure that we can still configure the track in different paths, we only tied down one end of the LED strip. This side was attached to a 9V battery. Even though the LED strip required a 12V source, 9V was enough to light the LEDs, so we used one 9V battery.Back to top

Software Design

Our software consisted of test components and the final design. We started off with code to turn the motors after we figured out how the K’NEX motors worked. This test code spun the two motors in two different directions. We used PORT B to do this, since PORT A was reserved for the ADC necessary for the phototransistors. We used C macros to keep track of which port was assigned to which motor/direction.
Once we got the motors working, we switched over to the phototransistors. After we got the hardware prepared, we put one output of the phototransistor into PORT A0 and the other into PORT A1. We initiallized the ADC like we did in lab 3 for the trimpot controller (Lab 3). To test if the phototransistors worked, we used uart.c and uart.h to communicate with PuTTY. We printed out the ADC output from one phototransistor, and then the other. Since the conversions take time, we found that in order to do two conversions, we needed to wait several cycles between reading and starting the conversions. Therefore, we created a task adc() which runs every 10ms to read one output (so it takes 20ms to read both). This was more than enough time to read the outputs and since our car was not very fast, we did not ned to sample the phototransistors any faster.
One thing we needed to take care of was to make sure the ADC did not respond to ambient light. Since the phototransistors were underneath the car, ambient light did not pose a large problem. Underneath our car, the phototransistors only outputted between 3 and 10 when the LED was turned off. When the lights were turned on, it detected between 3 and 230, depending on where the LED strip was. If the phototransistor was only detecting 3, it meant that the LED strip went out of the phototransistor’s detection range (which falls after around >30 degrees). To kill ambient noise, we set a threshold so that if the output of the ADC was less than the threshold, the software did nothing with the motors. This threshold was set to 20, since it was signifcantly greater than 10 and it worked well.
The greatest challenge was putting the two parts of our hardware together in software. First, we made a simple test program that would spin only one motor in only one direction. By doing so, we were able to test whether or not the phototransistors and the motors were still working properly. This test was important, because we decided not to add a USB connection to our custom PC board to save money. Thus, once our hardware was soldered together and placed on the car, we could no longer communicate through PuTTY for easier debugging.

While testing our car, we noticed that the motors did not have enough power from the batteries to spin two motors at a time. To get around this, we made our software such that only one motor could spin at any given time. We first checked if the value in Ain0 or Ain1 were greater than the ambient light threshold. We then took the difference of the two outputs. If the difference was between right_bound and left_bound, then the LED strip was centered with the car. Therefore, we drove the back wheels to go forward. If the difference was greater than right_bound, then we made the car turn its front wheels right. If the difference was less than left_bound, we made the car turn its front wheels left. To make sure the steering motor did not keep spinning (since this would cause our car to break) we limited how long the motor was allowed to spin by using a counter. If the steering motor spun for its limit, we made the car drive the back wheels again. We tried spinning both the steering motor and the driving motors at the same time but it did not work. We also tried alternating between steering and driving, but this failed as well.