How to detect a certain color and actuate a servomotor with Arduino

Hello all,

I need your help regarding a project with Arduino.

What I want to do, basically, is to actuate a servo motor when a certain color, let's say blue, is detected on a given object.

The thing is, I know how work a servo, but the only program examples that I found with TCS34725 or TCS34725 are ones that basically are to mimic the color detected by the sensor, on LED or on a screen.

What I would like to do is use the color detection sensor as an interrupter:

  • IF color detected = Black
    • Servo rotates to a given angle
  • Else
    • Servo rotates to the default position

I am clueless, and I would like to have a bit of help please.

Welcome to the forum.

Do you want to "look" at the object from a distance ? Then you need a camera and run code for image processing.
If the colored object is at close range, then the TCS34725 should work: https://www.adafruit.com/product/1334. Can you explain why the TSC34725 is not suitable for your project ?

A color sensor can detect a color, but it can not detect black. How would it distinguish between dark, no object or a black object ?

Hello el_cisnecito_negro

Post your sketch, well formated, with comments and in so called code tags "</>" and a none-Fritzing schematic to see how we can help.

Do this project in steps. Learn to move the servo first, then learn to use the color sensor. There are many tutorials on line and in the Arduino libraries for both.

Once you understand how the color sensor works, very simple if statements acting on the sensor result can be used to command the servo movements.

recently using a ESP32 to detect the color of beads using a VEML6040 could detect red, black, gold and no bead

1 Like

The TCS34725 sensor measures light. To detect color you will have to bounce white light off the target object and measure the relative intensity of the various bands of reflected light. If the blue band receives more reflected light than the red or green bands, the color can be said to be 'blue'.

Hello,

Thanks for your answer, actually, the only thing that interest me, is the fact that a given color (a sticker) is detected, to activate the motor, nothing more.
Other solution would be an ultrasonic sensor, wirh a delay.
The distance is approx. 20cms.

Got it, i'll do that. I have the scheme done.

You're right, it's still a bit sketchy for me.

Thanks, looking for that

I just realised that I put the two same sensor names ...

The infamous sketch.

//*Information related to the pins of the TCS 33200 sensor
//*  Sensor Pin Vcc -> Arduino Pin 5V
//*  Sensor Pin Gnd -> Arduino Pin Gnd
//*  Sensor Pin S0 -> Arduino Pin D8
//*  Sensor Pin S1 -> Arduino Pin D7
//*  Sensor Pin S2 -> Arduino Pin D6
//*  Sensor Pin S3 -> Arduino Pin D5
//*  Sensor Pin OUT -> Arduino Pin D4

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//Import the Servo library
#include <Servo.h>

//Define the pins of the TCS 33200 sensor 
#define S0_PIN 8 
#define S1_PIN 7
#define S2_PIN 6
#define S3_PIN 5
#define OUT_PIN 4

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// create servo object to control a servo
Servo myservo;  

//RGB Values
int Red=0, Blue=0, Green=0; 

//Variable to store the servo position
int pos = 0;

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void setup() {
  
// Set the S0, S1, S2, S3 Pins as Output
  pinMode(S0_PIN, OUTPUT);
  pinMode(S1_PIN, OUTPUT);
  pinMode(S2_PIN, OUTPUT);
  pinMode(S3_PIN, OUTPUT);
  
//Set OUT_PIN as Input
  pinMode(OUT_PIN, INPUT);

// Set Pulse Width scaling to 20%
  digitalWrite(S0_PIN, HIGH);
  digitalWrite(S1_PIN, HIGH);
  
// attaches the servo on pin 9 to the servo object
myservo.attach(9);  

// Enable UART for Debugging
  Serial.begin(9600);

}+

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void GetColors()  
{    
//S2/S3 levels define which set of photodiodes we are using LOW/LOW is for RED LOW/HIGH is for Blue and HIGH/HIGH is for green 
  digitalWrite(s2, LOW);                                           
  digitalWrite(s3, LOW);  

//here we wait until "out" go LOW, we start measuring the duration and stops when "out" is HIGH again, if you have trouble with this expression check the bottom of the code                                         
  Red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);       
  delay(20);  
  digitalWrite(s3, HIGH);                  
                         
//Here we select the other color (set of photodiodes) and measure the other blue color value using the same techinque
  Blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  delay(20);  
  
//Here we select the other color (set of photodiodes) and measure the green color value using the same techinque  
  digitalWrite(s2, HIGH);  
  Green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  delay(20);  
}

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void loop() {

//Execute the GetColors function to get the value of each RGB color  
GetColors();                                     
                                                   
//Depending of the RGB values given by the sensor we can define the color and actuate the servo or not 
if (Blue<Green && Blue<Red && Blue<20) { // if Red value is the lowest one and smaller than 20 it's likely Blue   
  for (pos = 0; pos <= 90; pos +=1) {   // goes from 0 degrees to 90 degrees in steps of 1 degrees
    myservo.write(pos);                // tell servo to go to position in variable 'pos'
    delay(15);                        // waits 15ms for the servo to reach the position
    }            
  } 
else {
  for (pos = 90; pos = 0; pos -=1) { // goes from 90 degrees to 0 degrees in steps of 1 degrees  
    delay(15); 
    }                           
  }
}

Did you mean:
for (pos = 90; pos >= 0; pos -=1)
and did you forget the:
myservo.write(pos);

Yes, and yes, thanks !

But dunno if the whole works or not

//*  Information related to the pins of the TCS 33200 sensor
//*  Sensor Pin Vcc -> Arduino Pin 5V
//*  Sensor Pin Gnd -> Arduino Pin Gnd
//*  Sensor Pin S0 -> Arduino Pin D8
//*  Sensor Pin S1 -> Arduino Pin D7
//*  Sensor Pin S2 -> Arduino Pin D6
//*  Sensor Pin S3 -> Arduino Pin D5
//*  Sensor Pin OUT -> Arduino Pin D4

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// Import the Servo library
#include <Servo.h>

// Define the pins of the TCS 33200 sensor 
#define S0_PIN 8 
#define S1_PIN 7
#define S2_PIN 6
#define S3_PIN 5
#define OUT_PIN 4

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// create servo object to control a servo
Servo myservo;  

//RGB Values
int Red=0, Blue=0, Green=0; 

//Variable to store the servo position
int pos = 0;

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void setup() {
  
// Set the S0, S1, S2, S3 Pins as Output
  pinMode(S0_PIN, OUTPUT);
  pinMode(S1_PIN, OUTPUT);
  pinMode(S2_PIN, OUTPUT);
  pinMode(S3_PIN, OUTPUT);
  
// Set OUT_PIN as Input
  pinMode(OUT_PIN, INPUT);

// Set Pulse Width scaling to 20%
  digitalWrite(S0_PIN, HIGH);
  digitalWrite(S1_PIN, HIGH);
  
// Attaches the servo on pin 9 to the servo object
myservo.attach(9);  

// Enable UART for Debugging
  Serial.begin(9600);

}+

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void GetColors()  
{    
// S2/S3 levels define which set of photodiodes we are using LOW/LOW is for RED LOW/HIGH is for Blue and HIGH/HIGH is for green 
  digitalWrite(s2, LOW);                                           
  digitalWrite(s3, LOW);  

// Here we wait until "out" go LOW, we start measuring the duration and stops when "out" is HIGH again, if you have trouble with this expression check the bottom of the code                                         
  Red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);       
  delay(20);  
  digitalWrite(s3, HIGH);                  
                         
// Here we select the other color (set of photodiodes) and measure the other blue color value using the same techinque
  Blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  delay(20);  
  
// Here we select the other color (set of photodiodes) and measure the green color value using the same techinque  
  digitalWrite(s2, HIGH);  
  Green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  delay(20);  
}

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void loop() {

// Execute the GetColors function to get the value of each RGB color  
GetColors();                                     
                                                   
// Depending of the RGB values given by the sensor we can define the color and actuate the servo or not 
if (Blue<Green && Blue<Red && Blue<20) { // if Red value is the lowest one and smaller than 20 it's likely Blue   
  for (pos = 0; pos <= 90; pos +=1) {   // Goes from 0 degrees to 90 degrees in steps of 1 degrees
    myservo.write(pos);                // Tell servo to go to position in variable 'pos'
    delay(15);                        // Waits 15ms for the servo to reach the position
    }            
  } 
else {
  for (pos = 90; pos >= 0; pos -=1) { // goes from 90 degrees to 0 degrees in steps of 1 degrees  
    myservo.write(pos);                // Tell servo to go to position in variable 'pos'
    delay(15); 
    }                           
  }
}

What happens if you try it?

I would add Serial output to show the pulse values read for Red, Green and Blue. Then you can look for patterns in the data that represent a 'blue' color.

Oh tell me more please.
I don't have the hardware yet.

When you do get the hardware, put it all together, test it, and then let us know if it works.

And obviously, nothing works.

If you want any help with your project you will have to provide a lot more detail.