GROVE i2c color sensor Library. based on https://github.com/Seeed-Studio/Grove_I2C_Color_Sensor_TCS3472

Dependents:   PROJ 2PA2S 2PA2S_v2 2PA2S-interrupteur

Files at this revision

API Documentation at this revision

Comitter:
sgrsn
Date:
Fri Aug 31 05:32:03 2018 +0000
Commit message:
First Commit

Changed in this revision

Adafruit_TCS34725.cpp Show annotated file Show diff for this revision Revisions of this file
Adafruit_TCS34725.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 1bf53b314b01 Adafruit_TCS34725.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_TCS34725.cpp	Fri Aug 31 05:32:03 2018 +0000
@@ -0,0 +1,258 @@
+#include "Adafruit_TCS34725.h"
+
+/*example*****************************************************************
+
+#include "mbed.h"
+#include "Adafruit_TCS34725.h"
+
+#define commonAnode true
+
+I2C i2c(p28, p27);
+Adafruit_TCS34725 tcs = Adafruit_TCS34725(&i2c, TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);
+
+int main()
+{
+    char gammatable[256];
+    if (tcs.begin())
+    {
+        printf("Found sensor");
+    }
+    else
+    {
+        printf("No TCS34725 found ... check your connections");
+        while (1); // halt!
+    }
+    for (int i=0; i<256; i++)
+    {
+        float x = i;
+        x /= 255;
+        x = pow((double)x, 2.5);
+        x *= 255;
+        if (commonAnode)
+        {
+            gammatable[i] = 255 - x;
+        }
+        else
+        {
+            gammatable[i] = x;      
+        }
+        printf("%d\r\n", gammatable[i]);
+    }
+    while(1)
+    {
+        uint16_t clear, red, green, blue;
+        tcs.setInterrupt(false);      // turn on LED
+        tcs.getRawData(&red, &green, &blue, &clear);
+        tcs.setInterrupt(true);  // turn off LED
+        printf("%d, %d, %d, %d\r\n", clear, red, green, blue);
+        // Figure out some basic hex code for visualization
+        uint32_t sum = clear;
+        float r, g, b;
+        r = red; r /= sum;
+        g = green; g /= sum;
+        b = blue; b /= sum;
+        r *= 256; g *= 256; b *= 256;
+    }
+}
+
+
+*************************************************************************/
+
+void Adafruit_TCS34725::write8 (uint8_t reg, uint32_t value)
+{
+    char data[2] = {TCS34725_COMMAND_BIT | reg, value & 0xFF};
+    _i2c->write(TCS34725_ADDRESS, data, 2);
+}
+
+uint8_t Adafruit_TCS34725::read8(uint8_t reg)
+{
+    char data[2] = {TCS34725_COMMAND_BIT | reg, 0};
+    char r_data = 0;
+    _i2c->write(TCS34725_ADDRESS, data, 1);
+    _i2c->read(TCS34725_ADDRESS, &r_data, 1);
+    
+    return r_data;
+}
+
+uint16_t Adafruit_TCS34725::read16(uint8_t reg)
+{
+    uint16_t x; uint16_t t;
+    char data[2] = {TCS34725_COMMAND_BIT | reg, 0};
+    char r_data[2] = {};
+    _i2c->write(TCS34725_ADDRESS, data, 1);
+    _i2c->read(TCS34725_ADDRESS, r_data, 2);
+    t = r_data[0];
+    x = r_data[1];
+    x <<= 8;
+    x |= t;
+    return x;
+}
+
+void Adafruit_TCS34725::enable(void)
+{
+    write8(TCS34725_ENABLE, TCS34725_ENABLE_PON);
+    wait_ms(3);
+    write8(TCS34725_ENABLE, TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN);  
+}
+
+void Adafruit_TCS34725::disable(void)
+{
+    /* Turn the device off to save power */
+    uint8_t reg = 0;
+    reg = read8(TCS34725_ENABLE);
+    write8(TCS34725_ENABLE, reg & ~(TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN));
+}
+
+Adafruit_TCS34725::Adafruit_TCS34725(I2C *i2c, tcs34725IntegrationTime_t it, tcs34725Gain_t gain) 
+{
+    _i2c = i2c;
+    _tcs34725Initialised = false;
+    _tcs34725IntegrationTime = it;
+    _tcs34725Gain = gain;
+}
+
+bool Adafruit_TCS34725::begin(void) 
+{
+    /* Make sure we're actually connected */
+    uint8_t x = read8(TCS34725_ID);
+    //Serial.println(x, HEX);
+    if (x != 0x44)
+    {
+        return false;
+    }
+    _tcs34725Initialised = true;
+    
+    /* Set default integration time and gain */
+    setIntegrationTime(_tcs34725IntegrationTime);
+    setGain(_tcs34725Gain);
+    
+    /* Note: by default, the device is in power down mode on bootup */
+    enable();
+    
+    return true;
+}
+
+void Adafruit_TCS34725::setIntegrationTime(tcs34725IntegrationTime_t it)
+{
+    if (!_tcs34725Initialised) begin();
+    
+    /* Update the timing register */
+    write8(TCS34725_ATIME, it);
+    
+    /* Update value placeholders */
+    _tcs34725IntegrationTime = it;
+}
+
+void Adafruit_TCS34725::setGain(tcs34725Gain_t gain)
+{
+    if (!_tcs34725Initialised) begin();
+    
+    /* Update the timing register */
+    write8(TCS34725_CONTROL, gain);
+    
+    /* Update value placeholders */
+    _tcs34725Gain = gain;
+}
+
+void Adafruit_TCS34725::getRawData (uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c)
+{
+    if (!_tcs34725Initialised) begin();
+    
+    *c = read16(TCS34725_CDATAL);
+    *r = read16(TCS34725_RDATAL);
+    *g = read16(TCS34725_GDATAL);
+    *b = read16(TCS34725_BDATAL);
+  
+    /* Set a delay for the integration time */
+    switch (_tcs34725IntegrationTime)
+    {
+        case TCS34725_INTEGRATIONTIME_2_4MS:
+            wait_ms(3);
+            break;
+        case TCS34725_INTEGRATIONTIME_24MS:
+            wait_ms(24);
+            break;
+        case TCS34725_INTEGRATIONTIME_50MS:
+            wait_ms(50);
+            break;
+        case TCS34725_INTEGRATIONTIME_101MS:
+            wait_ms(101);
+            break;
+        case TCS34725_INTEGRATIONTIME_154MS:
+            wait_ms(154);
+            break;
+        case TCS34725_INTEGRATIONTIME_700MS:
+            wait_ms(700);
+            break;
+    }
+}
+
+uint16_t Adafruit_TCS34725::calculateColorTemperature(uint16_t r, uint16_t g, uint16_t b)
+{
+    float X, Y, Z;      /* RGB to XYZ correlation      */
+    float xc, yc;       /* Chromaticity co-ordinates   */
+    float n;            /* McCamy's formula            */
+    float cct;
+    
+    /* 1. Map RGB values to their XYZ counterparts.    */
+    /* Based on 6500K fluorescent, 3000K fluorescent   */
+    /* and 60W incandescent values for a wide range.   */
+    /* Note: Y = Illuminance or lux                    */
+    X = (-0.14282F * r) + (1.54924F * g) + (-0.95641F * b);
+    Y = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b);
+    Z = (-0.68202F * r) + (0.77073F * g) + ( 0.56332F * b);
+
+    /* 2. Calculate the chromaticity co-ordinates      */
+    xc = (X) / (X + Y + Z);
+    yc = (Y) / (X + Y + Z);
+    
+    /* 3. Use McCamy's formula to determine the CCT    */
+    n = (xc - 0.3320F) / (0.1858F - yc);
+    
+    /* Calculate the final CCT */
+    cct = (449.0F * powf(n, 3)) + (3525.0F * powf(n, 2)) + (6823.3F * n) + 5520.33F;
+    
+    /* Return the results in degrees Kelvin */
+    return (uint16_t)cct;
+}
+
+uint16_t Adafruit_TCS34725::calculateLux(uint16_t r, uint16_t g, uint16_t b)
+{
+    float illuminance;
+    
+    /* This only uses RGB ... how can we integrate clear or calculate lux */
+    /* based exclusively on clear since this might be more reliable?      */
+    illuminance = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b);
+    
+    return (uint16_t)illuminance;
+}
+
+
+void Adafruit_TCS34725::setInterrupt(bool i)
+{
+    uint8_t r = read8(TCS34725_ENABLE);
+    if (i)
+    {
+        r |= TCS34725_ENABLE_AIEN;
+    }
+    else
+    {
+        r &= ~TCS34725_ENABLE_AIEN;
+    }
+    write8(TCS34725_ENABLE, r);
+}
+
+void Adafruit_TCS34725::clearInterrupt(void)
+{
+    char data[2] = {0x66, 0};
+    _i2c->write(TCS34725_ADDRESS, data, 1);
+}
+
+
+void Adafruit_TCS34725::setIntLimits(uint16_t low, uint16_t high)
+{
+    write8(0x04, low & 0xFF);
+    write8(0x05, low >> 8);
+    write8(0x06, high & 0xFF);
+    write8(0x07, high >> 8);
+}
diff -r 000000000000 -r 1bf53b314b01 Adafruit_TCS34725.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_TCS34725.h	Fri Aug 31 05:32:03 2018 +0000
@@ -0,0 +1,140 @@
+/**************************************************************************/
+/*! 
+    @file     Adafruit_TCS34725.h
+    @author   KTOWN (Adafruit Industries)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, Adafruit Industries
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#ifndef Adafruit_TCS34725_H_
+#define Adafruit_TCS34725_H_
+
+#include "mbed.h"
+
+#define TCS34725_ADDRESS          (0x29<<1)
+
+#define TCS34725_COMMAND_BIT      (0x80)
+
+#define TCS34725_ENABLE           (0x00)
+#define TCS34725_ENABLE_AIEN      (0x10)    /* RGBC Interrupt Enable */
+#define TCS34725_ENABLE_WEN       (0x08)    /* Wait enable - Writing 1 activates the wait timer */
+#define TCS34725_ENABLE_AEN       (0x02)    /* RGBC Enable - Writing 1 actives the ADC, 0 disables it */
+#define TCS34725_ENABLE_PON       (0x01)    /* Power on - Writing 1 activates the internal oscillator, 0 disables it */
+#define TCS34725_ATIME            (0x01)    /* Integration time */
+#define TCS34725_WTIME            (0x03)    /* Wait time (if TCS34725_ENABLE_WEN is asserted) */
+#define TCS34725_WTIME_2_4MS      (0xFF)    /* WLONG0 = 2.4ms   WLONG1 = 0.029s */
+#define TCS34725_WTIME_204MS      (0xAB)    /* WLONG0 = 204ms   WLONG1 = 2.45s  */
+#define TCS34725_WTIME_614MS      (0x00)    /* WLONG0 = 614ms   WLONG1 = 7.4s   */
+#define TCS34725_AILTL            (0x04)    /* Clear channel lower interrupt threshold */
+#define TCS34725_AILTH            (0x05)
+#define TCS34725_AIHTL            (0x06)    /* Clear channel upper interrupt threshold */
+#define TCS34725_AIHTH            (0x07)
+#define TCS34725_PERS             (0x0C)    /* Persistence register - basic SW filtering mechanism for interrupts */
+#define TCS34725_PERS_NONE        (0b0000)  /* Every RGBC cycle generates an interrupt                                */
+#define TCS34725_PERS_1_CYCLE     (0b0001)  /* 1 clean channel value outside threshold range generates an interrupt   */
+#define TCS34725_PERS_2_CYCLE     (0b0010)  /* 2 clean channel values outside threshold range generates an interrupt  */
+#define TCS34725_PERS_3_CYCLE     (0b0011)  /* 3 clean channel values outside threshold range generates an interrupt  */
+#define TCS34725_PERS_5_CYCLE     (0b0100)  /* 5 clean channel values outside threshold range generates an interrupt  */
+#define TCS34725_PERS_10_CYCLE    (0b0101)  /* 10 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_15_CYCLE    (0b0110)  /* 15 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_20_CYCLE    (0b0111)  /* 20 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_25_CYCLE    (0b1000)  /* 25 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_30_CYCLE    (0b1001)  /* 30 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_35_CYCLE    (0b1010)  /* 35 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_40_CYCLE    (0b1011)  /* 40 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_45_CYCLE    (0b1100)  /* 45 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_50_CYCLE    (0b1101)  /* 50 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_55_CYCLE    (0b1110)  /* 55 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_PERS_60_CYCLE    (0b1111)  /* 60 clean channel values outside threshold range generates an interrupt */
+#define TCS34725_CONFIG           (0x0D)
+#define TCS34725_CONFIG_WLONG     (0x02)    /* Choose between short and long (12x) wait times via TCS34725_WTIME */
+#define TCS34725_CONTROL          (0x0F)    /* Set the gain level for the sensor */
+#define TCS34725_ID               (0x12)    /* 0x44 = TCS34721/TCS34725, 0x4D = TCS34723/TCS34727 */
+#define TCS34725_STATUS           (0x13)
+#define TCS34725_STATUS_AINT      (0x10)    /* RGBC Clean channel interrupt */
+#define TCS34725_STATUS_AVALID    (0x01)    /* Indicates that the RGBC channels have completed an integration cycle */
+#define TCS34725_CDATAL           (0x14)    /* Clear channel data */
+#define TCS34725_CDATAH           (0x15)
+#define TCS34725_RDATAL           (0x16)    /* Red channel data */
+#define TCS34725_RDATAH           (0x17)
+#define TCS34725_GDATAL           (0x18)    /* Green channel data */
+#define TCS34725_GDATAH           (0x19)
+#define TCS34725_BDATAL           (0x1A)    /* Blue channel data */
+#define TCS34725_BDATAH           (0x1B)
+
+typedef enum
+{
+    TCS34725_INTEGRATIONTIME_2_4MS  = 0xFF,   /**<  2.4ms - 1 cycle    - Max Count: 1024  */
+    TCS34725_INTEGRATIONTIME_24MS   = 0xF6,   /**<  24ms  - 10 cycles  - Max Count: 10240 */
+    TCS34725_INTEGRATIONTIME_50MS   = 0xEB,   /**<  50ms  - 20 cycles  - Max Count: 20480 */
+    TCS34725_INTEGRATIONTIME_101MS  = 0xD5,   /**<  101ms - 42 cycles  - Max Count: 43008 */
+    TCS34725_INTEGRATIONTIME_154MS  = 0xC0,   /**<  154ms - 64 cycles  - Max Count: 65535 */
+    TCS34725_INTEGRATIONTIME_700MS  = 0x00    /**<  700ms - 256 cycles - Max Count: 65535 */
+}
+tcs34725IntegrationTime_t;
+
+typedef enum
+{
+    TCS34725_GAIN_1X                = 0x00,   /**<  No gain  */
+    TCS34725_GAIN_4X                = 0x01,   /**<  2x gain  */
+    TCS34725_GAIN_16X               = 0x02,   /**<  16x gain */
+    TCS34725_GAIN_60X               = 0x03    /**<  60x gain */
+}
+tcs34725Gain_t;
+
+class Adafruit_TCS34725 {
+public:
+    Adafruit_TCS34725(I2C *i2c, tcs34725IntegrationTime_t = TCS34725_INTEGRATIONTIME_2_4MS, tcs34725Gain_t = TCS34725_GAIN_1X);
+  
+    bool     begin(void);
+    void     setIntegrationTime(tcs34725IntegrationTime_t it);
+    void     setGain(tcs34725Gain_t gain);
+    void     getRawData(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c);
+    uint16_t calculateColorTemperature(uint16_t r, uint16_t g, uint16_t b);
+    uint16_t calculateLux(uint16_t r, uint16_t g, uint16_t b);
+    void     write8 (uint8_t reg, uint32_t value);
+    uint8_t  read8 (uint8_t reg);
+    uint16_t read16 (uint8_t reg);
+    void setInterrupt(bool flag);
+    void clearInterrupt(void);
+    void setIntLimits(uint16_t l, uint16_t h);
+    void     enable(void);
+
+private:
+    bool _tcs34725Initialised;
+    tcs34725Gain_t _tcs34725Gain;
+    tcs34725IntegrationTime_t _tcs34725IntegrationTime; 
+  
+    I2C *_i2c;
+  
+    void     disable(void);
+};
+
+#endif