Car That Follows Color

by wridzer in Circuits > Arduino

99 Views, 4 Favorites, 0 Comments

Car That Follows Color

If This Than That

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

IMG_20210803_131505.jpg
ITTT.png
IMG_20210808_132536.jpg

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

IMG_20210808_132516.jpg

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 8
int 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 read
digitalWrite(S2,LOW);
digitalWrite(S3,LOW);
// Reading the output frequency
frequency = pulseIn(sensorOut, LOW);
// Printing the value on the serial monitor
Serial.print("R= ");//printing name
Serial.print(frequency);//printing RED color frequency
Serial.print(" ");
delay(100);
// Setting Green filtered photodiodes to be read
digitalWrite(S2,HIGH);
digitalWrite(S3,HIGH);
// Reading the output frequency
frequency = pulseIn(sensorOut, LOW);
// Printing the value on the serial monitor
Serial.print("G= ");//printing name
Serial.print(frequency);//printing RED color frequency
Serial.print(" ");
delay(100);
// Setting Blue filtered photodiodes to be read
digitalWrite(S2,LOW);
digitalWrite(S3,HIGH);
// Reading the output frequency
frequency = pulseIn(sensorOut, LOW);
// Printing the value on the serial monitor
Serial.print("B= ");//printing name
Serial.print(frequency);//printing RED color frequency
Serial.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>

Downloads

Step 4: Make It Beautiful!

IMG-20210804-WA0013.jpg
IMG_20210803_203035.jpg