From ed77d41b7acfeba09c86f821f657c6ae2b776a74 Mon Sep 17 00:00:00 2001 From: Fisch Date: Sun, 1 Nov 2020 13:25:52 +0100 Subject: [PATCH] implement wrapper class with agc from library example code --- src/tcs34725_agc.cpp | 85 ++++++++++++++++++++++++++++++++++++++++++++ src/tcs34725_agc.h | 48 +++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 src/tcs34725_agc.cpp create mode 100644 src/tcs34725_agc.h diff --git a/src/tcs34725_agc.cpp b/src/tcs34725_agc.cpp new file mode 100644 index 0000000..ac0b0ff --- /dev/null +++ b/src/tcs34725_agc.cpp @@ -0,0 +1,85 @@ +//#include +//#include "Adafruit_TCS34725.h" +#include "tcs34725_agc.h" + +// +// Gain/time combinations to use and the min/max limits for hysteresis +// that avoid saturation. They should be in order from dim to bright. +// +// Also set the first min count and the last max count to 0 to indicate +// the start and end of the list. +// +const tcs34725::tcs_agc tcs34725::agc_lst[] = { + { TCS34725_GAIN_60X, TCS34725_INTEGRATIONTIME_700MS, 0, 20000 }, + { TCS34725_GAIN_60X, TCS34725_INTEGRATIONTIME_154MS, 4990, 63000 }, + { TCS34725_GAIN_16X, TCS34725_INTEGRATIONTIME_154MS, 16790, 63000 }, + { TCS34725_GAIN_4X, TCS34725_INTEGRATIONTIME_154MS, 15740, 63000 }, + { TCS34725_GAIN_1X, TCS34725_INTEGRATIONTIME_154MS, 15740, 0 } +}; +tcs34725::tcs34725() : agc_cur(0), isAvailable(0), isSaturated(0) { +} + +// initialize the sensor +boolean tcs34725::begin(void) { + tcs = Adafruit_TCS34725(agc_lst[agc_cur].at, agc_lst[agc_cur].ag); + if ((isAvailable = tcs.begin())) + setGainTime(); + return(isAvailable); +} + +// Set the gain and integration time +void tcs34725::setGainTime(void) { + tcs.setGain(agc_lst[agc_cur].ag); + tcs.setIntegrationTime(agc_lst[agc_cur].at); + atime = int(agc_lst[agc_cur].at); + atime_ms = ((256 - atime) * 2.4); + switch(agc_lst[agc_cur].ag) { + case TCS34725_GAIN_1X: + againx = 1; + break; + case TCS34725_GAIN_4X: + againx = 4; + break; + case TCS34725_GAIN_16X: + againx = 16; + break; + case TCS34725_GAIN_60X: + againx = 60; + break; + } +} + +// Retrieve data from the sensor and do the calculations +void tcs34725::getData(void) { + // read the sensor and autorange if necessary + tcs.getRawData(&r, &g, &b, &c); + while(1) { + if (agc_lst[agc_cur].maxcnt && c > agc_lst[agc_cur].maxcnt) + agc_cur++; + else if (agc_lst[agc_cur].mincnt && c < agc_lst[agc_cur].mincnt) + agc_cur--; + else break; + + setGainTime(); + delay((256 - atime) * 2.4 * 2); // shock absorber + tcs.getRawData(&r, &g, &b, &c); + break; + } + + // DN40 calculations + ir = (r + g + b > c) ? (r + g + b - c) / 2 : 0; + r_comp = r - ir; + g_comp = g - ir; + b_comp = b - ir; + c_comp = c - ir; + cratio = float(ir) / float(c); + + saturation = ((256 - atime) > 63) ? 65535 : 1024 * (256 - atime); + saturation75 = (atime_ms < 150) ? (saturation - saturation / 4) : saturation; + isSaturated = (atime_ms < 150 && c > saturation75) ? 1 : 0; + cpl = (atime_ms * againx) / (TCS34725_GA * TCS34725_DF); + maxlux = 65535 / (cpl * 3); + + lux = (TCS34725_R_Coef * float(r_comp) + TCS34725_G_Coef * float(g_comp) + TCS34725_B_Coef * float(b_comp)) / cpl; + ct = TCS34725_CT_Coef * float(b_comp) / float(r_comp) + TCS34725_CT_Offset; +} \ No newline at end of file diff --git a/src/tcs34725_agc.h b/src/tcs34725_agc.h new file mode 100644 index 0000000..a16caa1 --- /dev/null +++ b/src/tcs34725_agc.h @@ -0,0 +1,48 @@ +//copied from example code: https://github.com/adafruit/Adafruit_TCS34725/blob/master/examples/tcs34725autorange/tcs34725autorange.ino + +#ifndef _TCS34725_AGC_H_ +#define _TCS34725_AGC_H_ + +#include +#include "Adafruit_TCS34725.h" + + +#define TCS34725_R_Coef 0.136 +#define TCS34725_G_Coef 1.000 +#define TCS34725_B_Coef -0.444 +#define TCS34725_GA 1.0 +#define TCS34725_DF 310.0 +#define TCS34725_CT_Coef 3810.0 +#define TCS34725_CT_Offset 1391.0 + +// Autorange class for TCS34725 +class tcs34725 { +private: + struct tcs_agc { + tcs34725Gain_t ag; + tcs34725IntegrationTime_t at; + uint16_t mincnt; + uint16_t maxcnt; + }; + static const tcs_agc agc_lst[]; + uint16_t agc_cur; + + void setGainTime(void); + Adafruit_TCS34725 tcs; + +public: + tcs34725(void); + + boolean begin(void); + void getData(void); + + boolean isAvailable, isSaturated; + uint16_t againx, atime, atime_ms; + uint16_t r, g, b, c; + uint16_t ir; + uint16_t r_comp, g_comp, b_comp, c_comp; + uint16_t saturation, saturation75; + float cratio, cpl, ct, lux, maxlux; +}; + +#endif \ No newline at end of file