Go Down

Topic: Color Scanner using TAOS TCS230 (Read 1 time) previous topic - next topic

Gee63

Hi, I've been playing around with a TAOS TCS230 light to frequency converter. My aim is to scan various light sources and determine their RGB value.

I've been through the tutorial on http://roamingdrone.wordpress.com/2008/11/13/arduino-and-the-taos-tsl230r-light-sensor-getting-started/ which gives you a funky little lux meter. But i need to break down each color sensor and give me the RGB equivelents.

I came across some code on a Japanese site for 0012 which might do exactly what i need but can't get it to compile in 0017. Until i can get it to compile i won't know if it serves my purpose. So any help would be greatly appreciated even if its scrap this code and go back to trying to rework Roaming Drones code  ;)

CCP
Code: [Select]
#include "WConstants.h"
#include "ColorSensor.h"

#define COLOR_SENSOR_MAX_FREQ                  (600000)
#define COLOR_SENSOR_MIN_FREQ                  (5)
#define COLOR_SENSOR_MEASURE_TIMEOUT      (100000)
#define COLOR_SENSOR_ADJUST_SAMPLES            (8)

ColorSensor::ColorSensor(uint8_t pinOUT,uint8_t pinS2,uint8_t pinS3)
{
     _pinOUT = pinOUT;
     _pinS2      = pinS2;
     _pinS3      = pinS3;
     
     _colorReference = ColorSensor::COLOR_REF_RAW;
     
     _rFreq  = 0;
     _gFreq  = 0;
     _bFreq  = 0;
     
     _rfreqRange.max = COLOR_SENSOR_MAX_FREQ;
     _rfreqRange.min = COLOR_SENSOR_MIN_FREQ;
     
     _gfreqRange.max = COLOR_SENSOR_MAX_FREQ;
     _gfreqRange.min = COLOR_SENSOR_MIN_FREQ;
     
     _bfreqRange.max = COLOR_SENSOR_MAX_FREQ;
     _bfreqRange.min = COLOR_SENSOR_MIN_FREQ;
     
     pinMode(_pinOUT,INPUT);
     pinMode(_pinS2, OUTPUT);
     pinMode(_pinS3, OUTPUT);
     
     digitalWrite(_pinS2, LOW);
     digitalWrite(_pinS3, LOW);
}

ColorSensor::~ColorSensor()
{
}

uint32_t ColorSensor::measureSquareWaveWidth(uint8_t pin)
{
//       uint8_t bit = digitalPinToBitMask(pin);
//       volatile uint8_t *reg = portInputRegister(digitalPinToPort(pin));
     
//       uint32_t width = 0;
//       uint32_t numloops = 0;
//       uint32_t maxloops = microsecondsToClockCycles(COLOR_SENSOR_MEASURE_TIMEOUT) / 16;
     
//       stateMask = (*reg & bit);
//       while ((*reg & bit) == stateMask)
//             if (numloops++ == maxloops)
//                   return 0;
     
//       while ((*reg & bit) != stateMask)
//             width++;
     
//       return clockCyclesToMicroseconds(width * 10 + 16);
     uint32_t duration = pulseIn(pin, !digitalRead(pin), COLOR_SENSOR_MEASURE_TIMEOUT);
     return (duration ? duration : COLOR_SENSOR_MEASURE_TIMEOUT);
}

void ColorSensor::colorReference(uint8_t cref)
{
     _colorReference = cref;
}

void ColorSensor::adjustWhite(void)
{
     int i;
     uint32_t r_average = 0;
     uint32_t g_average = 0;
     uint32_t b_average = 0;
     
     for(i=0;i<COLOR_SENSOR_ADJUST_SAMPLES;i++){
           measureColor();
           r_average += _rFreq;
           g_average += _gFreq;
           b_average += _bFreq;
     }
     
     r_average /= COLOR_SENSOR_ADJUST_SAMPLES;
     _rfreqRange.max = (r_average > _rfreqRange.min) ? r_average : _rfreqRange.max;
     
     g_average /= COLOR_SENSOR_ADJUST_SAMPLES;
     _gfreqRange.max = (g_average > _gfreqRange.min) ? g_average : _gfreqRange.max;
     
     b_average /= COLOR_SENSOR_ADJUST_SAMPLES;
     _bfreqRange.max = (b_average > _bfreqRange.min) ? b_average : _bfreqRange.max;
}

void ColorSensor::adjustBlack(void)
{
     int i;
     uint32_t r_average = 0;
     uint32_t g_average = 0;
     uint32_t b_average = 0;
     
     for(i=0;i<COLOR_SENSOR_ADJUST_SAMPLES;i++){
           measureColor();
           r_average += _rFreq;
           g_average += _gFreq;
           b_average += _bFreq;
     }
     
     r_average /= COLOR_SENSOR_ADJUST_SAMPLES;
     _rfreqRange.min = (r_average < _rfreqRange.max) ? r_average : _rfreqRange.min;
     
     g_average /= COLOR_SENSOR_ADJUST_SAMPLES;
     _gfreqRange.min = (g_average < _gfreqRange.max) ? g_average : _gfreqRange.min;
     
     b_average /= COLOR_SENSOR_ADJUST_SAMPLES;
     _bfreqRange.min = (b_average < _bfreqRange.max) ? b_average : _bfreqRange.min;
}

void ColorSensor::measureColor(void)
{
     // measure red freq
     digitalWrite(_pinS2, LOW);
     digitalWrite(_pinS3, LOW);
     _rFreq = 1000000UL / 2UL / ColorSensor::measureSquareWaveWidth(_pinOUT);
     
     // measure blue freq
     digitalWrite(_pinS3, HIGH);
     _bFreq = 1000000UL / 2UL / ColorSensor::measureSquareWaveWidth(_pinOUT);
     
     // measure green freq
     digitalWrite(_pinS2, HIGH);
     _gFreq = 1000000UL / 2UL / ColorSensor::measureSquareWaveWidth(_pinOUT);
}

uint32_t ColorSensor::redValue(void)
{
     if(_colorReference != ColorSensor::COLOR_REF_RAW){
           return ((constrain(_rFreq,_rfreqRange.min,_rfreqRange.max) - _rfreqRange.min) << 10) / (_rfreqRange.max - _rfreqRange.min);
     }
     return _rFreq;
}

uint32_t ColorSensor::greenValue(void)
{
     if(_colorReference != ColorSensor::COLOR_REF_RAW){
           return ((constrain(_gFreq,_gfreqRange.min,_gfreqRange.max) - _gfreqRange.min) << 10) / (_gfreqRange.max - _gfreqRange.min);
     }
     return _gFreq;
}

uint32_t ColorSensor::blueValue(void)
{
     if(_colorReference != ColorSensor::COLOR_REF_RAW){
           return ((constrain(_bFreq,_bfreqRange.min,_bfreqRange.max) - _bfreqRange.min) << 10) / (_bfreqRange.max - _bfreqRange.min);
     }
     return _bFreq;
}


H
Code: [Select]
#ifndef ColorSensor_h
#define ColorSensor_h

#include <inttypes.h>

class ColorSensor
{
     uint8_t _pinOUT;
     uint8_t _pinS2;
     uint8_t _pinS3;
     
     uint8_t _colorReference;
     
     uint32_t _rFreq;
     uint32_t _gFreq;
     uint32_t _bFreq;
     
     struct _freq_range {
           uint32_t min;
           uint32_t max;
     };
     
     struct _freq_range _rfreqRange;
     struct _freq_range _gfreqRange;
     struct _freq_range _bfreqRange;
     
     static uint32_t measureSquareWaveWidth(uint8_t pin);
     
public:
     ColorSensor(uint8_t pinOUT,uint8_t pinS2,uint8_t pinS3);
     ~ColorSensor();
     
     enum {
           COLOR_REF_RAW,                  // 100Hz - 600,000Hz
           COLOR_REF_MANUAL,            // 0 - 1023
           COLOR_REF_WEAK_LIGHT,      // 0 - 1023
           COLOR_REF_STRONG_LIGHT,      // 0 - 1023
           COLOR_REF_REFLECTED_LIGHT_NEAR,            // 0 - 1023
           COLOR_REF_REFLECTED_LIGHT_FAR,            // 0 - 1023
     };
     
     void colorReference(uint8_t cref);
     void adjustWhite(void);
     void adjustBlack(void);
     void measureColor(void);
     
     uint32_t redValue(void);
     uint32_t greenValue(void);
     uint32_t blueValue(void);
};

#endif


Error Code
c:/documents and settings/graeme/my documents/arduino-0017/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected unqualified-id before 'int'

c:/documents and settings/graeme/my documents/arduino-0017/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected `)' before 'int'

c:/documents and settings/graeme/my documents/arduino-0017/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected `)' before 'int'


cr0sh

This may help you:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1242095532

I am suspecting things about the "uint#_t" types - that they aren't defined for some reason (you are bringing in WConstants.h though)...

Hmm...
I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

cr0sh

Try including "WProgram.h" as well as "WConstants.h"...
I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

Gee63

Hey Crosh, I tried it before (and just again for good luck) to no avail  :(
even tried #undef int
but still no good

Thanks for jumping in on this, its greatly appreciated

dakudiv

I have developed a TAOS TCS230 low cost evaluation board for Embedded For You magazine on Atmega8.
It is available on website as color analyzer project (CAN-10)
m planning to release the code soon.
cheers  ;)


Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy