Color Sensing Robot
Feb 2024
GOAL: Use a color sensor to autonomously navigate a maze by following a specific color line
SKILLS: CAD (OnShape), python programming, data collection, data processing, motor control, autonomous adjustment, wiring, low cost prototyping, laser cutting, use of single board computer (Raspberry Pi), design, collaboration
Summary
This robot uses 2 DFRobot color sensors to follow curved colored lines. It is designed to look like the standard kart in Mario Kart. You start by inputting what path of colors you want the robot to follow and the directions it needs to go (eg [red, blue, black, green] and [R, L, L, end]). Then, once you run the program, the robot should autonomously traverse this path.
To achieve this, one sensor goes directly over the line, while a second sensor is placed to over the white space to the left of the line. This configuration allows us to get enough data to accomplish the basic functionalities that the robot may need such as detecting when it veers off the life in either direction, when the current line intersects, when it has reached the end, etc. These basic cases are described below in the "Cases" section.
We also attempted to implement error-based proportional control; this method is able to know how much of a color is being detected by the sensor, resulting in more efficient navigation. The "Adding Error" Section will elaborate on the error-based method.
Video
Wiring
Cases (no error)
Path Curves Left:
right sensor detects white, left sensor detects the current color.
Path Curves Right:
both detect white
Intersection
In the images below, the robot is on the redline and is set to switch to the blue line.
1) both sensors detect the next color in the given array of colors, knows that the next direction is a right turn --> adjust until facing forward along next color
2) right sensor detects current color, left sensor detects next color, knows that the next direction is a right turn --> adjust until facing forward along next color
3) right sensor detects current color, left sensor detects next color, knows that the next direction is a left turn --> adjust until facing forward along next color
1) both sensors detect the next color in the given array of colors, knows that the next direction is a left turn --> adjust until facing forward along blue
Black line (finish line)
In the image below, the robot has arrived on the red line
1) if the next direction is 'end' then the robot just wants to stop --> stop the motors and end the program
2) both sensors detect black (the next color in the array is black) and the next direction is R, adjust until the left sensor is facing along the black line and continue forward until the right sensor detects the next color in the array. Then, adjust until the robot is facing along the new line with the right sensor over the line.
3) if the next direction was left when the robot arrives at black, follow similar steps but follow the black line with the right sensor and detect the next line with the left sensor.
Code

Color Detection Code
The two main functions that allow us to get useable color values from the sensors are DetectColor(s2,s3,sig) and ReadColor(color_vals,N).
DetectColor(s2,s3,sig)
DetectColor first sets the s2 and s3 GPIO pins to whatever combination is necessary for red, green, or blue, depending on which it wants to detect. Then, it counts how long it takes to detect a given number ( set as cycles = 10) of falling edges. Then cycles is divided by duration; this is effectively the frequency of the light since it is number of events/time. In order to get rid of noise in our data, we add the value into an array and take a weighted moving average of the last 5 data points, with the more recent data weighted more heavily. This ensures that one funky data point won't cause major issues. DetectColor does this for the red, green, and blue values and returns the weighted averages into an array.
ReadColor(color_vals,N)
ReadColor decides what the color is based on the values from DetectColor. It goes through each color and checks if the current RGB values are withing the range of that color. If the values are within a specific color's range, the function returns that color.
Adding Error
Our method for determining the degree to which the sensor is detecting a color involves finding the error between the current RBG values and the desired RBG values for the current color, then taking the difference between the right and left sensor to determine what direction the robot should be turning.
the Error(color_vals,RAvg,BAvg,GAvg,S) function takes the absolute value of the difference between the current values of R, G, and B, and the desired values for the color that the robot should be sensing. It then sums the R, G, and B values and returns that value. The Error function is called for both the right and left sensor.
At the end of the main motor control while loop, the current error is saved in a previous error variable, so that the it can be compared to the new error in the next loop. By subtracting the previous error from the current error, we can know whether the error is increasing or decreasing, and therefore whether the robot needs to turn right or left.
Cases (with error)
1) When the robot is centered, the error for the right sensor is zero and the forward function is called
2) When the robot drifts to the right of the line, the left sensor error relative to the ideal blue values decreases as more blue is detected, and the right sensor error relative ot blue increases as less blue is detected. The turn left function is called and the right sensor error multiplied by the gain constant is passed in as the speed to set the right motor to
3) When the robot drifted to the left of the line, the right sensor error obviously increases because there is less blue. Something we found out while testing the basic code was that the left sensor detects different values when it is over white depending on which color line it is next to because the colored tape reflects onto the white paper around it. So, as it drifts away, the error will actually increase even though it is still over white. The right turn function is called and the scaled right sensor error is passed in as the speed.
We had some wiring problems toward the end and were not able to test all the colors, so the code is unfinished, but it did work during trials for blue. I will add the code in once it has been polished up a bit.
CAD
Fabrication
We wanted the car to look like the standard Mario cart, so we used cardboard and duct tape for the front and side pieces to keep the pieces light and also achieve a shiny appearance. The back thrusters and steering wheel were 3D printed. The front wheels are 3D printed wheels from a previous project with yellow duct tape added on to match the back lego wheels and the yellow on the wheels of the actual kart. The chassis body and the supports for the cardboard are laser cut birch wood.
Challenges
GPIO errors
batteries dying
wires unplugging
lighting changes
needed to recalibrate the sensor
needing to design a solid setup in order to even get values that we could use to decide how we would design our program
Things to adjust in the future:
finish testing and implementing the intersection and return on different line functions
implement the ability to change speed based on the line color
implement derivative and integral control