@@ -119,9 +119,9 @@ void Adafruit_TCS34725::enable(void)
119
119
{
120
120
write8 (TCS34725_ENABLE, TCS34725_ENABLE_PON);
121
121
delay (3 );
122
- write8 (TCS34725_ENABLE, TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN);
122
+ write8 (TCS34725_ENABLE, TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN);
123
123
/* Set a delay for the integration time.
124
- This is only necessary in the case where enabling and then
124
+ This is only necessary in the case where enabling and then
125
125
immediately trying to read values back. This is because setting
126
126
AEN triggers an automatic integration, so if a read RGBC is
127
127
performed too quickly, the data is not yet valid and all 0's are
@@ -171,7 +171,7 @@ void Adafruit_TCS34725::disable(void)
171
171
Constructor
172
172
*/
173
173
/* *************************************************************************/
174
- Adafruit_TCS34725::Adafruit_TCS34725 (tcs34725IntegrationTime_t it, tcs34725Gain_t gain)
174
+ Adafruit_TCS34725::Adafruit_TCS34725 (tcs34725IntegrationTime_t it, tcs34725Gain_t gain)
175
175
{
176
176
_tcs34725Initialised = false ;
177
177
_tcs34725IntegrationTime = it;
@@ -188,10 +188,10 @@ Adafruit_TCS34725::Adafruit_TCS34725(tcs34725IntegrationTime_t it, tcs34725Gain_
188
188
doing anything else)
189
189
*/
190
190
/* *************************************************************************/
191
- boolean Adafruit_TCS34725::begin (void )
191
+ boolean Adafruit_TCS34725::begin (void )
192
192
{
193
193
Wire.begin ();
194
-
194
+
195
195
/* Make sure we're actually connected */
196
196
uint8_t x = read8 (TCS34725_ID);
197
197
if ((x != 0x44 ) && (x != 0x10 ))
@@ -209,7 +209,7 @@ boolean Adafruit_TCS34725::begin(void)
209
209
210
210
return true ;
211
211
}
212
-
212
+
213
213
/* *************************************************************************/
214
214
/* !
215
215
Sets the integration time for the TC34725
@@ -255,7 +255,7 @@ void Adafruit_TCS34725::getRawData (uint16_t *r, uint16_t *g, uint16_t *b, uint1
255
255
*r = read16 (TCS34725_RDATAL);
256
256
*g = read16 (TCS34725_GDATAL);
257
257
*b = read16 (TCS34725_BDATAL);
258
-
258
+
259
259
/* Set a delay for the integration time */
260
260
switch (_tcs34725IntegrationTime)
261
261
{
@@ -330,6 +330,136 @@ uint16_t Adafruit_TCS34725::calculateColorTemperature(uint16_t r, uint16_t g, ui
330
330
return (uint16_t )cct;
331
331
}
332
332
333
+ /* *************************************************************************/
334
+ /* !
335
+ @brief Converts the raw R/G/B values to color temperature in degrees
336
+ Kelvin using the algorithm described in DN40 from Taos (now AMS).
337
+ */
338
+ /* *************************************************************************/
339
+ uint16_t Adafruit_TCS34725::calculateColorTemperature_dn40 (uint16_t r, uint16_t g, uint16_t b, uint16_t c)
340
+ {
341
+ int rc; /* Error return code */
342
+ uint16_t r2, g2, b2; /* RGB values minus IR component */
343
+ int gl; /* Results of the initial lux conversion */
344
+ uint8_t gain_int; /* Gain multiplier as a normal integer */
345
+ uint16_t sat; /* Digital saturation level */
346
+ uint16_t ir; /* Inferred IR content */
347
+
348
+ /* Analog/Digital saturation:
349
+ *
350
+ * (a) As light becomes brighter, the clear channel will tend to
351
+ * saturate first since R+G+B is approximately equal to C.
352
+ * (b) The TCS34725 accumulates 1024 counts per 2.4ms of integration
353
+ * time, up to a maximum values of 65535. This means analog
354
+ * saturation can occur up to an integration time of 153.6ms
355
+ * (64*2.4ms=153.6ms).
356
+ * (c) If the integration time is > 153.6ms, digital saturation will
357
+ * occur before analog saturation. Digital saturation occurs when
358
+ * the count reaches 65535.
359
+ */
360
+ if ((256 - _tcs34725IntegrationTime) > 63 ) {
361
+ /* Track digital saturation */
362
+ sat = 65535 ;
363
+ } else {
364
+ /* Track analog saturation */
365
+ sat = 1024 * (256 - _tcs34725IntegrationTime);
366
+ }
367
+
368
+ /* Ripple rejection:
369
+ *
370
+ * (a) An integration time of 50ms or multiples of 50ms are required to
371
+ * reject both 50Hz and 60Hz ripple.
372
+ * (b) If an integration time faster than 50ms is required, you may need
373
+ * to average a number of samples over a 50ms period to reject ripple
374
+ * from fluorescent and incandescent light sources.
375
+ *
376
+ * Ripple saturation notes:
377
+ *
378
+ * (a) If there is ripple in the received signal, the value read from C
379
+ * will be less than the max, but still have some effects of being
380
+ * saturated. This means that you can be below the 'sat' value, but
381
+ * still be saturating. At integration times >150ms this can be
382
+ * ignored, but <= 150ms you should calculate the 75% saturation
383
+ * level to avoid this problem.
384
+ */
385
+ if ((256 - _tcs34725IntegrationTime) <= 63 ) {
386
+ /* Adjust sat to 75% to avoid analog saturation if atime < 153.6ms */
387
+ sat -= sat/4 ;
388
+ }
389
+
390
+ /* Check for saturation and mark the sample as invalid if true */
391
+ if (c >= sat) {
392
+ return 0 ;
393
+ }
394
+
395
+ /* AMS RGB sensors have no IR channel, so the IR content must be */
396
+ /* calculated indirectly. */
397
+ ir = (r + g + b > c) ? (r + g + b - c) / 2 : 0 ;
398
+
399
+ /* Remove the IR component from the raw RGB values */
400
+ r2 = r - ir;
401
+ g2 = g - ir;
402
+ b2 = b - ir;
403
+
404
+ /* Convert gain to a usable integer value */
405
+ switch (_tcs34725Gain) {
406
+ case TCS34725_GAIN_4X: /* GAIN 4X */
407
+ gain_int = 4 ;
408
+ break ;
409
+ case TCS34725_GAIN_16X: /* GAIN 16X */
410
+ gain_int = 16 ;
411
+ break ;
412
+ case TCS34725_GAIN_60X: /* GAIN 60X */
413
+ gain_int = 60 ;
414
+ break ;
415
+ case TCS34725_GAIN_1X: /* GAIN 1X */
416
+ default :
417
+ gain_int = 1 ;
418
+ break ;
419
+ }
420
+
421
+ /* Calculate the counts per lux (CPL), taking into account the optional
422
+ * arguments for Glass Attenuation (GA) and Device Factor (DF).
423
+ *
424
+ * GA = 1/T where T is glass transmissivity, meaning if glass is 50%
425
+ * transmissive, the GA is 2 (1/0.5=2), and if the glass attenuates light
426
+ * 95% the GA is 20 (1/0.05). A GA of 1.0 assumes perfect transmission.
427
+ *
428
+ * NOTE: It is recommended to have a CPL > 5 to have a lux accuracy
429
+ * < +/- 0.5 lux, where the digitization error can be calculated via:
430
+ * 'DER = (+/-2) / CPL'.
431
+ */
432
+ float cpl = (((256 -_tcs34725IntegrationTime)*2 .4f ) * gain_int) /
433
+ (1 .0f * 310 .0f );
434
+
435
+ /* Determine lux accuracy (+/- lux) */
436
+ float der = 2 .0f / cpl;
437
+
438
+ /* Determine the maximum lux value */
439
+ float max_lux = 65535.0 / (cpl * 3 );
440
+
441
+ /* Lux is a function of the IR-compensated RGB channels and the associated
442
+ * color coefficients, with G having a particularly heavy influence to
443
+ * match the nature of the human eye.
444
+ *
445
+ * NOTE: The green value should be > 10 to ensure the accuracy of the lux
446
+ * conversions. If it is below 10, the gain should be increased, but
447
+ * the clear<100 check earlier should cover this edge case.
448
+ */
449
+ gl = 0 .136f * (float )r2 + /* * Red coefficient. */
450
+ 1 .000f * (float )g2 + /* * Green coefficient. */
451
+ -0 .444f * (float )b2; /* * Blue coefficient. */
452
+
453
+ float lux = gl / cpl;
454
+
455
+ /* A simple method of measuring color temp is to use the ratio of blue */
456
+ /* to red light, taking IR cancellation into account. */
457
+ uint16_t cct = (3810 * (uint32_t )b2) / /* * Color temp coefficient. */
458
+ (uint32_t )r2 + 1391 ; /* * Color temp offset. */
459
+
460
+ return cct;
461
+ }
462
+
333
463
/* *************************************************************************/
334
464
/* !
335
465
@brief Converts the raw R/G/B values to lux
0 commit comments