Pages: [1] 2   Go Down
Author Topic: New library for TCS230 RGB Color Sensor  (Read 3289 times)
0 Members and 1 Guest are viewing this topic.
Sydney, Australia
Offline Offline
Edison Member
*
Karma: 27
Posts: 1180
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The TCS230 is a color light-to-frequency converter on single CMOS integrated circuit. The output is a square wave(50% duty cycle) with frequency directly proportional to light intensity (irradiance). The full-scale output frequency can be scaled by one of three preset values via two control input pins. Output enable (OE) places the output in the high-impedance state for multiple-unit sharing of a icrocontroller input.

I recently acquired one of these sensors and was surprised at not being able to find a good library, and explanation for how to use the sensor, so I wrote one. The library is available at http://arduinocode.codeplex.com/ (the link in my signature below). This library has a dependency on the FreqCount library for frequency counting (included in the download).

Library example code includes:
* Simple blcking read from the sensor
* Simple RGB non-blocking read
* Example incorporating sensor calibration
* Color learning and matching   

As usual an questions, comments and suggestions for improvement are welcome.
« Last Edit: November 22, 2013, 09:05:12 pm by marco_c » Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12428
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Thanks for sharing! you're good in libs! Well done,

Some small remarks to think over

Code:
typedef struct
{
uint32_t value[RGB_SIZE]; // Raw data from the sensor
} color32;

typedef struct
{
uint8_t value[RGB_SIZE]; // the evaluated colour data (RGB value 0-255 or other)
} color8;

Code:
void setEnable(bool t); // enable the device (using OE or frequency)
=>
void enable();
void disable();

Choose better names for some variables,
keeps the code more readable / maintainable
and you can remove comments as code becomes self documenting

e.g.
Code:
uint8_t _OutputEnable;
uint8_t _FreqScaler0, _FreqScaler1;
color32 _DarkCalibration;
color32 _WhiteBalance;
color32 _currentRaw;
color8 _currectRGB;
   also for the function prototypes
   
   MD_TCS230(... uint8_t freqScaler0, uint8_t freqScaler1, uint8_t outputEnable);

   
Have a look at error handling and return values. It is only slightly more code and adds real value
   
Code:
bool MD_TCS230::setFilter(uint8_t f)
// set the sensor color filter
{
if ((_S2 == NO_PIN) || (_S3 == NO_PIN))
return false;

DUMPS("\nsetFilter ");
switch (f)
{
case TCS230_RGB_R: DUMPS("R"); digitalWrite(_S2, LOW); digitalWrite(_S3, LOW); break;
case TCS230_RGB_G: DUMPS("G"); digitalWrite(_S2, HIGH); digitalWrite(_S3, HIGH); break;
case TCS230_RGB_B: DUMPS("B"); digitalWrite(_S2, LOW); digitalWrite(_S3, HIGH); break;
case TCS230_RGB_X: DUMPS("X"); digitalWrite(_S2, HIGH); digitalWrite(_S3, LOW); break;
default: DUMPS("setFilter error"); Serial.println(f, DEC); return false; break;   
}
return true;
}

or

Code:
bool MD_TCS230::setSampling(uint8_t t)
// set sampling rate divisor for frequency counter
{
if (t > 0)
{
   _readDiv =  t;
   return true;
   }
return false;
}

or

Code:
bool MD_TCS230::setDarkCal(sensorData *d)
// set dark calibration data for rgb calculations
{
if (d == NULL)
return false;

DUMPS("\nsetDarkCal");
for (uint8_t i=0; i<RGB_SIZE; i++)
{
DUMP(" ", d->value[i]);
_Fd.value[i] = d->value[i];
}
return true;
}

BTW I like your consequent debugging style!
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 27
Posts: 1180
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey Rob! Nice to hear from you again smiley

Quote
Have a look at error handling and return values. It is only slightly more code and adds real value
Good point. I'll check what makes sense for the lib.

Of interest to me- did you notice that there was a pdf file that expained the theory of how to convert a reading from the sensor to a valid RGB value? Same folder as the libraries. Most of the nomenclature for the library comes from there for consistency with the algebra behind the code. Also a lot of the variable names are directly related to the pins of the sensor and what is printed on the breakout boards, which I thought would make it easier for users to relate the library to the hardware.

This next one is interesting and one I have thought about for some time and I would welcome yours and others thoughts:
Quote
void    setEnable(bool t);       // enable the device (using OE or frequency)
=>
void enable();
void disable();

I have used objects that split out methods for every little property (like the trivial enable/disable here) and I have found that I then have to handle calling different functions in my code somehow, like
Code:
if (condition)
  object.enable()
else
  object.disable()
when in fact I could have used
Code:
object.enablefunction(condition);
which I think is shorter, clearer and more 'data driven' rather than code intensive.

Similary for libraries where there are many options to set, I would tend to think in terms of object.setoption(option, value) rather than a slew of .option1(), .option2(), etc. Is there any specific advantage to splitting out the functions that I don't understand? Clearly my style can be easily converted to be more wordy by implementing wrapper functions.
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12428
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK,
you have good args for your choices made. Keeping in sync with the datasheet is - at least for private parts - a good idea. For the public part you are on another abstraction level so more readable makes sense there. A library can hide the internals of the datasheet


Code:
if (condition)
  object.enable();
else
  object.disable();
-->
object.enablefunction(condition);

This makes perfect sense if the condition evaluates to true, but less (imho) when you want to disable() when the condition is true

Code:
if (condition)
  object.disable();
else
  object.enable();
-->
object.enablefunction(condition == false);    // looks a bit strange
object.enablefunction(!condition);               // risk of missing the !

most conditions are easy to rewrite to their negate version, so I think your args make more sense.



I often have code like this
Code:
if (condition)
{
  object.enable();
  ... other code
}

....  lines of other code

if (condition2)
{
  object.disable();
  ... other code
}
-->
object.enablefunction(condition);
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Belgium
Offline Offline
Sr. Member
****
Karma: 1
Posts: 278
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, I've tried your library but it does not seem to work with the board that I have. This is myTCS230 board (bought it on Ebay) http://www.bajdi.com/?attachment_id=940
I've connected OE to pin 8, S2 to pin 12, S3 to pin 13 and connected 5V and GND. I then tried the example calibrate sketch but I only get [0,0,0] values. The other sketches also don't work for me. The blocking sketch only gives 0 all the time, the non blocking sketch give [255,255,255] not matter what I hold in front of the sensor.
Logged


Sydney, Australia
Offline Offline
Edison Member
*
Karma: 27
Posts: 1180
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Did you connect OUT to pin 5? The Freqcount library counts frequency on that pin.

You also need to decide how to set s0 and s1. I would suggest you set them for 100% output (both 5v from memory)

Edit: your sensor looks like mine. It needs to be modified as explained in the PDF file that is in the library folder with the .cpp file if you want to use the OE line for control.
« Last Edit: February 25, 2013, 08:21:04 pm by marco_c » Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Belgium
Offline Offline
Sr. Member
****
Karma: 1
Posts: 278
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Oops I hadn't seen the pdf file  smiley-red I've just read it and cut the trace on my board. It was connected to ground just like yours. I've just uploaded the calibrate sketch and it works. Thanks for making the library and writing the pdf file. Not many libraries are that well documented  smiley
Logged


Sydney, Australia
Offline Offline
Edison Member
*
Karma: 27
Posts: 1180
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

No problems. I hope you have fun with the sensor. It actually works quite well if the calibration is right.
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I just want to say thank you for the library.
I'm new with Arduino and for my first project I'm making a color sorter machine with the TCS230.


Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hello

nice job, but i get a timer 2 error

In file included from C:\arduino-1.0.5\libraries\FreqCount\FreqCount.cpp:27:
C:\arduino-1.0.5\libraries\FreqCount\/util/timers.h: In function 'void timer_shutdown()':
C:\arduino-1.0.5\libraries\FreqCount\/util/timers.h:453: error: 'TCCR2B' was not declared in this scope

and can't solve it...using arduino uno

zhx in advance
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 27
Posts: 1180
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I have not had this problem reported before and I don't get it when I compile my version of the same thing.

Can you compile the test programs that come with the library files?

From the paths it seems like you have installed the 'user' libraries in the Arduino libraries folder. It probably makes no difference, but the recommended location for user libraries is in a libraries folder in your sketchbook folder. This makes it easier to upgrade as this location does not change between upgrades of the Arduino IDE/compiler software. It is also worth a try to see if moving it fixes your problem.

You have not included the rest of your code (ie, the whole sketch). A lot of the time the problems are not where the errors are coming from. Without the entire context it is hard to offer advice about what could be going wrong.
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hello,
I am so new at Arduino and I got one TCS230. exactly this one https://www.kartalotomasyon.com.tr/modules/catalog/products/pr_01_10006_max.jpg . I downloaded your library now trying to get some results but couldnt get anything on screen. Can you tell me the pic connections with arduino and TCS230 please?
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 27
Posts: 1180
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You can connect the sensor to any pin as long as you tell the library which one is which when you create the object - please read the documentation PDF that comes with the library.

The one exception is the frequency reading pin. From the header file:

Quote
  This library has a dependency on the FreqCount library for frequency counting. FreqCount library is available at  http://www.pjrc.com/teensy/td_libs_FreqCount.html
   
  ** IMPORTANT NOTE**
  FreqCount imposes a limitation that the frequency can only be counted on specific pins and limits the use of other pins as   follows:
  Board       Input Pin Pins Unusable with analogWrite()
  ----------- --------- -------------------------------- 
  Arduino Uno      5      3, 9, 10, 11
  Arduino 2009    5      3, 9, 10, 11
  Arduino Mega    47    9, 10, 44, 45, 46
  Sanguino            1      12, 13, 14, 15
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks very much for the library, it's working nicely for me. Is it possible to turn off the LEDs through a command or shall I just have VCC across a transistor so I can turn the chip on and off as required? For my application the readings will be taken in near dark conditions and the LEDs are dazzling.

Secondly, it is mentioned that you connect the output to 5 but I don't think it's clearly specified in the code. Anyone should be able to figure it out by reading the documentation a bit more carefully but I would have had your library going practically instantly if I had known this.

Thanks very much for your work though, I am very happy with it!  smiley
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 27
Posts: 1180
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You need to turn Vcc off. The problem will be that it turns the sensor off as well, so the chip will need to be reinitialised when power is applied. You may be able to modify the sensor so the LEDs are being powered separately from the chip.

I understand your comment on pin 5, but that is only true for the Uno and related Arduino. As per my previous post, the pin will change depending on the type of Arduino being used.
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Pages: [1] 2   Go Up
Jump to: