Color sensor TCS34725 relay switching

Hello,
I would like to create a code based on the TCS34725 color sensor. The goal in that the sensor detects a color and switches a relay based on that. I already have the basic code running on my Arduino Uno, and can see the R,G,B values.

#include <Wire.h>
#include "Adafruit_TCS34725.h"

// Pick analog outputs, for the UNO these three work well
// use ~560  ohm resistor between Red & Blue, ~1K for green (its brighter)
#define redpin 3
#define greenpin 5
#define bluepin 6
// for a common anode LED, connect the common pin to +5V
// for common cathode, connect the common to ground

// set to false if using a common cathode LED
#define commonAnode true

// our RGB -> eye-recognized gamma color
byte gammatable[256];


Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);

void setup() {
  Serial.begin(9600);
  //Serial.println("Color View Test!");

  if (tcs.begin()) {
    //Serial.println("Found sensor");
  } else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1); // halt!
  }

  // use these three pins to drive an LED
#if defined(ARDUINO_ARCH_ESP32)
  ledcAttachPin(redpin, 1);
  ledcSetup(1, 12000, 8);
  ledcAttachPin(greenpin, 2);
  ledcSetup(2, 12000, 8);
  ledcAttachPin(bluepin, 3);
  ledcSetup(3, 12000, 8);
#else
  pinMode(redpin, OUTPUT);
  pinMode(greenpin, OUTPUT);
  pinMode(bluepin, OUTPUT);
#endif

  // thanks PhilB for this gamma table!
  // it helps convert RGB colors to what humans see
  for (int i=0; i<256; i++) {
    float x = i;
    x /= 255;
    x = pow(x, 2.5);
    x *= 255;

    if (commonAnode) {
      gammatable[i] = 255 - x;
    } else {
      gammatable[i] = x;
    }
    //Serial.println(gammatable[i]);
  }
}

// The commented out code in loop is example of getRawData with clear value.
// Processing example colorview.pde can work with this kind of data too, but It requires manual conversion to 
// [0-255] RGB value. You can still uncomments parts of colorview.pde and play with clear value.
void loop() {
  float red, green, blue;
  
  tcs.setInterrupt(false);  // turn on LED

  delay(60);  // takes 50ms to read

  tcs.getRGB(&red, &green, &blue);
  
  tcs.setInterrupt(true);  // turn off LED

  Serial.print("R:\t"); Serial.print(int(red)); 
  Serial.print("\tG:\t"); Serial.print(int(green)); 
  Serial.print("\tB:\t"); Serial.print(int(blue));

//  Serial.print("\t");
//  Serial.print((int)red, HEX); Serial.print((int)green, HEX); Serial.print((int)blue, HEX);
  Serial.print("\n");

//  uint16_t red, green, blue, clear;
//  
//  tcs.setInterrupt(false);  // turn on LED
//
//  delay(60);  // takes 50ms to read
//
//  tcs.getRawData(&red, &green, &blue, &clear);
//  
//  tcs.setInterrupt(true);  // turn off LED
//
//  Serial.print("C:\t"); Serial.print(int(clear)); 
//  Serial.print("R:\t"); Serial.print(int(red)); 
//  Serial.print("\tG:\t"); Serial.print(int(green)); 
//  Serial.print("\tB:\t"); Serial.print(int(blue));
//  Serial.println();


#if defined(ARDUINO_ARCH_ESP32)
  ledcWrite(1, gammatable[(int)red]);
  ledcWrite(2, gammatable[(int)green]);
  ledcWrite(3, gammatable[(int)blue]);
#else
  analogWrite(redpin, gammatable[(int)red]);
  analogWrite(greenpin, gammatable[(int)green]);
  analogWrite(bluepin, gammatable[(int)blue]);
#endif
}

Would you guys be willing to help me with this? I myself am having trouble figuring out how to build this.

Thanks in advance!

You will find that the RGB output, when pointing the sensor at a surface of given color, depends very strongly on the lighting conditions.

Your plan will have to take that variation into account, so it would be best to experiment for a bit, before deciding on a strategy.

Many people find the HSV (Hue Saturation Value) or HSL color systems much more convenient than RGB for this purpose.

The RGB values are nicely stable. Also the intention is to always have the same light intensity, so that is not a problem.
My question is, how do I switch 3 different relays (red,green,blue) based on RGB value from the sensor.
Thanks in advance for the help.

If statements come to mind.

if (red >= some_value) red_relay_on();

It has already succeeded, ChatGPT helped me get a good code.

#include <Wire.h>
#include <Adafruit_TCS34725.h>

#define RELAY_RED_PIN 2
#define RELAY_GREEN_PIN 3
#define RELAY_BLUE_PIN 4

Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);

uint16_t redThreshold = 500;
uint16_t greenThreshold = 300;
uint16_t blueThreshold = 300;

void setup() {
  pinMode(RELAY_RED_PIN, OUTPUT);
  pinMode(RELAY_GREEN_PIN, OUTPUT);
  pinMode(RELAY_BLUE_PIN, OUTPUT);

  digitalWrite(RELAY_RED_PIN, HIGH); // Turn off relay initially
  digitalWrite(RELAY_GREEN_PIN, HIGH); // Turn off relay initially
  digitalWrite(RELAY_BLUE_PIN, HIGH); // Turn off relay initially

  Serial.begin(9600);

  if (tcs.begin()) {
    Serial.println("Found color sensor");
  } else {
    Serial.println("Color sensor not found");
    while (1);
  }
}

void loop() {
  uint16_t r, g, b, c;

  tcs.getRawData(&r, &g, &b, &c);

  if (r > redThreshold && r > g && r > b) {
    digitalWrite(RELAY_RED_PIN, HIGH); // Turn on red relay
    digitalWrite(RELAY_GREEN_PIN, LOW); // Turn off green relay
    digitalWrite(RELAY_BLUE_PIN, LOW); // Turn off blue relay
    Serial.println("Red detected");
  } else if (g > greenThreshold && g > r && g > b) {
    digitalWrite(RELAY_GREEN_PIN, HIGH); // Turn on green relay
    digitalWrite(RELAY_RED_PIN, LOW); // Turn off red relay
    digitalWrite(RELAY_BLUE_PIN, LOW); // Turn off blue relay
    Serial.println("Green detected");
  } else if (b > blueThreshold && b > r && b > g) {
    digitalWrite(RELAY_BLUE_PIN, HIGH); // Turn on blue relay
    digitalWrite(RELAY_RED_PIN, LOW); // Turn off red relay
    digitalWrite(RELAY_GREEN_PIN, LOW); // Turn off green relay
    Serial.println("Blue detected");
  } else {
    digitalWrite(RELAY_RED_PIN, LOW); // Turn off red relay
    digitalWrite(RELAY_GREEN_PIN, LOW); // Turn off green relay
    digitalWrite(RELAY_BLUE_PIN, LOW); // Turn off blue relay
  }
  delay(100);
}

Anyway, thanks for thinking with me.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.