Luminosity sensor by Texas Advanced Optoelectronic Solutions Inc.. Device combines one broadband photodiode (visible plus infrared) and one infrared-responding photodiode. Sets Gain x1 and 402mS as default.

Dependents:   MusicBoxForFathersDay FTHR_SensorHub Affich_Lum_Moist Projetv0 ... more

Committer:
kenjiArai
Date:
Fri Sep 21 22:57:07 2018 +0000
Revision:
5:5b1b625fda6f
based on Adafruit program and keep interface functions

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 5:5b1b625fda6f 1 /*!
kenjiArai 5:5b1b625fda6f 2 * @file Adafruit_TSL2561_U.cpp
kenjiArai 5:5b1b625fda6f 3 *
kenjiArai 5:5b1b625fda6f 4 * @mainpage Adafruit TSL2561 Light/Lux sensor driver
kenjiArai 5:5b1b625fda6f 5 *
kenjiArai 5:5b1b625fda6f 6 * @section intro_sec Introduction
kenjiArai 5:5b1b625fda6f 7 *
kenjiArai 5:5b1b625fda6f 8 * This is the documentation for Adafruit's TSL2561 driver for the
kenjiArai 5:5b1b625fda6f 9 * Arduino platform. It is designed specifically to work with the
kenjiArai 5:5b1b625fda6f 10 * Adafruit TSL2561 breakout: http://www.adafruit.com/products/439
kenjiArai 5:5b1b625fda6f 11 *
kenjiArai 5:5b1b625fda6f 12 * These sensors use I2C to communicate, 2 pins (SCL+SDA) are required
kenjiArai 5:5b1b625fda6f 13 * to interface with the breakout.
kenjiArai 5:5b1b625fda6f 14 *
kenjiArai 5:5b1b625fda6f 15 * Adafruit invests time and resources providing this open source code,
kenjiArai 5:5b1b625fda6f 16 * please support Adafruit and open-source hardware by purchasing
kenjiArai 5:5b1b625fda6f 17 * products from Adafruit!
kenjiArai 5:5b1b625fda6f 18 *
kenjiArai 5:5b1b625fda6f 19 * @section dependencies Dependencies
kenjiArai 5:5b1b625fda6f 20 *
kenjiArai 5:5b1b625fda6f 21 * This library depends on <a href="https://github.com/adafruit/Adafruit_Sensor">
kenjiArai 5:5b1b625fda6f 22 * Adafruit_Sensor</a> being present on your system. Please make sure you have
kenjiArai 5:5b1b625fda6f 23 * installed the latest version before using this library.
kenjiArai 5:5b1b625fda6f 24 *
kenjiArai 5:5b1b625fda6f 25 * @section author Author
kenjiArai 5:5b1b625fda6f 26 *
kenjiArai 5:5b1b625fda6f 27 * Written by Kevin "KTOWN" Townsend for Adafruit Industries.
kenjiArai 5:5b1b625fda6f 28 *
kenjiArai 5:5b1b625fda6f 29 * @section license License
kenjiArai 5:5b1b625fda6f 30 *
kenjiArai 5:5b1b625fda6f 31 * BSD license, all text here must be included in any redistribution.
kenjiArai 5:5b1b625fda6f 32 *
kenjiArai 5:5b1b625fda6f 33 * @section HISTORY
kenjiArai 5:5b1b625fda6f 34 *
kenjiArai 5:5b1b625fda6f 35 * v2.0 - Rewrote driver for Adafruit_Sensor and Auto-Gain support, and
kenjiArai 5:5b1b625fda6f 36 * added lux clipping check (returns 0 lux on sensor saturation)
kenjiArai 5:5b1b625fda6f 37 * v1.0 - First release (previously TSL2561)
kenjiArai 5:5b1b625fda6f 38 */
kenjiArai 5:5b1b625fda6f 39 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 40
kenjiArai 5:5b1b625fda6f 41 #include "Adafruit_TSL2561_U.h"
kenjiArai 5:5b1b625fda6f 42
kenjiArai 5:5b1b625fda6f 43 /*========================================================================*/
kenjiArai 5:5b1b625fda6f 44 /* CONSTRUCTORS */
kenjiArai 5:5b1b625fda6f 45 /*========================================================================*/
kenjiArai 5:5b1b625fda6f 46
kenjiArai 5:5b1b625fda6f 47 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 48 /*!
kenjiArai 5:5b1b625fda6f 49 @brief Constructor
kenjiArai 5:5b1b625fda6f 50 @param addr The I2C address this chip can be found on, 0x29, 0x39 or 0x49
kenjiArai 5:5b1b625fda6f 51 @param sensorID An optional ID that will be placed in sensor events to help
kenjiArai 5:5b1b625fda6f 52 keep track if you have many sensors in use
kenjiArai 5:5b1b625fda6f 53 */
kenjiArai 5:5b1b625fda6f 54 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 55 Adafruit_TSL2561_Unified::Adafruit_TSL2561_Unified(uint8_t addr, int32_t sensorID)
kenjiArai 5:5b1b625fda6f 56 {
kenjiArai 5:5b1b625fda6f 57 _addr = addr;
kenjiArai 5:5b1b625fda6f 58 _tsl2561Initialised = false;
kenjiArai 5:5b1b625fda6f 59 _tsl2561AutoGain = false;
kenjiArai 5:5b1b625fda6f 60 _tsl2561IntegrationTime = TSL2561_INTEGRATIONTIME_13MS;
kenjiArai 5:5b1b625fda6f 61 _tsl2561Gain = TSL2561_GAIN_1X;
kenjiArai 5:5b1b625fda6f 62 _tsl2561SensorID = sensorID;
kenjiArai 5:5b1b625fda6f 63 }
kenjiArai 5:5b1b625fda6f 64
kenjiArai 5:5b1b625fda6f 65 /*========================================================================*/
kenjiArai 5:5b1b625fda6f 66 /* PUBLIC FUNCTIONS */
kenjiArai 5:5b1b625fda6f 67 /*========================================================================*/
kenjiArai 5:5b1b625fda6f 68
kenjiArai 5:5b1b625fda6f 69 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 70 /*!
kenjiArai 5:5b1b625fda6f 71 @brief Initializes I2C and configures the sensor with default Wire I2C
kenjiArai 5:5b1b625fda6f 72 (call this function before doing anything else)
kenjiArai 5:5b1b625fda6f 73 @returns True if sensor is found and initialized, false otherwise.
kenjiArai 5:5b1b625fda6f 74 */
kenjiArai 5:5b1b625fda6f 75 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 76 boolean Adafruit_TSL2561_Unified::begin()
kenjiArai 5:5b1b625fda6f 77 {
kenjiArai 5:5b1b625fda6f 78 _i2c = &Wire;
kenjiArai 5:5b1b625fda6f 79 _i2c->begin();
kenjiArai 5:5b1b625fda6f 80 return init();
kenjiArai 5:5b1b625fda6f 81 }
kenjiArai 5:5b1b625fda6f 82
kenjiArai 5:5b1b625fda6f 83 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 84 /*!
kenjiArai 5:5b1b625fda6f 85 @brief Initializes I2C and configures the sensor with provided I2C device
kenjiArai 5:5b1b625fda6f 86 (call this function before doing anything else)
kenjiArai 5:5b1b625fda6f 87 @param theWire A pointer to any I2C interface (e.g. &Wire1)
kenjiArai 5:5b1b625fda6f 88 @returns True if sensor is found and initialized, false otherwise.
kenjiArai 5:5b1b625fda6f 89 */
kenjiArai 5:5b1b625fda6f 90 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 91 boolean Adafruit_TSL2561_Unified::begin(TwoWire *theWire)
kenjiArai 5:5b1b625fda6f 92 {
kenjiArai 5:5b1b625fda6f 93 _i2c = theWire;
kenjiArai 5:5b1b625fda6f 94 _i2c-> begin();
kenjiArai 5:5b1b625fda6f 95 return init();
kenjiArai 5:5b1b625fda6f 96 }
kenjiArai 5:5b1b625fda6f 97
kenjiArai 5:5b1b625fda6f 98 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 99 /*!
kenjiArai 5:5b1b625fda6f 100 @brief Initializes I2C connection and settings.
kenjiArai 5:5b1b625fda6f 101 Attempts to determine if the sensor is contactable, then sets up a default
kenjiArai 5:5b1b625fda6f 102 integration time and gain. Then powers down the chip.
kenjiArai 5:5b1b625fda6f 103 @returns True if sensor is found and initialized, false otherwise.
kenjiArai 5:5b1b625fda6f 104 */
kenjiArai 5:5b1b625fda6f 105 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 106 boolean Adafruit_TSL2561_Unified::init()
kenjiArai 5:5b1b625fda6f 107 {
kenjiArai 5:5b1b625fda6f 108 /* Make sure we're actually connected */
kenjiArai 5:5b1b625fda6f 109 uint8_t x = read8(TSL2561_REGISTER_ID);
kenjiArai 5:5b1b625fda6f 110 if (x & 0xF0 != 0x10) { // ID code for TSL2561
kenjiArai 5:5b1b625fda6f 111 return false;
kenjiArai 5:5b1b625fda6f 112 }
kenjiArai 5:5b1b625fda6f 113 _tsl2561Initialised = true;
kenjiArai 5:5b1b625fda6f 114
kenjiArai 5:5b1b625fda6f 115 /* Set default integration time and gain */
kenjiArai 5:5b1b625fda6f 116 setIntegrationTime(_tsl2561IntegrationTime);
kenjiArai 5:5b1b625fda6f 117 setGain(_tsl2561Gain);
kenjiArai 5:5b1b625fda6f 118
kenjiArai 5:5b1b625fda6f 119 /* Note: by default, the device is in power down mode on bootup */
kenjiArai 5:5b1b625fda6f 120 disable();
kenjiArai 5:5b1b625fda6f 121
kenjiArai 5:5b1b625fda6f 122 return true;
kenjiArai 5:5b1b625fda6f 123 }
kenjiArai 5:5b1b625fda6f 124
kenjiArai 5:5b1b625fda6f 125 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 126 /*!
kenjiArai 5:5b1b625fda6f 127 @brief Enables or disables the auto-gain settings when reading
kenjiArai 5:5b1b625fda6f 128 data from the sensor
kenjiArai 5:5b1b625fda6f 129 @param enable Set to true to enable, False to disable
kenjiArai 5:5b1b625fda6f 130 */
kenjiArai 5:5b1b625fda6f 131 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 132 void Adafruit_TSL2561_Unified::enableAutoRange(bool enable)
kenjiArai 5:5b1b625fda6f 133 {
kenjiArai 5:5b1b625fda6f 134 _tsl2561AutoGain = enable ? true : false;
kenjiArai 5:5b1b625fda6f 135 }
kenjiArai 5:5b1b625fda6f 136
kenjiArai 5:5b1b625fda6f 137 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 138 /*!
kenjiArai 5:5b1b625fda6f 139 @brief Sets the integration time for the TSL2561. Higher time means
kenjiArai 5:5b1b625fda6f 140 more light captured (better for low light conditions) but will
kenjiArai 5:5b1b625fda6f 141 take longer to run readings.
kenjiArai 5:5b1b625fda6f 142 @param time The amount of time we'd like to add up values
kenjiArai 5:5b1b625fda6f 143 */
kenjiArai 5:5b1b625fda6f 144 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 145 void Adafruit_TSL2561_Unified::setIntegrationTime(tsl2561IntegrationTime_t time)
kenjiArai 5:5b1b625fda6f 146 {
kenjiArai 5:5b1b625fda6f 147 if (!_tsl2561Initialised) begin();
kenjiArai 5:5b1b625fda6f 148
kenjiArai 5:5b1b625fda6f 149 /* Enable the device by setting the control bit to 0x03 */
kenjiArai 5:5b1b625fda6f 150 enable();
kenjiArai 5:5b1b625fda6f 151
kenjiArai 5:5b1b625fda6f 152 /* Update the timing register */
kenjiArai 5:5b1b625fda6f 153 write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, time | _tsl2561Gain);
kenjiArai 5:5b1b625fda6f 154
kenjiArai 5:5b1b625fda6f 155 /* Update value placeholders */
kenjiArai 5:5b1b625fda6f 156 _tsl2561IntegrationTime = time;
kenjiArai 5:5b1b625fda6f 157
kenjiArai 5:5b1b625fda6f 158 /* Turn the device off to save power */
kenjiArai 5:5b1b625fda6f 159 disable();
kenjiArai 5:5b1b625fda6f 160 }
kenjiArai 5:5b1b625fda6f 161
kenjiArai 5:5b1b625fda6f 162 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 163 /*!
kenjiArai 5:5b1b625fda6f 164 @brief Adjusts the gain on the TSL2561 (adjusts the sensitivity to light)
kenjiArai 5:5b1b625fda6f 165 @param gain The value we'd like to set the gain to
kenjiArai 5:5b1b625fda6f 166 */
kenjiArai 5:5b1b625fda6f 167 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 168 void Adafruit_TSL2561_Unified::setGain(tsl2561Gain_t gain)
kenjiArai 5:5b1b625fda6f 169 {
kenjiArai 5:5b1b625fda6f 170 if (!_tsl2561Initialised) begin();
kenjiArai 5:5b1b625fda6f 171
kenjiArai 5:5b1b625fda6f 172 /* Enable the device by setting the control bit to 0x03 */
kenjiArai 5:5b1b625fda6f 173 enable();
kenjiArai 5:5b1b625fda6f 174
kenjiArai 5:5b1b625fda6f 175 /* Update the timing register */
kenjiArai 5:5b1b625fda6f 176 write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _tsl2561IntegrationTime | gain);
kenjiArai 5:5b1b625fda6f 177
kenjiArai 5:5b1b625fda6f 178 /* Update value placeholders */
kenjiArai 5:5b1b625fda6f 179 _tsl2561Gain = gain;
kenjiArai 5:5b1b625fda6f 180
kenjiArai 5:5b1b625fda6f 181 /* Turn the device off to save power */
kenjiArai 5:5b1b625fda6f 182 disable();
kenjiArai 5:5b1b625fda6f 183 }
kenjiArai 5:5b1b625fda6f 184
kenjiArai 5:5b1b625fda6f 185 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 186 /*!
kenjiArai 5:5b1b625fda6f 187 @brief Gets the broadband (mixed lighting) and IR only values from
kenjiArai 5:5b1b625fda6f 188 the TSL2561, adjusting gain if auto-gain is enabled
kenjiArai 5:5b1b625fda6f 189 @param broadband Pointer to a uint16_t we will fill with a sensor
kenjiArai 5:5b1b625fda6f 190 reading from the IR+visible light diode.
kenjiArai 5:5b1b625fda6f 191 @param ir Pointer to a uint16_t we will fill with a sensor the
kenjiArai 5:5b1b625fda6f 192 IR-only light diode.
kenjiArai 5:5b1b625fda6f 193 */
kenjiArai 5:5b1b625fda6f 194 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 195 void Adafruit_TSL2561_Unified::getLuminosity (uint16_t *broadband, uint16_t *ir)
kenjiArai 5:5b1b625fda6f 196 {
kenjiArai 5:5b1b625fda6f 197 bool valid = false;
kenjiArai 5:5b1b625fda6f 198
kenjiArai 5:5b1b625fda6f 199 if (!_tsl2561Initialised) begin();
kenjiArai 5:5b1b625fda6f 200
kenjiArai 5:5b1b625fda6f 201 /* If Auto gain disabled get a single reading and continue */
kenjiArai 5:5b1b625fda6f 202 if(!_tsl2561AutoGain)
kenjiArai 5:5b1b625fda6f 203 {
kenjiArai 5:5b1b625fda6f 204 getData (broadband, ir);
kenjiArai 5:5b1b625fda6f 205 return;
kenjiArai 5:5b1b625fda6f 206 }
kenjiArai 5:5b1b625fda6f 207
kenjiArai 5:5b1b625fda6f 208 /* Read data until we find a valid range */
kenjiArai 5:5b1b625fda6f 209 bool _agcCheck = false;
kenjiArai 5:5b1b625fda6f 210 do
kenjiArai 5:5b1b625fda6f 211 {
kenjiArai 5:5b1b625fda6f 212 uint16_t _b, _ir;
kenjiArai 5:5b1b625fda6f 213 uint16_t _hi, _lo;
kenjiArai 5:5b1b625fda6f 214 tsl2561IntegrationTime_t _it = _tsl2561IntegrationTime;
kenjiArai 5:5b1b625fda6f 215
kenjiArai 5:5b1b625fda6f 216 /* Get the hi/low threshold for the current integration time */
kenjiArai 5:5b1b625fda6f 217 switch(_it)
kenjiArai 5:5b1b625fda6f 218 {
kenjiArai 5:5b1b625fda6f 219 case TSL2561_INTEGRATIONTIME_13MS:
kenjiArai 5:5b1b625fda6f 220 _hi = TSL2561_AGC_THI_13MS;
kenjiArai 5:5b1b625fda6f 221 _lo = TSL2561_AGC_TLO_13MS;
kenjiArai 5:5b1b625fda6f 222 break;
kenjiArai 5:5b1b625fda6f 223 case TSL2561_INTEGRATIONTIME_101MS:
kenjiArai 5:5b1b625fda6f 224 _hi = TSL2561_AGC_THI_101MS;
kenjiArai 5:5b1b625fda6f 225 _lo = TSL2561_AGC_TLO_101MS;
kenjiArai 5:5b1b625fda6f 226 break;
kenjiArai 5:5b1b625fda6f 227 default:
kenjiArai 5:5b1b625fda6f 228 _hi = TSL2561_AGC_THI_402MS;
kenjiArai 5:5b1b625fda6f 229 _lo = TSL2561_AGC_TLO_402MS;
kenjiArai 5:5b1b625fda6f 230 break;
kenjiArai 5:5b1b625fda6f 231 }
kenjiArai 5:5b1b625fda6f 232
kenjiArai 5:5b1b625fda6f 233 getData(&_b, &_ir);
kenjiArai 5:5b1b625fda6f 234
kenjiArai 5:5b1b625fda6f 235 /* Run an auto-gain check if we haven't already done so ... */
kenjiArai 5:5b1b625fda6f 236 if (!_agcCheck)
kenjiArai 5:5b1b625fda6f 237 {
kenjiArai 5:5b1b625fda6f 238 if ((_b < _lo) && (_tsl2561Gain == TSL2561_GAIN_1X))
kenjiArai 5:5b1b625fda6f 239 {
kenjiArai 5:5b1b625fda6f 240 /* Increase the gain and try again */
kenjiArai 5:5b1b625fda6f 241 setGain(TSL2561_GAIN_16X);
kenjiArai 5:5b1b625fda6f 242 /* Drop the previous conversion results */
kenjiArai 5:5b1b625fda6f 243 getData(&_b, &_ir);
kenjiArai 5:5b1b625fda6f 244 /* Set a flag to indicate we've adjusted the gain */
kenjiArai 5:5b1b625fda6f 245 _agcCheck = true;
kenjiArai 5:5b1b625fda6f 246 }
kenjiArai 5:5b1b625fda6f 247 else if ((_b > _hi) && (_tsl2561Gain == TSL2561_GAIN_16X))
kenjiArai 5:5b1b625fda6f 248 {
kenjiArai 5:5b1b625fda6f 249 /* Drop gain to 1x and try again */
kenjiArai 5:5b1b625fda6f 250 setGain(TSL2561_GAIN_1X);
kenjiArai 5:5b1b625fda6f 251 /* Drop the previous conversion results */
kenjiArai 5:5b1b625fda6f 252 getData(&_b, &_ir);
kenjiArai 5:5b1b625fda6f 253 /* Set a flag to indicate we've adjusted the gain */
kenjiArai 5:5b1b625fda6f 254 _agcCheck = true;
kenjiArai 5:5b1b625fda6f 255 }
kenjiArai 5:5b1b625fda6f 256 else
kenjiArai 5:5b1b625fda6f 257 {
kenjiArai 5:5b1b625fda6f 258 /* Nothing to look at here, keep moving ....
kenjiArai 5:5b1b625fda6f 259 Reading is either valid, or we're already at the chips limits */
kenjiArai 5:5b1b625fda6f 260 *broadband = _b;
kenjiArai 5:5b1b625fda6f 261 *ir = _ir;
kenjiArai 5:5b1b625fda6f 262 valid = true;
kenjiArai 5:5b1b625fda6f 263 }
kenjiArai 5:5b1b625fda6f 264 }
kenjiArai 5:5b1b625fda6f 265 else
kenjiArai 5:5b1b625fda6f 266 {
kenjiArai 5:5b1b625fda6f 267 /* If we've already adjusted the gain once, just return the new results.
kenjiArai 5:5b1b625fda6f 268 This avoids endless loops where a value is at one extreme pre-gain,
kenjiArai 5:5b1b625fda6f 269 and the the other extreme post-gain */
kenjiArai 5:5b1b625fda6f 270 *broadband = _b;
kenjiArai 5:5b1b625fda6f 271 *ir = _ir;
kenjiArai 5:5b1b625fda6f 272 valid = true;
kenjiArai 5:5b1b625fda6f 273 }
kenjiArai 5:5b1b625fda6f 274 } while (!valid);
kenjiArai 5:5b1b625fda6f 275 }
kenjiArai 5:5b1b625fda6f 276
kenjiArai 5:5b1b625fda6f 277
kenjiArai 5:5b1b625fda6f 278
kenjiArai 5:5b1b625fda6f 279 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 280 /*!
kenjiArai 5:5b1b625fda6f 281 Enables the device
kenjiArai 5:5b1b625fda6f 282 */
kenjiArai 5:5b1b625fda6f 283 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 284 void Adafruit_TSL2561_Unified::enable(void)
kenjiArai 5:5b1b625fda6f 285 {
kenjiArai 5:5b1b625fda6f 286 /* Enable the device by setting the control bit to 0x03 */
kenjiArai 5:5b1b625fda6f 287 write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON);
kenjiArai 5:5b1b625fda6f 288 }
kenjiArai 5:5b1b625fda6f 289
kenjiArai 5:5b1b625fda6f 290 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 291 /*!
kenjiArai 5:5b1b625fda6f 292 Disables the device (putting it in lower power sleep mode)
kenjiArai 5:5b1b625fda6f 293 */
kenjiArai 5:5b1b625fda6f 294 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 295 void Adafruit_TSL2561_Unified::disable(void)
kenjiArai 5:5b1b625fda6f 296 {
kenjiArai 5:5b1b625fda6f 297 /* Turn the device off to save power */
kenjiArai 5:5b1b625fda6f 298 write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF);
kenjiArai 5:5b1b625fda6f 299 }
kenjiArai 5:5b1b625fda6f 300
kenjiArai 5:5b1b625fda6f 301 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 302 /*!
kenjiArai 5:5b1b625fda6f 303 Private function to read luminosity on both channels
kenjiArai 5:5b1b625fda6f 304 */
kenjiArai 5:5b1b625fda6f 305 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 306 void Adafruit_TSL2561_Unified::getData (uint16_t *broadband, uint16_t *ir)
kenjiArai 5:5b1b625fda6f 307 {
kenjiArai 5:5b1b625fda6f 308 /* Enable the device by setting the control bit to 0x03 */
kenjiArai 5:5b1b625fda6f 309 enable();
kenjiArai 5:5b1b625fda6f 310
kenjiArai 5:5b1b625fda6f 311 /* Wait x ms for ADC to complete */
kenjiArai 5:5b1b625fda6f 312 switch (_tsl2561IntegrationTime)
kenjiArai 5:5b1b625fda6f 313 {
kenjiArai 5:5b1b625fda6f 314 case TSL2561_INTEGRATIONTIME_13MS:
kenjiArai 5:5b1b625fda6f 315 delay(TSL2561_DELAY_INTTIME_13MS); // KTOWN: Was 14ms
kenjiArai 5:5b1b625fda6f 316 break;
kenjiArai 5:5b1b625fda6f 317 case TSL2561_INTEGRATIONTIME_101MS:
kenjiArai 5:5b1b625fda6f 318 delay(TSL2561_DELAY_INTTIME_101MS); // KTOWN: Was 102ms
kenjiArai 5:5b1b625fda6f 319 break;
kenjiArai 5:5b1b625fda6f 320 default:
kenjiArai 5:5b1b625fda6f 321 delay(TSL2561_DELAY_INTTIME_402MS); // KTOWN: Was 403ms
kenjiArai 5:5b1b625fda6f 322 break;
kenjiArai 5:5b1b625fda6f 323 }
kenjiArai 5:5b1b625fda6f 324
kenjiArai 5:5b1b625fda6f 325 /* Reads a two byte value from channel 0 (visible + infrared) */
kenjiArai 5:5b1b625fda6f 326 *broadband = read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW);
kenjiArai 5:5b1b625fda6f 327
kenjiArai 5:5b1b625fda6f 328 /* Reads a two byte value from channel 1 (infrared) */
kenjiArai 5:5b1b625fda6f 329 *ir = read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW);
kenjiArai 5:5b1b625fda6f 330
kenjiArai 5:5b1b625fda6f 331 /* Turn the device off to save power */
kenjiArai 5:5b1b625fda6f 332 disable();
kenjiArai 5:5b1b625fda6f 333 }
kenjiArai 5:5b1b625fda6f 334
kenjiArai 5:5b1b625fda6f 335
kenjiArai 5:5b1b625fda6f 336 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 337 /*!
kenjiArai 5:5b1b625fda6f 338 @brief Converts the raw sensor values to the standard SI lux equivalent.
kenjiArai 5:5b1b625fda6f 339 @param broadband The 16-bit sensor reading from the IR+visible light diode.
kenjiArai 5:5b1b625fda6f 340 @param ir The 16-bit sensor reading from the IR-only light diode.
kenjiArai 5:5b1b625fda6f 341 @returns The integer Lux value we calcuated.
kenjiArai 5:5b1b625fda6f 342 Returns 0 if the sensor is saturated and the values are
kenjiArai 5:5b1b625fda6f 343 unreliable, or 65536 if the sensor is saturated.
kenjiArai 5:5b1b625fda6f 344 */
kenjiArai 5:5b1b625fda6f 345 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 346 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 347 /*!
kenjiArai 5:5b1b625fda6f 348
kenjiArai 5:5b1b625fda6f 349 Returns
kenjiArai 5:5b1b625fda6f 350 */
kenjiArai 5:5b1b625fda6f 351 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 352 uint32_t Adafruit_TSL2561_Unified::calculateLux(uint16_t broadband, uint16_t ir)
kenjiArai 5:5b1b625fda6f 353 {
kenjiArai 5:5b1b625fda6f 354 unsigned long chScale;
kenjiArai 5:5b1b625fda6f 355 unsigned long channel1;
kenjiArai 5:5b1b625fda6f 356 unsigned long channel0;
kenjiArai 5:5b1b625fda6f 357
kenjiArai 5:5b1b625fda6f 358 /* Make sure the sensor isn't saturated! */
kenjiArai 5:5b1b625fda6f 359 uint16_t clipThreshold;
kenjiArai 5:5b1b625fda6f 360 switch (_tsl2561IntegrationTime)
kenjiArai 5:5b1b625fda6f 361 {
kenjiArai 5:5b1b625fda6f 362 case TSL2561_INTEGRATIONTIME_13MS:
kenjiArai 5:5b1b625fda6f 363 clipThreshold = TSL2561_CLIPPING_13MS;
kenjiArai 5:5b1b625fda6f 364 break;
kenjiArai 5:5b1b625fda6f 365 case TSL2561_INTEGRATIONTIME_101MS:
kenjiArai 5:5b1b625fda6f 366 clipThreshold = TSL2561_CLIPPING_101MS;
kenjiArai 5:5b1b625fda6f 367 break;
kenjiArai 5:5b1b625fda6f 368 default:
kenjiArai 5:5b1b625fda6f 369 clipThreshold = TSL2561_CLIPPING_402MS;
kenjiArai 5:5b1b625fda6f 370 break;
kenjiArai 5:5b1b625fda6f 371 }
kenjiArai 5:5b1b625fda6f 372
kenjiArai 5:5b1b625fda6f 373 /* Return 65536 lux if the sensor is saturated */
kenjiArai 5:5b1b625fda6f 374 if ((broadband > clipThreshold) || (ir > clipThreshold))
kenjiArai 5:5b1b625fda6f 375 {
kenjiArai 5:5b1b625fda6f 376 return 65536;
kenjiArai 5:5b1b625fda6f 377 }
kenjiArai 5:5b1b625fda6f 378
kenjiArai 5:5b1b625fda6f 379 /* Get the correct scale depending on the intergration time */
kenjiArai 5:5b1b625fda6f 380 switch (_tsl2561IntegrationTime)
kenjiArai 5:5b1b625fda6f 381 {
kenjiArai 5:5b1b625fda6f 382 case TSL2561_INTEGRATIONTIME_13MS:
kenjiArai 5:5b1b625fda6f 383 chScale = TSL2561_LUX_CHSCALE_TINT0;
kenjiArai 5:5b1b625fda6f 384 break;
kenjiArai 5:5b1b625fda6f 385 case TSL2561_INTEGRATIONTIME_101MS:
kenjiArai 5:5b1b625fda6f 386 chScale = TSL2561_LUX_CHSCALE_TINT1;
kenjiArai 5:5b1b625fda6f 387 break;
kenjiArai 5:5b1b625fda6f 388 default: /* No scaling ... integration time = 402ms */
kenjiArai 5:5b1b625fda6f 389 chScale = (1 << TSL2561_LUX_CHSCALE);
kenjiArai 5:5b1b625fda6f 390 break;
kenjiArai 5:5b1b625fda6f 391 }
kenjiArai 5:5b1b625fda6f 392
kenjiArai 5:5b1b625fda6f 393 /* Scale for gain (1x or 16x) */
kenjiArai 5:5b1b625fda6f 394 if (!_tsl2561Gain) chScale = chScale << 4;
kenjiArai 5:5b1b625fda6f 395
kenjiArai 5:5b1b625fda6f 396 /* Scale the channel values */
kenjiArai 5:5b1b625fda6f 397 channel0 = (broadband * chScale) >> TSL2561_LUX_CHSCALE;
kenjiArai 5:5b1b625fda6f 398 channel1 = (ir * chScale) >> TSL2561_LUX_CHSCALE;
kenjiArai 5:5b1b625fda6f 399
kenjiArai 5:5b1b625fda6f 400 /* Find the ratio of the channel values (Channel1/Channel0) */
kenjiArai 5:5b1b625fda6f 401 unsigned long ratio1 = 0;
kenjiArai 5:5b1b625fda6f 402 if (channel0 != 0) ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE+1)) / channel0;
kenjiArai 5:5b1b625fda6f 403
kenjiArai 5:5b1b625fda6f 404 /* round the ratio value */
kenjiArai 5:5b1b625fda6f 405 unsigned long ratio = (ratio1 + 1) >> 1;
kenjiArai 5:5b1b625fda6f 406
kenjiArai 5:5b1b625fda6f 407 unsigned int b, m;
kenjiArai 5:5b1b625fda6f 408
kenjiArai 5:5b1b625fda6f 409 #ifdef TSL2561_PACKAGE_CS
kenjiArai 5:5b1b625fda6f 410 if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C))
kenjiArai 5:5b1b625fda6f 411 {b=TSL2561_LUX_B1C; m=TSL2561_LUX_M1C;}
kenjiArai 5:5b1b625fda6f 412 else if (ratio <= TSL2561_LUX_K2C)
kenjiArai 5:5b1b625fda6f 413 {b=TSL2561_LUX_B2C; m=TSL2561_LUX_M2C;}
kenjiArai 5:5b1b625fda6f 414 else if (ratio <= TSL2561_LUX_K3C)
kenjiArai 5:5b1b625fda6f 415 {b=TSL2561_LUX_B3C; m=TSL2561_LUX_M3C;}
kenjiArai 5:5b1b625fda6f 416 else if (ratio <= TSL2561_LUX_K4C)
kenjiArai 5:5b1b625fda6f 417 {b=TSL2561_LUX_B4C; m=TSL2561_LUX_M4C;}
kenjiArai 5:5b1b625fda6f 418 else if (ratio <= TSL2561_LUX_K5C)
kenjiArai 5:5b1b625fda6f 419 {b=TSL2561_LUX_B5C; m=TSL2561_LUX_M5C;}
kenjiArai 5:5b1b625fda6f 420 else if (ratio <= TSL2561_LUX_K6C)
kenjiArai 5:5b1b625fda6f 421 {b=TSL2561_LUX_B6C; m=TSL2561_LUX_M6C;}
kenjiArai 5:5b1b625fda6f 422 else if (ratio <= TSL2561_LUX_K7C)
kenjiArai 5:5b1b625fda6f 423 {b=TSL2561_LUX_B7C; m=TSL2561_LUX_M7C;}
kenjiArai 5:5b1b625fda6f 424 else if (ratio > TSL2561_LUX_K8C)
kenjiArai 5:5b1b625fda6f 425 {b=TSL2561_LUX_B8C; m=TSL2561_LUX_M8C;}
kenjiArai 5:5b1b625fda6f 426 #else
kenjiArai 5:5b1b625fda6f 427 if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T))
kenjiArai 5:5b1b625fda6f 428 {b=TSL2561_LUX_B1T; m=TSL2561_LUX_M1T;}
kenjiArai 5:5b1b625fda6f 429 else if (ratio <= TSL2561_LUX_K2T)
kenjiArai 5:5b1b625fda6f 430 {b=TSL2561_LUX_B2T; m=TSL2561_LUX_M2T;}
kenjiArai 5:5b1b625fda6f 431 else if (ratio <= TSL2561_LUX_K3T)
kenjiArai 5:5b1b625fda6f 432 {b=TSL2561_LUX_B3T; m=TSL2561_LUX_M3T;}
kenjiArai 5:5b1b625fda6f 433 else if (ratio <= TSL2561_LUX_K4T)
kenjiArai 5:5b1b625fda6f 434 {b=TSL2561_LUX_B4T; m=TSL2561_LUX_M4T;}
kenjiArai 5:5b1b625fda6f 435 else if (ratio <= TSL2561_LUX_K5T)
kenjiArai 5:5b1b625fda6f 436 {b=TSL2561_LUX_B5T; m=TSL2561_LUX_M5T;}
kenjiArai 5:5b1b625fda6f 437 else if (ratio <= TSL2561_LUX_K6T)
kenjiArai 5:5b1b625fda6f 438 {b=TSL2561_LUX_B6T; m=TSL2561_LUX_M6T;}
kenjiArai 5:5b1b625fda6f 439 else if (ratio <= TSL2561_LUX_K7T)
kenjiArai 5:5b1b625fda6f 440 {b=TSL2561_LUX_B7T; m=TSL2561_LUX_M7T;}
kenjiArai 5:5b1b625fda6f 441 else if (ratio > TSL2561_LUX_K8T)
kenjiArai 5:5b1b625fda6f 442 {b=TSL2561_LUX_B8T; m=TSL2561_LUX_M8T;}
kenjiArai 5:5b1b625fda6f 443 #endif
kenjiArai 5:5b1b625fda6f 444
kenjiArai 5:5b1b625fda6f 445 unsigned long temp;
kenjiArai 5:5b1b625fda6f 446 temp = ((channel0 * b) - (channel1 * m));
kenjiArai 5:5b1b625fda6f 447
kenjiArai 5:5b1b625fda6f 448 /* Do not allow negative lux value */
kenjiArai 5:5b1b625fda6f 449 if (temp < 0) temp = 0;
kenjiArai 5:5b1b625fda6f 450
kenjiArai 5:5b1b625fda6f 451 /* Round lsb (2^(LUX_SCALE-1)) */
kenjiArai 5:5b1b625fda6f 452 temp += (1 << (TSL2561_LUX_LUXSCALE-1));
kenjiArai 5:5b1b625fda6f 453
kenjiArai 5:5b1b625fda6f 454 /* Strip off fractional portion */
kenjiArai 5:5b1b625fda6f 455 uint32_t lux = temp >> TSL2561_LUX_LUXSCALE;
kenjiArai 5:5b1b625fda6f 456
kenjiArai 5:5b1b625fda6f 457 /* Signal I2C had no errors */
kenjiArai 5:5b1b625fda6f 458 return lux;
kenjiArai 5:5b1b625fda6f 459 }
kenjiArai 5:5b1b625fda6f 460
kenjiArai 5:5b1b625fda6f 461 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 462 /*!
kenjiArai 5:5b1b625fda6f 463 @brief Gets the most recent sensor event
kenjiArai 5:5b1b625fda6f 464 @param event Pointer to a sensor_event_t type that will be filled
kenjiArai 5:5b1b625fda6f 465 with the lux value, timestamp, data type and sensor ID.
kenjiArai 5:5b1b625fda6f 466 @returns True if sensor reading is between 0 and 65535 lux,
kenjiArai 5:5b1b625fda6f 467 false if sensor is saturated
kenjiArai 5:5b1b625fda6f 468 */
kenjiArai 5:5b1b625fda6f 469 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 470 bool Adafruit_TSL2561_Unified::getEvent(sensors_event_t *event)
kenjiArai 5:5b1b625fda6f 471 {
kenjiArai 5:5b1b625fda6f 472 uint16_t broadband, ir;
kenjiArai 5:5b1b625fda6f 473
kenjiArai 5:5b1b625fda6f 474 /* Clear the event */
kenjiArai 5:5b1b625fda6f 475 memset(event, 0, sizeof(sensors_event_t));
kenjiArai 5:5b1b625fda6f 476
kenjiArai 5:5b1b625fda6f 477 event->version = sizeof(sensors_event_t);
kenjiArai 5:5b1b625fda6f 478 event->sensor_id = _tsl2561SensorID;
kenjiArai 5:5b1b625fda6f 479 event->type = SENSOR_TYPE_LIGHT;
kenjiArai 5:5b1b625fda6f 480 event->timestamp = millis();
kenjiArai 5:5b1b625fda6f 481
kenjiArai 5:5b1b625fda6f 482 /* Calculate the actual lux value */
kenjiArai 5:5b1b625fda6f 483 getLuminosity(&broadband, &ir);
kenjiArai 5:5b1b625fda6f 484 event->light = calculateLux(broadband, ir);
kenjiArai 5:5b1b625fda6f 485
kenjiArai 5:5b1b625fda6f 486 if (event->light == 65536) {
kenjiArai 5:5b1b625fda6f 487 return false;
kenjiArai 5:5b1b625fda6f 488 }
kenjiArai 5:5b1b625fda6f 489 return true;
kenjiArai 5:5b1b625fda6f 490 }
kenjiArai 5:5b1b625fda6f 491
kenjiArai 5:5b1b625fda6f 492 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 493 /*!
kenjiArai 5:5b1b625fda6f 494 @brief Gets the sensor_t data
kenjiArai 5:5b1b625fda6f 495 @param sensor A pointer to a sensor_t structure that we will fill with
kenjiArai 5:5b1b625fda6f 496 details about the TSL2561 and its capabilities
kenjiArai 5:5b1b625fda6f 497 */
kenjiArai 5:5b1b625fda6f 498 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 499 void Adafruit_TSL2561_Unified::getSensor(sensor_t *sensor)
kenjiArai 5:5b1b625fda6f 500 {
kenjiArai 5:5b1b625fda6f 501 /* Clear the sensor_t object */
kenjiArai 5:5b1b625fda6f 502 memset(sensor, 0, sizeof(sensor_t));
kenjiArai 5:5b1b625fda6f 503
kenjiArai 5:5b1b625fda6f 504 /* Insert the sensor name in the fixed length char array */
kenjiArai 5:5b1b625fda6f 505 strncpy (sensor->name, "TSL2561", sizeof(sensor->name) - 1);
kenjiArai 5:5b1b625fda6f 506 sensor->name[sizeof(sensor->name)- 1] = 0;
kenjiArai 5:5b1b625fda6f 507 sensor->version = 1;
kenjiArai 5:5b1b625fda6f 508 sensor->sensor_id = _tsl2561SensorID;
kenjiArai 5:5b1b625fda6f 509 sensor->type = SENSOR_TYPE_LIGHT;
kenjiArai 5:5b1b625fda6f 510 sensor->min_delay = 0;
kenjiArai 5:5b1b625fda6f 511 sensor->max_value = 17000.0; /* Based on trial and error ... confirm! */
kenjiArai 5:5b1b625fda6f 512 sensor->min_value = 1.0;
kenjiArai 5:5b1b625fda6f 513 sensor->resolution = 1.0;
kenjiArai 5:5b1b625fda6f 514 }
kenjiArai 5:5b1b625fda6f 515
kenjiArai 5:5b1b625fda6f 516
kenjiArai 5:5b1b625fda6f 517
kenjiArai 5:5b1b625fda6f 518 /*========================================================================*/
kenjiArai 5:5b1b625fda6f 519 /* PRIVATE FUNCTIONS */
kenjiArai 5:5b1b625fda6f 520 /*========================================================================*/
kenjiArai 5:5b1b625fda6f 521
kenjiArai 5:5b1b625fda6f 522 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 523 /*!
kenjiArai 5:5b1b625fda6f 524 @brief Writes a register and an 8 bit value over I2C
kenjiArai 5:5b1b625fda6f 525 @param reg I2C register to write the value to
kenjiArai 5:5b1b625fda6f 526 @param value The 8-bit value we're writing to the register
kenjiArai 5:5b1b625fda6f 527 */
kenjiArai 5:5b1b625fda6f 528 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 529 void Adafruit_TSL2561_Unified::write8 (uint8_t reg, uint8_t value)
kenjiArai 5:5b1b625fda6f 530 {
kenjiArai 5:5b1b625fda6f 531 _i2c->beginTransmission(_addr);
kenjiArai 5:5b1b625fda6f 532 _i2c->write(reg);
kenjiArai 5:5b1b625fda6f 533 _i2c->write(value);
kenjiArai 5:5b1b625fda6f 534 _i2c->endTransmission();
kenjiArai 5:5b1b625fda6f 535 }
kenjiArai 5:5b1b625fda6f 536
kenjiArai 5:5b1b625fda6f 537 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 538 /*!
kenjiArai 5:5b1b625fda6f 539 @brief Reads an 8 bit value over I2C
kenjiArai 5:5b1b625fda6f 540 @param reg I2C register to read from
kenjiArai 5:5b1b625fda6f 541 @returns 8-bit value containing single byte data read
kenjiArai 5:5b1b625fda6f 542 */
kenjiArai 5:5b1b625fda6f 543 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 544 uint8_t Adafruit_TSL2561_Unified::read8(uint8_t reg)
kenjiArai 5:5b1b625fda6f 545 {
kenjiArai 5:5b1b625fda6f 546 _i2c->beginTransmission(_addr);
kenjiArai 5:5b1b625fda6f 547 _i2c->write(reg);
kenjiArai 5:5b1b625fda6f 548 _i2c->endTransmission();
kenjiArai 5:5b1b625fda6f 549
kenjiArai 5:5b1b625fda6f 550 _i2c->requestFrom(_addr, 1);
kenjiArai 5:5b1b625fda6f 551 return _i2c-> read();
kenjiArai 5:5b1b625fda6f 552 }
kenjiArai 5:5b1b625fda6f 553
kenjiArai 5:5b1b625fda6f 554 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 555 /*!
kenjiArai 5:5b1b625fda6f 556 @brief Reads a 16 bit values over I2C
kenjiArai 5:5b1b625fda6f 557 @param reg I2C register to read from
kenjiArai 5:5b1b625fda6f 558 @returns 16-bit value containing 2-byte data read
kenjiArai 5:5b1b625fda6f 559 */
kenjiArai 5:5b1b625fda6f 560 /**************************************************************************/
kenjiArai 5:5b1b625fda6f 561 uint16_t Adafruit_TSL2561_Unified::read16(uint8_t reg)
kenjiArai 5:5b1b625fda6f 562 {
kenjiArai 5:5b1b625fda6f 563 uint16_t x, t;
kenjiArai 5:5b1b625fda6f 564
kenjiArai 5:5b1b625fda6f 565 _i2c->beginTransmission(_addr);
kenjiArai 5:5b1b625fda6f 566 _i2c->write(reg);
kenjiArai 5:5b1b625fda6f 567 _i2c->endTransmission();
kenjiArai 5:5b1b625fda6f 568
kenjiArai 5:5b1b625fda6f 569 _i2c->requestFrom(_addr, 2);
kenjiArai 5:5b1b625fda6f 570 t = _i2c->read();
kenjiArai 5:5b1b625fda6f 571 x = _i2c->read();
kenjiArai 5:5b1b625fda6f 572 x <<= 8;
kenjiArai 5:5b1b625fda6f 573 x |= t;
kenjiArai 5:5b1b625fda6f 574 return x;
kenjiArai 5:5b1b625fda6f 575 }