New library for TCS230 RGB Color Sensor

You may not need to mod the PCB. It depends on whether the manufacturer has tied the OE line to ground (to permanently enable the sensor) and whether you want to manually control the OE line. Test with a multimeter by measuring the resistance between OE and GND – zero ohms reading indicates a direct connection an potential issues.

The mod is simply to break the connection between OE and ground and leave the connection to the OE pin intact. You can do that anywhere - just trace the circuit. OR, you can just leave it as is but be careful to not trigger the OE line using software.

Hi Thanks so much for writing an awesome library..

I can get it reading colours and running the calibrate at the beginning when the sketch runs before picking colours after that.. but try as I might the colours always return super dark..

Is there something I'm missing here:

When the sketch initialises the user presses a button on this first button press I do the following:

BrushColourSensor.getRaw(&sd); //Reads the raw frequency data from the sensor
BrushColourSensor.setDarkCal(&sd); //Sets the dark baseline

Then after the next button press I'm calling
BrushColourSensor.getRaw(&sd); //Reads the raw frequency data from the sensor
BrushColourSensor.setWhiteCal(&sd); //Sets the light baseline

That gives me a chance to let the user move the sensor from a black object to a white object.

But I can't seem to work out what is off about the frequency that is causing all colours picked after that using:
BrushColourSensor.getRGB(&rgb);
Serial.print(F("\nRGB is ["));
Serial.print(rgb.value[TCS230_RGB_R]);
Serial.print(F(","));
Serial.print(rgb.value[TCS230_RGB_G]);
Serial.print(F(","));
Serial.print(rgb.value[TCS230_RGB_B]);
Serial.print(F("]"));

To then read dark.

Any assistance would be most appreciated..
Thanks

What is the application? And it is always better to post all the code as the errors are often not where you think they are, or you would have found it.

Have you tried the calibration example from the library and do you see the same problem with that code?

Hey, thx to @marco_c. Thats the best TCS2300 Lib i found so far! Rly nice work.

But i struggle a bit in combination with a Servo.

My Servo works, but after i call the .read() funktion of the library, my Servos wont do anything more.

When i delete the read command, it works...

Thats my Loop where the function is called:

And there is the funktion where the .read() is:

Do you have an Idea how i can fix it?

Regards

You should check the FreqCount library doc to see if it uses the same hardware timer as the servo library. If it does then look for alternative servo libraries that use a different timer.

Well, thx. Thats the Problem.

Since the Arduino Uno only have 1 Timer, i have to buy a Servo Driver with an on Board Timer...

Hello marco_c,

My robotics team has been trying to use your library to get accurate colour readings from the TCS3200 sensor. Basically, we've modified the ColourMatch example code (which works great BTW) to get rid of learn/match mode while conserving the calibration data:

#include <MD_TCS230.h>
#include <FreqCount.h>
#include "ColorMatch.h"

#define  READ_VAL  2

// Pin definitions
#define  S2_OUT  12
#define  S3_OUT  13
#define  OE_OUT   8    // LOW = ENABLED 
#define  OUT_OUT  5

MD_TCS230  CS(S2_OUT, S3_OUT, OE_OUT);

// Global variables
uint8_t ctIndex;
colorData rgb;


void setup() {
  //Begin serial monitor
  Serial.begin(57600);
  
  // initialise color sensor
  CS.begin();
  // Use calibration parameters from the header file
  CS.setDarkCal(&sdBlack);
  CS.setWhiteCal(&sdWhite);
}

void loop() {

  // read a value
  fsmReadValue();

  // find the matching color
  uint8_t  i = colorMatch(&rgb);

  Serial.print(F("\nClosest color is "));
  Serial.print(ct[i].name);
  
}

uint8_t fsmReadValue()
// Finite State Machine for reading a value from the sensor
// Current FSM state is passed in and returned
// Type of value being read is passed in
// Current reading stored in a global rgb buffer
{
  static  sensorData  sd;

  // start the reading process
  CS.read();

  // wait for a read to complete
  if (CS.available()){
  
  CS.getRGB(&rgb);
  Serial.print(F("\nRGB is ["));
  Serial.print(rgb.value[TCS230_RGB_R]);
  Serial.print(F(","));
  Serial.print(rgb.value[TCS230_RGB_G]);
  Serial.print(F(","));
  Serial.print(rgb.value[TCS230_RGB_B]);
  Serial.print(F("]"));
  }   
}

uint8_t colorMatch(colorData *rgb)
// Root mean square distance between the color and colors in the table.
// FOr a limited range of colors this method works ok using RGB
// We don't work out the square root or the mean as it has no effect on the 
// comparison for minimum. Square of the distance is used to ensure that 
// negative distances do not subtract from the total.
{
  int32_t   d;
  uint32_t  v, minV = 999999L;
  uint8_t   minI;

  for (uint8_t i=0; i<ARRAY_SIZE(ct); i++)
  {
    v = 0;
    for (uint8_t j=0; j<RGB_SIZE; j++)
    {
      d = ct[i].rgb.value[j] - rgb->value[j];
      v += (d * d);
    }
    if (v < minV) // new best
    {
      minV = v;
      minI = i;
    }
    if (v == 0)   // perfect match, no need to search more
      break;
  }

  return(minI);
}

Unfortunately, all the sensor reads now is black. Do you have any advice for us?

Thanks.

The FreqCount library needs the AVR timer to work. If you have other software that uses that same timer it can interfere.

Does it still work with the 'stock' examples? If so, look at what you coded does that is different and try and trace it through. Another option is to start again from a working example and change gradually, testing at each stage to make sure that it still works.

Please help me to correct the below code for color sensor. I want to add a push button program so when it is ask for the "Reading value for Black calibration and white calibration", I'll press push button and program move ahead. But data(RGB) it will read continuously. Please help me.

#include <MD_TCS230.h>
#include <FreqCount.h>
#include <LiquidCrystal.h>

#define BLACK_CAL 0
#define WHITE_CAL 1
#define READ_VAL 2

// Pin definitions
#define S2_OUT 9
#define S3_OUT 10
#define OE_OUT 13 // LOW = ENABLED

MD_TCS230 CS(S2_OUT, S3_OUT, OE_OUT);
const int rs = 8, en = 7, d4 = 6, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup()
{

Serial.begin(57600);
lcd.begin(16, 2);
lcd.setCursor(1, 0);
Serial.print(F("\n[Sensor Calibration]"));
lcd.print(F("Sensor Values"));
CS.begin();
}
char getChar()

{
while (Serial.available() == 0)
;
return(toupper(Serial.read()));
}

void clearInput()

{
while (Serial.read() != -1)
;
}

uint8_t fsmReadValue(uint8_t state, uint8_t valType, uint8_t maxReads)

{
static uint8_t selChannel;
static uint8_t readCount;
static sensorData sd;

switch(state)
{
case 0: // Prompt for the user to start
Serial.print(F("\n\nReading value for "));
switch(valType)
{
case BLACK_CAL: Serial.print(F("BLACK calibration")); break;
case WHITE_CAL: Serial.print(F("WHITE calibration")); break;
case READ_VAL: Serial.print(F("DATA")); break;
default: Serial.print(F("??")); break;
}

Serial.print(F("\nPress any key to start ..."));
state++;
break;

case 1:
getChar();
clearInput();
state++;
break;

case 2:
CS.read();
state++;
break;

case 3:
if (CS.available())
{
sensorData sd;
colorData rgb;

switch(valType)
{
case BLACK_CAL:
CS.getRaw(&sd);
CS.setDarkCal(&sd);
break;

case WHITE_CAL:
CS.getRaw(&sd);
CS.setWhiteCal(&sd);
break;

case READ_VAL:
CS.getRGB(&rgb);
Serial.println("RGB [");
lcd.setCursor(0, 1);
lcd.print("RGB [");
Serial.print(rgb.value[TCS230_RGB_R]);
lcd.print(rgb.value[TCS230_RGB_R]);
Serial.print(",");
lcd.print(",");
Serial.print(rgb.value[TCS230_RGB_G]);
lcd.print(rgb.value[TCS230_RGB_G]);
Serial.print(",");
lcd.print(",");
Serial.print(rgb.value[TCS230_RGB_B]);
lcd.print(rgb.value[TCS230_RGB_B]);
Serial.println("]");
lcd.print("]");
delay(2000);
lcd.print(" ");
//lcd.clearLine(0);
//lcd.clear();
//lcd.noDisplay();
delay(10);
lcd.setCursor(0, 1);
//lcd.display();
break;
}
state++;
}
break;

default: // reset fsm
state = 0;
break;
}

return(state);
}

void loop()
{
static uint8_t runState = 0;
static uint8_t readState = 0;

switch(runState)
{
case 0: // calibrate black
readState = fsmReadValue(readState, BLACK_CAL, 2);
if (readState == 0) runState++;
break;

case 1: // calibrate white
readState = fsmReadValue(readState, WHITE_CAL, 2);
if (readState == 0) runState++;
break;

case 2: // read color
readState = fsmReadValue(readState, READ_VAL, 1);
break;

default:
runState = 0;
}
}