Skip to content

Commit 6c99bd5

Browse files
joshua-yangJohn Lee
authored andcommitted
src/sensors: Add libraries to support the new sensors
Change-Id: Ie24356129fc6f604e2de7af0161d6191108b8ff0
1 parent f743477 commit 6c99bd5

26 files changed

+4239
-0
lines changed

src/sensors/Adafruit_TCS34725.cpp

Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
/**************************************************************************/
2+
/*!
3+
@file Adafruit_TCS34725.cpp
4+
@author KTOWN (Adafruit Industries)
5+
@license BSD (see license.txt)
6+
7+
Driver for the TCS34725 digital color sensors.
8+
9+
Adafruit invests time and resources providing this open source code,
10+
please support Adafruit and open-source hardware by purchasing
11+
products from Adafruit!
12+
13+
@section HISTORY
14+
15+
v1.0 - First release
16+
*/
17+
/**************************************************************************/
18+
#ifdef __AVR
19+
#include <avr/pgmspace.h>
20+
#elif defined(ESP8266)
21+
#include <pgmspace.h>
22+
#endif
23+
#include <stdlib.h>
24+
#include <math.h>
25+
26+
#include "Adafruit_TCS34725.h"
27+
28+
/*========================================================================*/
29+
/* PRIVATE FUNCTIONS */
30+
/*========================================================================*/
31+
32+
/**************************************************************************/
33+
/*!
34+
@brief Implements missing powf function
35+
*/
36+
/**************************************************************************/
37+
float powf(const float x, const float y)
38+
{
39+
return (float)(pow((double)x, (double)y));
40+
}
41+
42+
/**************************************************************************/
43+
/*!
44+
@brief Writes a register and an 8 bit value over I2C
45+
*/
46+
/**************************************************************************/
47+
void Adafruit_TCS34725::write8 (uint8_t reg, uint32_t value)
48+
{
49+
Wire.beginTransmission(TCS34725_ADDRESS);
50+
#if ARDUINO >= 100
51+
Wire.write(TCS34725_COMMAND_BIT | reg);
52+
Wire.write(value & 0xFF);
53+
#else
54+
Wire.send(TCS34725_COMMAND_BIT | reg);
55+
Wire.send(value & 0xFF);
56+
#endif
57+
Wire.endTransmission();
58+
}
59+
60+
/**************************************************************************/
61+
/*!
62+
@brief Reads an 8 bit value over I2C
63+
*/
64+
/**************************************************************************/
65+
uint8_t Adafruit_TCS34725::read8(uint8_t reg)
66+
{
67+
Wire.beginTransmission(TCS34725_ADDRESS);
68+
#if ARDUINO >= 100
69+
Wire.write(TCS34725_COMMAND_BIT | reg);
70+
#else
71+
Wire.send(TCS34725_COMMAND_BIT | reg);
72+
#endif
73+
Wire.endTransmission();
74+
75+
Wire.requestFrom(TCS34725_ADDRESS, 1);
76+
#if ARDUINO >= 100
77+
return Wire.read();
78+
#else
79+
return Wire.receive();
80+
#endif
81+
}
82+
83+
/**************************************************************************/
84+
/*!
85+
@brief Reads a 16 bit values over I2C
86+
*/
87+
/**************************************************************************/
88+
uint16_t Adafruit_TCS34725::read16(uint8_t reg)
89+
{
90+
uint16_t x; uint16_t t;
91+
92+
Wire.beginTransmission(TCS34725_ADDRESS);
93+
#if ARDUINO >= 100
94+
Wire.write(TCS34725_COMMAND_BIT | reg);
95+
#else
96+
Wire.send(TCS34725_COMMAND_BIT | reg);
97+
#endif
98+
Wire.endTransmission();
99+
100+
Wire.requestFrom(TCS34725_ADDRESS, 2);
101+
#if ARDUINO >= 100
102+
t = Wire.read();
103+
x = Wire.read();
104+
#else
105+
t = Wire.receive();
106+
x = Wire.receive();
107+
#endif
108+
x <<= 8;
109+
x |= t;
110+
return x;
111+
}
112+
113+
/**************************************************************************/
114+
/*!
115+
Enables the device
116+
*/
117+
/**************************************************************************/
118+
void Adafruit_TCS34725::enable(void)
119+
{
120+
write8(TCS34725_ENABLE, TCS34725_ENABLE_PON);
121+
delay(3);
122+
write8(TCS34725_ENABLE, TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN);
123+
}
124+
125+
/**************************************************************************/
126+
/*!
127+
Disables the device (putting it in lower power sleep mode)
128+
*/
129+
/**************************************************************************/
130+
void Adafruit_TCS34725::disable(void)
131+
{
132+
/* Turn the device off to save power */
133+
uint8_t reg = 0;
134+
reg = read8(TCS34725_ENABLE);
135+
write8(TCS34725_ENABLE, reg & ~(TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN));
136+
}
137+
138+
/*========================================================================*/
139+
/* CONSTRUCTORS */
140+
/*========================================================================*/
141+
142+
/**************************************************************************/
143+
/*!
144+
Constructor
145+
*/
146+
/**************************************************************************/
147+
Adafruit_TCS34725::Adafruit_TCS34725(tcs34725IntegrationTime_t it, tcs34725Gain_t gain)
148+
{
149+
_tcs34725Initialised = false;
150+
_tcs34725IntegrationTime = it;
151+
_tcs34725Gain = gain;
152+
}
153+
154+
/*========================================================================*/
155+
/* PUBLIC FUNCTIONS */
156+
/*========================================================================*/
157+
158+
/**************************************************************************/
159+
/*!
160+
Initializes I2C and configures the sensor (call this function before
161+
doing anything else)
162+
*/
163+
/**************************************************************************/
164+
boolean Adafruit_TCS34725::begin(void)
165+
{
166+
Wire.begin();
167+
168+
/* Make sure we're actually connected */
169+
uint8_t x = read8(TCS34725_ID);
170+
Serial.println(x, HEX);
171+
if (x != 0x44)
172+
{
173+
return false;
174+
}
175+
_tcs34725Initialised = true;
176+
177+
/* Set default integration time and gain */
178+
setIntegrationTime(_tcs34725IntegrationTime);
179+
setGain(_tcs34725Gain);
180+
181+
/* Note: by default, the device is in power down mode on bootup */
182+
enable();
183+
184+
return true;
185+
}
186+
187+
/**************************************************************************/
188+
/*!
189+
Sets the integration time for the TC34725
190+
*/
191+
/**************************************************************************/
192+
void Adafruit_TCS34725::setIntegrationTime(tcs34725IntegrationTime_t it)
193+
{
194+
if (!_tcs34725Initialised) begin();
195+
196+
/* Update the timing register */
197+
write8(TCS34725_ATIME, it);
198+
199+
/* Update value placeholders */
200+
_tcs34725IntegrationTime = it;
201+
}
202+
203+
/**************************************************************************/
204+
/*!
205+
Adjusts the gain on the TCS34725 (adjusts the sensitivity to light)
206+
*/
207+
/**************************************************************************/
208+
void Adafruit_TCS34725::setGain(tcs34725Gain_t gain)
209+
{
210+
if (!_tcs34725Initialised) begin();
211+
212+
/* Update the timing register */
213+
write8(TCS34725_CONTROL, gain);
214+
215+
/* Update value placeholders */
216+
_tcs34725Gain = gain;
217+
}
218+
219+
/**************************************************************************/
220+
/*!
221+
@brief Reads the raw red, green, blue and clear channel values
222+
*/
223+
/**************************************************************************/
224+
void Adafruit_TCS34725::getRawData (uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c)
225+
{
226+
if (!_tcs34725Initialised) begin();
227+
228+
*c = read16(TCS34725_CDATAL);
229+
*r = read16(TCS34725_RDATAL);
230+
*g = read16(TCS34725_GDATAL);
231+
*b = read16(TCS34725_BDATAL);
232+
233+
/* Set a delay for the integration time */
234+
switch (_tcs34725IntegrationTime)
235+
{
236+
case TCS34725_INTEGRATIONTIME_2_4MS:
237+
delay(3);
238+
break;
239+
case TCS34725_INTEGRATIONTIME_24MS:
240+
delay(24);
241+
break;
242+
case TCS34725_INTEGRATIONTIME_50MS:
243+
delay(50);
244+
break;
245+
case TCS34725_INTEGRATIONTIME_101MS:
246+
delay(101);
247+
break;
248+
case TCS34725_INTEGRATIONTIME_154MS:
249+
delay(154);
250+
break;
251+
case TCS34725_INTEGRATIONTIME_700MS:
252+
delay(700);
253+
break;
254+
}
255+
}
256+
257+
/**************************************************************************/
258+
/*!
259+
@brief Converts the raw R/G/B values to color temperature in degrees
260+
Kelvin
261+
*/
262+
/**************************************************************************/
263+
uint16_t Adafruit_TCS34725::calculateColorTemperature(uint16_t r, uint16_t g, uint16_t b)
264+
{
265+
float X, Y, Z; /* RGB to XYZ correlation */
266+
float xc, yc; /* Chromaticity co-ordinates */
267+
float n; /* McCamy's formula */
268+
float cct;
269+
270+
/* 1. Map RGB values to their XYZ counterparts. */
271+
/* Based on 6500K fluorescent, 3000K fluorescent */
272+
/* and 60W incandescent values for a wide range. */
273+
/* Note: Y = Illuminance or lux */
274+
X = (-0.14282F * r) + (1.54924F * g) + (-0.95641F * b);
275+
Y = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b);
276+
Z = (-0.68202F * r) + (0.77073F * g) + ( 0.56332F * b);
277+
278+
/* 2. Calculate the chromaticity co-ordinates */
279+
xc = (X) / (X + Y + Z);
280+
yc = (Y) / (X + Y + Z);
281+
282+
/* 3. Use McCamy's formula to determine the CCT */
283+
n = (xc - 0.3320F) / (0.1858F - yc);
284+
285+
/* Calculate the final CCT */
286+
cct = (449.0F * powf(n, 3)) + (3525.0F * powf(n, 2)) + (6823.3F * n) + 5520.33F;
287+
288+
/* Return the results in degrees Kelvin */
289+
return (uint16_t)cct;
290+
}
291+
292+
/**************************************************************************/
293+
/*!
294+
@brief Converts the raw R/G/B values to color temperature in degrees
295+
Kelvin
296+
*/
297+
/**************************************************************************/
298+
uint16_t Adafruit_TCS34725::calculateLux(uint16_t r, uint16_t g, uint16_t b)
299+
{
300+
float illuminance;
301+
302+
/* This only uses RGB ... how can we integrate clear or calculate lux */
303+
/* based exclusively on clear since this might be more reliable? */
304+
illuminance = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b);
305+
306+
return (uint16_t)illuminance;
307+
}
308+
309+
310+
void Adafruit_TCS34725::setInterrupt(boolean i) {
311+
uint8_t r = read8(TCS34725_ENABLE);
312+
if (i) {
313+
r |= TCS34725_ENABLE_AIEN;
314+
} else {
315+
r &= ~TCS34725_ENABLE_AIEN;
316+
}
317+
write8(TCS34725_ENABLE, r);
318+
}
319+
320+
void Adafruit_TCS34725::clearInterrupt(void) {
321+
Wire.beginTransmission(TCS34725_ADDRESS);
322+
#if ARDUINO >= 100
323+
Wire.write(0x66);
324+
#else
325+
Wire.send(0x66);
326+
#endif
327+
Wire.endTransmission();
328+
}
329+
330+
331+
void Adafruit_TCS34725::setIntLimits(uint16_t low, uint16_t high) {
332+
write8(0x04, low & 0xFF);
333+
write8(0x05, low >> 8);
334+
write8(0x06, high & 0xFF);
335+
write8(0x07, high >> 8);
336+
}

0 commit comments

Comments
 (0)