source: rtos_arduino/trunk/examples/CompositeExample/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp@ 137

Last change on this file since 137 was 137, checked in by ertl-honda, 8 years ago

サンプルの追加.

File size: 9.6 KB
Line 
1/**************************************************************************/
2/*!
3 @file Adafruit_TSL2591.cpp
4 @author KT0WN (adafruit.com)
5
6 This is a library for the Adafruit TSL2591 breakout board
7 This library works with the Adafruit TSL2591 breakout
8 ----> https://www.adafruit.com/products/1980
9
10 Check out the links above for our tutorials and wiring diagrams
11 These chips use I2C to communicate
12
13 Adafruit invests time and resources providing this open source code,
14 please support Adafruit and open-source hardware by purchasing
15 products from Adafruit!
16
17 @section LICENSE
18
19 Software License Agreement (BSD License)
20
21 Copyright (c) 2014 Adafruit Industries
22 All rights reserved.
23
24 Redistribution and use in source and binary forms, with or without
25 modification, are permitted provided that the following conditions are met:
26 1. Redistributions of source code must retain the above copyright
27 notice, this list of conditions and the following disclaimer.
28 2. Redistributions in binary form must reproduce the above copyright
29 notice, this list of conditions and the following disclaimer in the
30 documentation and/or other materials provided with the distribution.
31 3. Neither the name of the copyright holders nor the
32 names of its contributors may be used to endorse or promote products
33 derived from this software without specific prior written permission.
34
35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
36 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
39 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
40 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
41 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
42 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45*/
46/**************************************************************************/
47#if defined(ESP8266)
48#include <pgmspace.h>
49#else
50#include <avr/pgmspace.h>
51#endif
52#if defined(__AVR__)
53#include <util/delay.h>
54#endif
55#include <stdlib.h>
56
57#include "Adafruit_TSL2591.h"
58
59Adafruit_TSL2591::Adafruit_TSL2591(int32_t sensorID)
60{
61 _initialized = false;
62 _integration = TSL2591_INTEGRATIONTIME_100MS;
63 _gain = TSL2591_GAIN_MED;
64 _sensorID = sensorID;
65
66 // we cant do wire initialization till later, because we havent loaded Wire yet
67}
68
69boolean Adafruit_TSL2591::begin(void)
70{
71 Wire.begin();
72
73 /*
74 for (uint8_t i=0; i<0x20; i++)
75 {
76 uint8_t id = read8(0x12);
77 Serial.print("$"); Serial.print(i, HEX);
78 Serial.print(" = 0x"); Serial.println(read8(i), HEX);
79 }
80 */
81
82 uint8_t id = read8(0x12);
83 if (id == 0x50 )
84 {
85 //Serial.println("Found Adafruit_TSL2591");
86 }
87 else
88 {
89 return false;
90 }
91
92 _initialized = true;
93
94 // Set default integration time and gain
95 setTiming(_integration);
96 setGain(_gain);
97
98 // Note: by default, the device is in power down mode on bootup
99 disable();
100
101 return true;
102}
103
104void Adafruit_TSL2591::enable(void)
105{
106 if (!_initialized)
107 {
108 if (!begin())
109 {
110 return;
111 }
112 }
113
114 // Enable the device by setting the control bit to 0x01
115 write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_ENABLE, TSL2591_ENABLE_POWERON | TSL2591_ENABLE_AEN | TSL2591_ENABLE_AIEN);
116}
117
118void Adafruit_TSL2591::disable(void)
119{
120 if (!_initialized)
121 {
122 if (!begin())
123 {
124 return;
125 }
126 }
127
128 // Disable the device by setting the control bit to 0x00
129 write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_ENABLE, TSL2591_ENABLE_POWEROFF);
130}
131
132void Adafruit_TSL2591::setGain(tsl2591Gain_t gain)
133{
134 if (!_initialized)
135 {
136 if (!begin())
137 {
138 return;
139 }
140 }
141
142 enable();
143 _gain = gain;
144 write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, _integration | _gain);
145 disable();
146}
147
148tsl2591Gain_t Adafruit_TSL2591::getGain()
149{
150 return _gain;
151}
152
153void Adafruit_TSL2591::setTiming(tsl2591IntegrationTime_t integration)
154{
155 if (!_initialized)
156 {
157 if (!begin())
158 {
159 return;
160 }
161 }
162
163 enable();
164 _integration = integration;
165 write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, _integration | _gain);
166 disable();
167}
168
169tsl2591IntegrationTime_t Adafruit_TSL2591::getTiming()
170{
171 return _integration;
172}
173
174uint32_t Adafruit_TSL2591::calculateLux(uint16_t ch0, uint16_t ch1)
175{
176 uint16_t atime, again;
177 float cpl, lux1, lux2, lux;
178 uint32_t chan0, chan1;
179
180 // Check for overflow conditions first
181 if ((ch0 == 0xFFFF) | (ch1 == 0xFFFF))
182 {
183 // Signal an overflow
184 return 0;
185 }
186
187 // Note: This algorithm is based on preliminary coefficients
188 // provided by AMS and may need to be updated in the future
189
190 switch (_integration)
191 {
192 case TSL2591_INTEGRATIONTIME_100MS :
193 atime = 100.0F;
194 break;
195 case TSL2591_INTEGRATIONTIME_200MS :
196 atime = 200.0F;
197 break;
198 case TSL2591_INTEGRATIONTIME_300MS :
199 atime = 300.0F;
200 break;
201 case TSL2591_INTEGRATIONTIME_400MS :
202 atime = 400.0F;
203 break;
204 case TSL2591_INTEGRATIONTIME_500MS :
205 atime = 500.0F;
206 break;
207 case TSL2591_INTEGRATIONTIME_600MS :
208 atime = 600.0F;
209 break;
210 default: // 100ms
211 atime = 100.0F;
212 break;
213 }
214
215 switch (_gain)
216 {
217 case TSL2591_GAIN_LOW :
218 again = 1.0F;
219 break;
220 case TSL2591_GAIN_MED :
221 again = 25.0F;
222 break;
223 case TSL2591_GAIN_HIGH :
224 again = 428.0F;
225 break;
226 case TSL2591_GAIN_MAX :
227 again = 9876.0F;
228 break;
229 default:
230 again = 1.0F;
231 break;
232 }
233
234 // cpl = (ATIME * AGAIN) / DF
235 cpl = (atime * again) / TSL2591_LUX_DF;
236
237 lux1 = ( (float)ch0 - (TSL2591_LUX_COEFB * (float)ch1) ) / cpl;
238 lux2 = ( ( TSL2591_LUX_COEFC * (float)ch0 ) - ( TSL2591_LUX_COEFD * (float)ch1 ) ) / cpl;
239
240 // The highest value is the approximate lux equivalent
241 lux = lux1 > lux2 ? lux1 : lux2;
242
243 // Signal I2C had no errors
244 return (uint32_t)lux;
245}
246
247uint32_t Adafruit_TSL2591::getFullLuminosity (void)
248{
249 if (!_initialized)
250 {
251 if (!begin())
252 {
253 return 0;
254 }
255 }
256
257 // Enable the device
258 enable();
259
260 // Wait x ms for ADC to complete
261 for (uint8_t d=0; d<=_integration; d++)
262 {
263 delay(120);
264 }
265
266 uint32_t x;
267 x = read16(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN1_LOW);
268 x <<= 16;
269 x |= read16(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN0_LOW);
270
271 disable();
272
273 return x;
274}
275
276uint16_t Adafruit_TSL2591::getLuminosity (uint8_t channel)
277{
278 uint32_t x = getFullLuminosity();
279
280 if (channel == TSL2591_FULLSPECTRUM)
281 {
282 // Reads two byte value from channel 0 (visible + infrared)
283 return (x & 0xFFFF);
284 }
285 else if (channel == TSL2591_INFRARED)
286 {
287 // Reads two byte value from channel 1 (infrared)
288 return (x >> 16);
289 }
290 else if (channel == TSL2591_VISIBLE)
291 {
292 // Reads all and subtracts out just the visible!
293 return ( (x & 0xFFFF) - (x >> 16));
294 }
295
296 // unknown channel!
297 return 0;
298}
299
300uint8_t Adafruit_TSL2591::read8(uint8_t reg)
301{
302 Wire.beginTransmission(TSL2591_ADDR);
303 Wire.write(0x80 | 0x20 | reg); // command bit, normal mode
304 Wire.endTransmission();
305
306 Wire.requestFrom(TSL2591_ADDR, 1);
307 while (! Wire.available());
308 return Wire.read();
309}
310
311uint16_t Adafruit_TSL2591::read16(uint8_t reg)
312{
313 uint16_t x;
314 uint16_t t;
315
316 Wire.beginTransmission(TSL2591_ADDR);
317#if ARDUINO >= 100
318 Wire.write(reg);
319#else
320 Wire.send(reg);
321#endif
322 Wire.endTransmission();
323
324 Wire.requestFrom(TSL2591_ADDR, 2);
325#if ARDUINO >= 100
326 t = Wire.read();
327 x = Wire.read();
328#else
329 t = Wire.receive();
330 x = Wire.receive();
331#endif
332 x <<= 8;
333 x |= t;
334 return x;
335}
336
337void Adafruit_TSL2591::write8 (uint8_t reg, uint8_t value)
338{
339 Wire.beginTransmission(TSL2591_ADDR);
340#if ARDUINO >= 100
341 Wire.write(reg);
342 Wire.write(value);
343#else
344 Wire.send(reg);
345 Wire.send(value);
346#endif
347 Wire.endTransmission();
348}
349
350/**************************************************************************/
351/*!
352 @brief Gets the most recent sensor event
353*/
354/**************************************************************************/
355bool Adafruit_TSL2591::getEvent(sensors_event_t *event)
356{
357 uint16_t ir, full;
358 uint32_t lum = getFullLuminosity();
359 /* Early silicon seems to have issues when there is a sudden jump in */
360 /* light levels. :( To work around this for now sample the sensor 2x */
361 lum = getFullLuminosity();
362 ir = lum >> 16;
363 full = lum & 0xFFFF;
364
365 /* Clear the event */
366 memset(event, 0, sizeof(sensors_event_t));
367
368 event->version = sizeof(sensors_event_t);
369 event->sensor_id = _sensorID;
370 event->type = SENSOR_TYPE_LIGHT;
371 event->timestamp = millis();
372
373 /* Calculate the actual lux value */
374 /* 0 = sensor overflow (too much light) */
375 event->light = calculateLux(full, ir);
376
377 return true;
378}
379
380/**************************************************************************/
381/*!
382 @brief Gets the sensor_t data
383*/
384/**************************************************************************/
385void Adafruit_TSL2591::getSensor(sensor_t *sensor)
386{
387 /* Clear the sensor_t object */
388 memset(sensor, 0, sizeof(sensor_t));
389
390 /* Insert the sensor name in the fixed length char array */
391 strncpy (sensor->name, "TSL2591", sizeof(sensor->name) - 1);
392 sensor->name[sizeof(sensor->name)- 1] = 0;
393 sensor->version = 1;
394 sensor->sensor_id = _sensorID;
395 sensor->type = SENSOR_TYPE_LIGHT;
396 sensor->min_delay = 0;
397 sensor->max_value = 88000.0;
398 sensor->min_value = 0.0;
399 sensor->resolution = 1.0;
400}
Note: See TracBrowser for help on using the repository browser.