Skip to content

Commit 1602fee

Browse files
committed
Initial commit
0 parents  commit 1602fee

File tree

3 files changed

+465
-0
lines changed

3 files changed

+465
-0
lines changed

README.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
This is an Arduino library for the TSL2561 digital luminosity (light) sensors.
2+
3+
Pick one up at http://www.adafruit.com/products/xxx
4+
5+
To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder TSL2561. Check that the TSL2561 folder contains TSL2561.cpp and TSL2561.h
6+
7+
Place the TSL2561 library folder your <arduinosketchfolder>/libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE.

TSL2561.cpp

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
2+
/**************************************************************************/
3+
/*!
4+
@file tsl2561.c
5+
@author K. Townsend (microBuilder.eu / adafruit.com)
6+
7+
@section LICENSE
8+
9+
Software License Agreement (BSD License)
10+
11+
Copyright (c) 2010, microBuilder SARL, Adafruit Industries
12+
All rights reserved.
13+
14+
Redistribution and use in source and binary forms, with or without
15+
modification, are permitted provided that the following conditions are met:
16+
1. Redistributions of source code must retain the above copyright
17+
notice, this list of conditions and the following disclaimer.
18+
2. Redistributions in binary form must reproduce the above copyright
19+
notice, this list of conditions and the following disclaimer in the
20+
documentation and/or other materials provided with the distribution.
21+
3. Neither the name of the copyright holders nor the
22+
names of its contributors may be used to endorse or promote products
23+
derived from this software without specific prior written permission.
24+
25+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
26+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
29+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35+
*/
36+
/**************************************************************************/
37+
38+
#include <avr/pgmspace.h>
39+
#include <WProgram.h>
40+
#include <util/delay.h>
41+
#include <stdlib.h>
42+
#include <Wire.h>
43+
44+
#include "TSL2561.h"
45+
46+
TSL2561::TSL2561(uint8_t addr) {
47+
_addr = addr;
48+
_initialized = false;
49+
_integration = TSL2561_INTEGRATIONTIME_13MS;
50+
_gain = TSL2561_GAIN_16X;
51+
52+
// we cant do wire initialization till later, because we havent loaded Wire yet
53+
}
54+
55+
boolean TSL2561::begin(void) {
56+
Wire.begin();
57+
58+
// Initialise I2C
59+
Wire.beginTransmission(_addr);
60+
Wire.send(TSL2561_REGISTER_ID);
61+
Wire.endTransmission();
62+
Wire.requestFrom(_addr, 1);
63+
int x = Wire.receive();
64+
//Serial.print("0x"); Serial.println(x, HEX);
65+
if (x & 0x0A ) {
66+
//Serial.println("Found TSL2561");
67+
} else {
68+
return false;
69+
}
70+
_initialized = true;
71+
72+
// Set default integration time and gain
73+
setTiming(_integration);
74+
setGain(_gain);
75+
// Note: by default, the device is in power down mode on bootup
76+
disable();
77+
78+
return true;
79+
}
80+
81+
void TSL2561::enable(void)
82+
{
83+
if (!_initialized) begin();
84+
85+
// Enable the device by setting the control bit to 0x03
86+
write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON);
87+
}
88+
89+
void TSL2561::disable(void)
90+
{
91+
if (!_initialized) begin();
92+
93+
// Disable the device by setting the control bit to 0x03
94+
write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF);
95+
}
96+
97+
98+
void TSL2561::setGain(tsl2561Gain_t gain) {
99+
if (!_initialized) begin();
100+
101+
enable();
102+
_gain = gain;
103+
write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _integration | _gain);
104+
disable();
105+
}
106+
107+
void TSL2561::setTiming(tsl2561IntegrationTime_t integration)
108+
{
109+
if (!_initialized) begin();
110+
111+
enable();
112+
_integration = integration;
113+
write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _integration | _gain);
114+
disable();
115+
}
116+
117+
uint32_t TSL2561::calculateLux(uint16_t ch0, uint16_t ch1)
118+
{
119+
unsigned long chScale;
120+
unsigned long channel1;
121+
unsigned long channel0;
122+
123+
switch (_integration)
124+
{
125+
case TSL2561_INTEGRATIONTIME_13MS:
126+
chScale = TSL2561_LUX_CHSCALE_TINT0;
127+
break;
128+
case TSL2561_INTEGRATIONTIME_101MS:
129+
chScale = TSL2561_LUX_CHSCALE_TINT1;
130+
break;
131+
default: // No scaling ... integration time = 402ms
132+
chScale = (1 << TSL2561_LUX_CHSCALE);
133+
break;
134+
}
135+
136+
// Scale for gain (1x or 16x)
137+
if (!_gain) chScale = chScale << 4;
138+
139+
// scale the channel values
140+
channel0 = (ch0 * chScale) >> TSL2561_LUX_CHSCALE;
141+
channel1 = (ch1 * chScale) >> TSL2561_LUX_CHSCALE;
142+
143+
// find the ratio of the channel values (Channel1/Channel0)
144+
unsigned long ratio1 = 0;
145+
if (channel0 != 0) ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE+1)) / channel0;
146+
147+
// round the ratio value
148+
unsigned long ratio = (ratio1 + 1) >> 1;
149+
150+
unsigned int b, m;
151+
152+
#ifdef TSL2561_PACKAGE_CS
153+
if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C))
154+
{b=TSL2561_LUX_B1C; m=TSL2561_LUX_M1C;}
155+
else if (ratio <= TSL2561_LUX_K2C)
156+
{b=TSL2561_LUX_B2C; m=TSL2561_LUX_M2C;}
157+
else if (ratio <= TSL2561_LUX_K3C)
158+
{b=TSL2561_LUX_B3C; m=TSL2561_LUX_M3C;}
159+
else if (ratio <= TSL2561_LUX_K4C)
160+
{b=TSL2561_LUX_B4C; m=TSL2561_LUX_M4C;}
161+
else if (ratio <= TSL2561_LUX_K5C)
162+
{b=TSL2561_LUX_B5C; m=TSL2561_LUX_M5C;}
163+
else if (ratio <= TSL2561_LUX_K6C)
164+
{b=TSL2561_LUX_B6C; m=TSL2561_LUX_M6C;}
165+
else if (ratio <= TSL2561_LUX_K7C)
166+
{b=TSL2561_LUX_B7C; m=TSL2561_LUX_M7C;}
167+
else if (ratio > TSL2561_LUX_K8C)
168+
{b=TSL2561_LUX_B8C; m=TSL2561_LUX_M8C;}
169+
#else
170+
if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T))
171+
{b=TSL2561_LUX_B1T; m=TSL2561_LUX_M1T;}
172+
else if (ratio <= TSL2561_LUX_K2T)
173+
{b=TSL2561_LUX_B2T; m=TSL2561_LUX_M2T;}
174+
else if (ratio <= TSL2561_LUX_K3T)
175+
{b=TSL2561_LUX_B3T; m=TSL2561_LUX_M3T;}
176+
else if (ratio <= TSL2561_LUX_K4T)
177+
{b=TSL2561_LUX_B4T; m=TSL2561_LUX_M4T;}
178+
else if (ratio <= TSL2561_LUX_K5T)
179+
{b=TSL2561_LUX_B5T; m=TSL2561_LUX_M5T;}
180+
else if (ratio <= TSL2561_LUX_K6T)
181+
{b=TSL2561_LUX_B6T; m=TSL2561_LUX_M6T;}
182+
else if (ratio <= TSL2561_LUX_K7T)
183+
{b=TSL2561_LUX_B7T; m=TSL2561_LUX_M7T;}
184+
else if (ratio > TSL2561_LUX_K8T)
185+
{b=TSL2561_LUX_B8T; m=TSL2561_LUX_M8T;}
186+
#endif
187+
188+
unsigned long temp;
189+
temp = ((channel0 * b) - (channel1 * m));
190+
191+
// do not allow negative lux value
192+
if (temp < 0) temp = 0;
193+
194+
// round lsb (2^(LUX_SCALE-1))
195+
temp += (1 << (TSL2561_LUX_LUXSCALE-1));
196+
197+
// strip off fractional portion
198+
uint32_t lux = temp >> TSL2561_LUX_LUXSCALE;
199+
200+
// Signal I2C had no errors
201+
return lux;
202+
}
203+
204+
uint32_t TSL2561::getFullLuminosity (void)
205+
{
206+
if (!_initialized) begin();
207+
208+
// Enable the device by setting the control bit to 0x03
209+
enable();
210+
211+
// Wait x ms for ADC to complete
212+
switch (_integration)
213+
{
214+
case TSL2561_INTEGRATIONTIME_13MS:
215+
delay(14);
216+
break;
217+
case TSL2561_INTEGRATIONTIME_101MS:
218+
delay(102);
219+
break;
220+
default:
221+
delay(400);
222+
break;
223+
}
224+
225+
uint32_t x;
226+
x = read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW);
227+
x <<= 16;
228+
x |= read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW);
229+
230+
disable();
231+
232+
return x;
233+
}
234+
uint16_t TSL2561::getLuminosity (uint8_t channel) {
235+
236+
uint32_t x = getFullLuminosity();
237+
238+
if (channel == 0) {
239+
// Reads two byte value from channel 0 (visible + infrared)
240+
return (x & 0xFFFF);
241+
} else if (channel == 1) {
242+
// Reads two byte value from channel 1 (infrared)
243+
return (x >> 16);
244+
} else if (channel == 2) {
245+
// Reads all and subtracts out just the visible!
246+
return ( (x & 0xFFFF) - (x >> 16));
247+
}
248+
249+
// unknown channel!
250+
return 0;
251+
}
252+
253+
254+
uint16_t TSL2561::read16(uint8_t reg)
255+
{
256+
uint16_t x; uint16_t t;
257+
258+
Wire.beginTransmission(_addr);
259+
Wire.send(reg);
260+
Wire.endTransmission();
261+
262+
Wire.requestFrom(_addr, 2);
263+
t = Wire.receive();
264+
x = Wire.receive();
265+
x <<= 8;
266+
x |= t;
267+
return x;
268+
}
269+
270+
271+
272+
void TSL2561::write8 (uint8_t reg, uint8_t value)
273+
{
274+
Wire.beginTransmission(_addr);
275+
Wire.send(reg);
276+
Wire.send(value);
277+
Wire.endTransmission();
278+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy