Car That Follows Color
Hello everyone!
I'd like to show this school project I've made, I hope some people will find it fun and interesting!
It's a car that drives around on a specific colour and it can find roads this way. I've had lots of troubles and failed attempts along the way so I hope this guide will help others with their own projects.
The idea came to me when I thought it would be fun to have a robot car give a tour, in the end I don't think that the car is right for that but I'm still proud of how it turned out!
Supplies
1x Arduino Uno
1x TCS230 TCS3200 Color Sensor
1x L298N Motor Driver
1x 9V battery
1x Servo
1x DC Jack with battery holder
2x DC motor with wheel
15x Jumper wire
Some lose wire
Step 1: Connect the Modules
Colorsensor
Connect the colorsensor by connecting the ground and VCC (I suggest using a breadboard to test it out before soldering). Then connect S0, S1, S2, S3 and SensorOut to pins 4 to 8.
L298n motor driver
Connect the motor driver by connecting the ground and the 12V to the power (do not use 5V it does not work for some reason). Then connect IN1-4 to pins 9-12. lastly connect the motors to the driver.
Servo
Connect the servo to the ground and power and the input to pin 13.
Step 2: Calibrate Colorsensor
The colorsensor needs to be calibrated to give correct values, note that even though correctly calibrated it will not be 100% accurate.
To learn about the colorsensor I used this tutorial. The code needed to to calibrate I got from this tutorial. I suggest you visit it if you want to know more about the colorsensor.
/* Arduino Color Sensing Tutorial** by Dejan Nedelkovski, www.HowToMechatronics.com**/#define S0 4#define S1 5#define S2 6#define S3 7#define sensorOut 8int frequency = 0;void setup() {pinMode(S0, OUTPUT);pinMode(S1, OUTPUT);pinMode(S2, OUTPUT);pinMode(S3, OUTPUT);pinMode(sensorOut, INPUT);// Setting frequency-scaling to 20%digitalWrite(S0,HIGH);digitalWrite(S1,LOW);Serial.begin(9600);}void loop() {// Setting red filtered photodiodes to be readdigitalWrite(S2,LOW);digitalWrite(S3,LOW);// Reading the output frequencyfrequency = pulseIn(sensorOut, LOW);// Printing the value on the serial monitorSerial.print("R= ");//printing nameSerial.print(frequency);//printing RED color frequencySerial.print(" ");delay(100);// Setting Green filtered photodiodes to be readdigitalWrite(S2,HIGH);digitalWrite(S3,HIGH);// Reading the output frequencyfrequency = pulseIn(sensorOut, LOW);// Printing the value on the serial monitorSerial.print("G= ");//printing nameSerial.print(frequency);//printing RED color frequencySerial.print(" ");delay(100);// Setting Blue filtered photodiodes to be readdigitalWrite(S2,LOW);digitalWrite(S3,HIGH);// Reading the output frequencyfrequency = pulseIn(sensorOut, LOW);// Printing the value on the serial monitorSerial.print("B= ");//printing nameSerial.print(frequency);//printing RED color frequencySerial.println(" ");delay(100);}
When you uploaded the code to your Arduino you can open the serial monitor and see all kinds of values. In my experience the colorsensor works better with low light and about 5cm from the surface.
For the calibration you first need to hold something white under the sensor, I suggest just using blank paper. Look at the serial monitor and take note of all the lowest values for each colour.
Then hold something black under the sensor, preferably a piece of black paper. This time you should take note of all the highest values.
link: http://howtomechatronics.com/tutorials/arduino/arduino-color-sensing-tutorial-tcs230-tcs3200-color-sensor/
Downloads
Step 3: Upload Code
Now it is time to upload the code. I made the code from various tutorials that I have followed. I did my best on commenting the different functions so it is readable for you.
Before you upload the code to your Arduino there is just one thing you need to do. Near the top of the code file there are calibration values, and as you might have guessed, that is where you have to put the values you wrote down earlier.
Then it should all work!
#include <Servo.h> // Servo Servo myservo; // Define color sensor pins #define S0 4 #define S1 5 #define S2 6 #define S3 7 #define sensorOut 8 // Calibration Values int redMin = 114; // Red minimum value int redMax = 275; // Red maximum value int greenMin = 250; // Green minimum value int greenMax = 320; // Green maximum value int blueMin = 192; // Blue minimum value int blueMax = 242; // Blue maximum value // Variables for Color Pulse Width Measurements int redPW = 0; int greenPW = 0; int bluePW = 0; // Variables for final Color values int redValue; int greenValue; int blueValue; // For motors int leftMotorForward = 9; int leftMotorBackward = 10; int rightMotorForward = 11; int rightMotorBackward = 12; void setup() { // Set S0 - S3 as outputs pinMode(S0, OUTPUT); pinMode(S1, OUTPUT); pinMode(S2, OUTPUT); pinMode(S3, OUTPUT); // Set Sensor output as input pinMode(sensorOut, INPUT); // Set Frequency scaling to 20% digitalWrite(S0,HIGH); digitalWrite(S1,LOW); // Servo assign myservo.attach(13); myservo.write(90); // Setup Serial Monitor Serial.begin(9600); } void loop() { ColorCheck(); Serial.print(ColorCheck()); if(ColorCheck()) { Forward(); } if(!ColorCheck()) { Brake(); Search(); delay(2000); } } bool ColorCheck() { // Read Red value redPW = getRedPW(); // Map to value from 0-255 redValue = map(redPW, redMin,redMax,255,0); // Delay to stabilize sensor delay(100); // Read Green value greenPW = getGreenPW(); // Map to value from 0-255 greenValue = map(greenPW, greenMin,greenMax,255,0); // Delay to stabilize sensor delay(100); // Read Blue value bluePW = getBluePW(); // Map to value from 0-255 blueValue = map(bluePW, blueMin,blueMax,255,0); // Delay to stabilize sensor delay(100); // Print output to Serial Monitor Serial.print("Red = "); Serial.print(redValue); Serial.print(" - Green = "); Serial.print(greenValue); Serial.print(" - Blue = "); Serial.println(blueValue); // Check if color is green and returns if (greenValue > redValue && greenValue > blueValue) { return true; } else { return false; } } // Function to read Red Pulse Widths int getRedPW() { // Set sensor to read Red only digitalWrite(S2,LOW); digitalWrite(S3,LOW); // Define integer to represent Pulse Width int PW; // Read the output Pulse Width PW = pulseIn(sensorOut, LOW); // Return the value return PW; } // Function to read Green Pulse Widths int getGreenPW() { // Set sensor to read Green only digitalWrite(S2,HIGH); digitalWrite(S3,HIGH); // Define integer to represent Pulse Width int PW; // Read the output Pulse Width PW = pulseIn(sensorOut, LOW); // Return the value return PW; } // Function to read Blue Pulse Widths int getBluePW() { // Set sensor to read Blue only digitalWrite(S2,LOW); digitalWrite(S3,HIGH); // Define integer to represent Pulse Width int PW; // Read the output Pulse Width PW = pulseIn(sensorOut, LOW); // Return the value return PW; } // Function to search line is lost void Search() { Brake(); bool goRight = LookRight(); delay(1000); if (goRight) { Right(); ColorCheck; while (!ColorCheck) { Right(); ColorCheck; } } if (!goRight) { bool goLeft = LookLeft(); delay(1000); if (goLeft) { Left(); ColorCheck; while (!ColorCheck) { Left(); ColorCheck; } } } } bool LookLeft() { int pos; for (pos = 90; pos < 180; pos += 10) { myservo.write(pos); ColorCheck(); if (ColorCheck()) { myservo.write(90); return true; } delay(15); } return false; } bool LookRight() { int pos; for (pos = 90; pos >= 1; pos -= 10) { myservo.write(pos); ColorCheck(); if (ColorCheck()) { myservo.write(90); return true; } delay(15); } return false; } // Function to move the car forward void Forward() { digitalWrite(leftMotorForward, HIGH); digitalWrite(rightMotorForward, HIGH); delay(500); digitalWrite(leftMotorForward, LOW); digitalWrite(rightMotorForward, LOW); } // Function to turn the car left void Left() { digitalWrite(leftMotorForward, LOW); digitalWrite(rightMotorForward, HIGH); delay(500); digitalWrite(leftMotorForward, LOW); digitalWrite(rightMotorForward, LOW); } //function to turn the car right void Right() { digitalWrite(leftMotorForward, HIGH); digitalWrite(rightMotorForward, LOW); delay(500); digitalWrite(leftMotorForward, LOW); digitalWrite(rightMotorForward, LOW); } // Function to move the car in reverse void Reverse() { digitalWrite(leftMotorBackward, HIGH); digitalWrite(rightMotorBackward, HIGH); } // Function to make the car stop void Brake() { digitalWrite(leftMotorForward, LOW); digitalWrite(rightMotorForward, LOW); }<br>