diff --git a/lib/TSL2561-Arduino-Library/.github/ISSUE_TEMPLATE.md b/lib/TSL2561-Arduino-Library/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..f0e26146f --- /dev/null +++ b/lib/TSL2561-Arduino-Library/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,46 @@ +Thank you for opening an issue on an Adafruit Arduino library repository. To +improve the speed of resolution please review the following guidelines and +common troubleshooting steps below before creating the issue: + +- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use + the forums at http://forums.adafruit.com to ask questions and troubleshoot why + something isn't working as expected. In many cases the problem is a common issue + that you will more quickly receive help from the forum community. GitHub issues + are meant for known defects in the code. If you don't know if there is a defect + in the code then start with troubleshooting on the forum first. + +- **If following a tutorial or guide be sure you didn't miss a step.** Carefully + check all of the steps and commands to run have been followed. Consult the + forum if you're unsure or have questions about steps in a guide/tutorial. + +- **For Arduino projects check these very common issues to ensure they don't apply**: + + - For uploading sketches or communicating with the board make sure you're using + a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes + very hard to tell the difference between a data and charge cable! Try using the + cable with other devices or swapping to another cable to confirm it is not + the problem. + + - **Be sure you are supplying adequate power to the board.** Check the specs of + your board and plug in an external power supply. In many cases just + plugging a board into your computer is not enough to power it and other + peripherals. + + - **Double check all soldering joints and connections.** Flakey connections + cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. + + - **Ensure you are using an official Arduino or Adafruit board.** We can't + guarantee a clone board will have the same functionality and work as expected + with this code and don't support them. + +If you're sure this issue is a defect in the code and checked the steps above +please fill in the following fields to provide enough troubleshooting information. +You may delete the guideline and text above to just leave the following details: + +- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE** + +- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO + VERSION HERE** + +- List the steps to reproduce the problem below (if possible attach a sketch or + copy the sketch code in too): **LIST REPRO STEPS BELOW** diff --git a/lib/TSL2561-Arduino-Library/.github/PULL_REQUEST_TEMPLATE.md b/lib/TSL2561-Arduino-Library/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..7b641eb86 --- /dev/null +++ b/lib/TSL2561-Arduino-Library/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,26 @@ +Thank you for creating a pull request to contribute to Adafruit's GitHub code! +Before you open the request please review the following guidelines and tips to +help it be more easily integrated: + +- **Describe the scope of your change--i.e. what the change does and what parts + of the code were modified.** This will help us understand any risks of integrating + the code. + +- **Describe any known limitations with your change.** For example if the change + doesn't apply to a supported platform of the library please mention it. + +- **Please run any tests or examples that can exercise your modified code.** We + strive to not break users of the code and running tests/examples helps with this + process. + +Thank you again for contributing! We will try to test and integrate the change +as soon as we can, but be aware we have many GitHub repositories to manage and +can't immediately respond to every request. There is no need to bump or check in +on a pull request (it will clutter the discussion of the request). + +Also don't be worried if the request is closed or not integrated--sometimes the +priorities of Adafruit's GitHub code (education, ease of use) might not match the +priorities of the pull request. Don't fret, the open source community thrives on +forks and GitHub makes it easy to keep your changes in a forked repo. + +After reviewing the guidelines above you can delete this text from the pull request. diff --git a/lib/TSL2561-Arduino-Library/README.txt b/lib/TSL2561-Arduino-Library/README.txt new file mode 100644 index 000000000..f59baf9e8 --- /dev/null +++ b/lib/TSL2561-Arduino-Library/README.txt @@ -0,0 +1,7 @@ +This is an Arduino library for the TSL2561 digital luminosity (light) sensors. + +Pick one up at http://www.adafruit.com/products/439 + +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 + +Place the TSL2561 library folder your /libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE. \ No newline at end of file diff --git a/lib/TSL2561-Arduino-Library/TSL2561.cpp b/lib/TSL2561-Arduino-Library/TSL2561.cpp new file mode 100644 index 000000000..b033aad0a --- /dev/null +++ b/lib/TSL2561-Arduino-Library/TSL2561.cpp @@ -0,0 +1,301 @@ +/**************************************************************************/ +/*! + @file tsl2561.c + @author K. Townsend (microBuilder.eu / adafruit.com) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL, Adafruit Industries + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#if defined ( ESP8266 ) + #include +#else + #include + #include +#endif +#include + +#include "TSL2561.h" + +TSL2561::TSL2561(uint8_t addr) { + _addr = addr; + _initialized = false; + _integration = TSL2561_INTEGRATIONTIME_13MS; + _gain = TSL2561_GAIN_16X; + + // we cant do wire initialization till later, because we havent loaded Wire yet +} + +boolean TSL2561::begin(void) { + Wire.begin(); + + // Initialise I2C + Wire.beginTransmission(_addr); +#if ARDUINO >= 100 + Wire.write(TSL2561_REGISTER_ID); +#else + Wire.send(TSL2561_REGISTER_ID); +#endif + Wire.endTransmission(); + Wire.requestFrom(_addr, 1); +#if ARDUINO >= 100 + int x = Wire.read(); +#else + int x = Wire.receive(); +#endif + //Serial.print("0x"); Serial.println(x, HEX); + if (x & 0x0A ) { + //Serial.println("Found TSL2561"); + } else { + return false; + } + _initialized = true; + + // Set default integration time and gain + setTiming(_integration); + setGain(_gain); + // Note: by default, the device is in power down mode on bootup + disable(); + + return true; +} + +void TSL2561::enable(void) +{ + if (!_initialized) begin(); + + // Enable the device by setting the control bit to 0x03 + write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON); +} + +void TSL2561::disable(void) +{ + if (!_initialized) begin(); + + // Disable the device by setting the control bit to 0x03 + write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF); +} + + +void TSL2561::setGain(tsl2561Gain_t gain) { + if (!_initialized) begin(); + + enable(); + _gain = gain; + write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _integration | _gain); + disable(); +} + +void TSL2561::setTiming(tsl2561IntegrationTime_t integration) +{ + if (!_initialized) begin(); + + enable(); + _integration = integration; + write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _integration | _gain); + disable(); +} + +uint32_t TSL2561::calculateLux(uint16_t ch0, uint16_t ch1) +{ + unsigned long chScale; + unsigned long channel1; + unsigned long channel0; + + switch (_integration) + { + case TSL2561_INTEGRATIONTIME_13MS: + chScale = TSL2561_LUX_CHSCALE_TINT0; + break; + case TSL2561_INTEGRATIONTIME_101MS: + chScale = TSL2561_LUX_CHSCALE_TINT1; + break; + default: // No scaling ... integration time = 402ms + chScale = (1 << TSL2561_LUX_CHSCALE); + break; + } + + // Scale for gain (1x or 16x) + if (!_gain) chScale = chScale << 4; + + // scale the channel values + channel0 = (ch0 * chScale) >> TSL2561_LUX_CHSCALE; + channel1 = (ch1 * chScale) >> TSL2561_LUX_CHSCALE; + + // find the ratio of the channel values (Channel1/Channel0) + unsigned long ratio1 = 0; + if (channel0 != 0) ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE+1)) / channel0; + + // round the ratio value + unsigned long ratio = (ratio1 + 1) >> 1; + + unsigned int b, m; + +#ifdef TSL2561_PACKAGE_CS + if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C)) + {b=TSL2561_LUX_B1C; m=TSL2561_LUX_M1C;} + else if (ratio <= TSL2561_LUX_K2C) + {b=TSL2561_LUX_B2C; m=TSL2561_LUX_M2C;} + else if (ratio <= TSL2561_LUX_K3C) + {b=TSL2561_LUX_B3C; m=TSL2561_LUX_M3C;} + else if (ratio <= TSL2561_LUX_K4C) + {b=TSL2561_LUX_B4C; m=TSL2561_LUX_M4C;} + else if (ratio <= TSL2561_LUX_K5C) + {b=TSL2561_LUX_B5C; m=TSL2561_LUX_M5C;} + else if (ratio <= TSL2561_LUX_K6C) + {b=TSL2561_LUX_B6C; m=TSL2561_LUX_M6C;} + else if (ratio <= TSL2561_LUX_K7C) + {b=TSL2561_LUX_B7C; m=TSL2561_LUX_M7C;} + else if (ratio > TSL2561_LUX_K8C) + {b=TSL2561_LUX_B8C; m=TSL2561_LUX_M8C;} +#else + if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T)) + {b=TSL2561_LUX_B1T; m=TSL2561_LUX_M1T;} + else if (ratio <= TSL2561_LUX_K2T) + {b=TSL2561_LUX_B2T; m=TSL2561_LUX_M2T;} + else if (ratio <= TSL2561_LUX_K3T) + {b=TSL2561_LUX_B3T; m=TSL2561_LUX_M3T;} + else if (ratio <= TSL2561_LUX_K4T) + {b=TSL2561_LUX_B4T; m=TSL2561_LUX_M4T;} + else if (ratio <= TSL2561_LUX_K5T) + {b=TSL2561_LUX_B5T; m=TSL2561_LUX_M5T;} + else if (ratio <= TSL2561_LUX_K6T) + {b=TSL2561_LUX_B6T; m=TSL2561_LUX_M6T;} + else if (ratio <= TSL2561_LUX_K7T) + {b=TSL2561_LUX_B7T; m=TSL2561_LUX_M7T;} + else if (ratio > TSL2561_LUX_K8T) + {b=TSL2561_LUX_B8T; m=TSL2561_LUX_M8T;} +#endif + + unsigned long temp; + temp = ((channel0 * b) - (channel1 * m)); + + // do not allow negative lux value + if (temp < 0) temp = 0; + + // round lsb (2^(LUX_SCALE-1)) + temp += (1 << (TSL2561_LUX_LUXSCALE-1)); + + // strip off fractional portion + uint32_t lux = temp >> TSL2561_LUX_LUXSCALE; + + // Signal I2C had no errors + return lux; +} + +uint32_t TSL2561::getFullLuminosity (void) +{ + if (!_initialized) begin(); + + // Enable the device by setting the control bit to 0x03 + enable(); + + // Wait x ms for ADC to complete + switch (_integration) + { + case TSL2561_INTEGRATIONTIME_13MS: + delay(14); + break; + case TSL2561_INTEGRATIONTIME_101MS: + delay(102); + break; + default: + delay(403); + break; + } + + uint32_t x; + x = read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW); + x <<= 16; + x |= read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW); + + disable(); + + return x; +} +uint16_t TSL2561::getLuminosity (uint8_t channel) { + + uint32_t x = getFullLuminosity(); + + if (channel == 0) { + // Reads two byte value from channel 0 (visible + infrared) + return (x & 0xFFFF); + } else if (channel == 1) { + // Reads two byte value from channel 1 (infrared) + return (x >> 16); + } else if (channel == 2) { + // Reads all and subtracts out just the visible! + return ( (x & 0xFFFF) - (x >> 16)); + } + + // unknown channel! + return 0; +} + + +uint16_t TSL2561::read16(uint8_t reg) +{ + uint16_t x; uint16_t t; + + Wire.beginTransmission(_addr); +#if ARDUINO >= 100 + Wire.write(reg); +#else + Wire.send(reg); +#endif + Wire.endTransmission(); + + Wire.requestFrom(_addr, 2); +#if ARDUINO >= 100 + t = Wire.read(); + x = Wire.read(); +#else + t = Wire.receive(); + x = Wire.receive(); +#endif + x <<= 8; + x |= t; + return x; +} + + + +void TSL2561::write8 (uint8_t reg, uint8_t value) +{ + Wire.beginTransmission(_addr); +#if ARDUINO >= 100 + Wire.write(reg); + Wire.write(value); +#else + Wire.send(reg); + Wire.send(value); +#endif + Wire.endTransmission(); +} diff --git a/lib/TSL2561-Arduino-Library/TSL2561.h b/lib/TSL2561-Arduino-Library/TSL2561.h new file mode 100644 index 000000000..2750f2b13 --- /dev/null +++ b/lib/TSL2561-Arduino-Library/TSL2561.h @@ -0,0 +1,184 @@ + +/**************************************************************************/ +/*! + @file tsl2561.h + @author K. Townsend (microBuilder.eu) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2010, microBuilder SARL + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#ifndef _TSL2561_H_ +#define _TSL2561_H_ + +#if ARDUINO >= 100 + #include +#else + #include +#endif +#include + +#define TSL2561_VISIBLE 2 // channel 0 - channel 1 +#define TSL2561_INFRARED 1 // channel 1 +#define TSL2561_FULLSPECTRUM 0 // channel 0 + +// 3 i2c address options! +#define TSL2561_ADDR_LOW 0x29 +#define TSL2561_ADDR_FLOAT 0x39 +#define TSL2561_ADDR_HIGH 0x49 + +// Lux calculations differ slightly for CS package +//#define TSL2561_PACKAGE_CS +#define TSL2561_PACKAGE_T_FN_CL + +#define TSL2561_READBIT (0x01) + +#define TSL2561_COMMAND_BIT (0x80) // Must be 1 +#define TSL2561_CLEAR_BIT (0x40) // Clears any pending interrupt (write 1 to clear) +#define TSL2561_WORD_BIT (0x20) // 1 = read/write word (rather than byte) +#define TSL2561_BLOCK_BIT (0x10) // 1 = using block read/write + +#define TSL2561_CONTROL_POWERON (0x03) +#define TSL2561_CONTROL_POWEROFF (0x00) + +#define TSL2561_LUX_LUXSCALE (14) // Scale by 2^14 +#define TSL2561_LUX_RATIOSCALE (9) // Scale ratio by 2^9 +#define TSL2561_LUX_CHSCALE (10) // Scale channel values by 2^10 +#define TSL2561_LUX_CHSCALE_TINT0 (0x7517) // 322/11 * 2^TSL2561_LUX_CHSCALE +#define TSL2561_LUX_CHSCALE_TINT1 (0x0FE7) // 322/81 * 2^TSL2561_LUX_CHSCALE + +// T, FN and CL package values +#define TSL2561_LUX_K1T (0x0040) // 0.125 * 2^RATIO_SCALE +#define TSL2561_LUX_B1T (0x01f2) // 0.0304 * 2^LUX_SCALE +#define TSL2561_LUX_M1T (0x01be) // 0.0272 * 2^LUX_SCALE +#define TSL2561_LUX_K2T (0x0080) // 0.250 * 2^RATIO_SCALE +#define TSL2561_LUX_B2T (0x0214) // 0.0325 * 2^LUX_SCALE +#define TSL2561_LUX_M2T (0x02d1) // 0.0440 * 2^LUX_SCALE +#define TSL2561_LUX_K3T (0x00c0) // 0.375 * 2^RATIO_SCALE +#define TSL2561_LUX_B3T (0x023f) // 0.0351 * 2^LUX_SCALE +#define TSL2561_LUX_M3T (0x037b) // 0.0544 * 2^LUX_SCALE +#define TSL2561_LUX_K4T (0x0100) // 0.50 * 2^RATIO_SCALE +#define TSL2561_LUX_B4T (0x0270) // 0.0381 * 2^LUX_SCALE +#define TSL2561_LUX_M4T (0x03fe) // 0.0624 * 2^LUX_SCALE +#define TSL2561_LUX_K5T (0x0138) // 0.61 * 2^RATIO_SCALE +#define TSL2561_LUX_B5T (0x016f) // 0.0224 * 2^LUX_SCALE +#define TSL2561_LUX_M5T (0x01fc) // 0.0310 * 2^LUX_SCALE +#define TSL2561_LUX_K6T (0x019a) // 0.80 * 2^RATIO_SCALE +#define TSL2561_LUX_B6T (0x00d2) // 0.0128 * 2^LUX_SCALE +#define TSL2561_LUX_M6T (0x00fb) // 0.0153 * 2^LUX_SCALE +#define TSL2561_LUX_K7T (0x029a) // 1.3 * 2^RATIO_SCALE +#define TSL2561_LUX_B7T (0x0018) // 0.00146 * 2^LUX_SCALE +#define TSL2561_LUX_M7T (0x0012) // 0.00112 * 2^LUX_SCALE +#define TSL2561_LUX_K8T (0x029a) // 1.3 * 2^RATIO_SCALE +#define TSL2561_LUX_B8T (0x0000) // 0.000 * 2^LUX_SCALE +#define TSL2561_LUX_M8T (0x0000) // 0.000 * 2^LUX_SCALE + +// CS package values +#define TSL2561_LUX_K1C (0x0043) // 0.130 * 2^RATIO_SCALE +#define TSL2561_LUX_B1C (0x0204) // 0.0315 * 2^LUX_SCALE +#define TSL2561_LUX_M1C (0x01ad) // 0.0262 * 2^LUX_SCALE +#define TSL2561_LUX_K2C (0x0085) // 0.260 * 2^RATIO_SCALE +#define TSL2561_LUX_B2C (0x0228) // 0.0337 * 2^LUX_SCALE +#define TSL2561_LUX_M2C (0x02c1) // 0.0430 * 2^LUX_SCALE +#define TSL2561_LUX_K3C (0x00c8) // 0.390 * 2^RATIO_SCALE +#define TSL2561_LUX_B3C (0x0253) // 0.0363 * 2^LUX_SCALE +#define TSL2561_LUX_M3C (0x0363) // 0.0529 * 2^LUX_SCALE +#define TSL2561_LUX_K4C (0x010a) // 0.520 * 2^RATIO_SCALE +#define TSL2561_LUX_B4C (0x0282) // 0.0392 * 2^LUX_SCALE +#define TSL2561_LUX_M4C (0x03df) // 0.0605 * 2^LUX_SCALE +#define TSL2561_LUX_K5C (0x014d) // 0.65 * 2^RATIO_SCALE +#define TSL2561_LUX_B5C (0x0177) // 0.0229 * 2^LUX_SCALE +#define TSL2561_LUX_M5C (0x01dd) // 0.0291 * 2^LUX_SCALE +#define TSL2561_LUX_K6C (0x019a) // 0.80 * 2^RATIO_SCALE +#define TSL2561_LUX_B6C (0x0101) // 0.0157 * 2^LUX_SCALE +#define TSL2561_LUX_M6C (0x0127) // 0.0180 * 2^LUX_SCALE +#define TSL2561_LUX_K7C (0x029a) // 1.3 * 2^RATIO_SCALE +#define TSL2561_LUX_B7C (0x0037) // 0.00338 * 2^LUX_SCALE +#define TSL2561_LUX_M7C (0x002b) // 0.00260 * 2^LUX_SCALE +#define TSL2561_LUX_K8C (0x029a) // 1.3 * 2^RATIO_SCALE +#define TSL2561_LUX_B8C (0x0000) // 0.000 * 2^LUX_SCALE +#define TSL2561_LUX_M8C (0x0000) // 0.000 * 2^LUX_SCALE + +enum +{ + TSL2561_REGISTER_CONTROL = 0x00, + TSL2561_REGISTER_TIMING = 0x01, + TSL2561_REGISTER_THRESHHOLDL_LOW = 0x02, + TSL2561_REGISTER_THRESHHOLDL_HIGH = 0x03, + TSL2561_REGISTER_THRESHHOLDH_LOW = 0x04, + TSL2561_REGISTER_THRESHHOLDH_HIGH = 0x05, + TSL2561_REGISTER_INTERRUPT = 0x06, + TSL2561_REGISTER_CRC = 0x08, + TSL2561_REGISTER_ID = 0x0A, + TSL2561_REGISTER_CHAN0_LOW = 0x0C, + TSL2561_REGISTER_CHAN0_HIGH = 0x0D, + TSL2561_REGISTER_CHAN1_LOW = 0x0E, + TSL2561_REGISTER_CHAN1_HIGH = 0x0F +}; + +typedef enum +{ + TSL2561_INTEGRATIONTIME_13MS = 0x00, // 13.7ms + TSL2561_INTEGRATIONTIME_101MS = 0x01, // 101ms + TSL2561_INTEGRATIONTIME_402MS = 0x02 // 402ms +} +tsl2561IntegrationTime_t; + +typedef enum +{ + TSL2561_GAIN_0X = 0x00, // No gain + TSL2561_GAIN_16X = 0x10, // 16x gain +} +tsl2561Gain_t; + + +class TSL2561 { + public: + TSL2561(uint8_t addr); + boolean begin(void); + void enable(void); + void disable(void); + void write8(uint8_t r, uint8_t v); + uint16_t read16(uint8_t reg); + + uint32_t calculateLux(uint16_t ch0, uint16_t ch1); + void setTiming(tsl2561IntegrationTime_t integration); + void setGain(tsl2561Gain_t gain); + uint16_t getLuminosity (uint8_t channel); + uint32_t getFullLuminosity (); + + private: + int8_t _addr; + tsl2561IntegrationTime_t _integration; + tsl2561Gain_t _gain; + + boolean _initialized; +}; +#endif diff --git a/lib/TSL2561-Arduino-Library/examples/tsl2561/tsl2561.ino b/lib/TSL2561-Arduino-Library/examples/tsl2561/tsl2561.ino new file mode 100644 index 000000000..775223071 --- /dev/null +++ b/lib/TSL2561-Arduino-Library/examples/tsl2561/tsl2561.ino @@ -0,0 +1,63 @@ +#include +#include "TSL2561.h" + +// Example for demonstrating the TSL2561 library - public domain! + +// connect SCL to analog 5 +// connect SDA to analog 4 +// connect VDD to 3.3V DC +// connect GROUND to common ground +// ADDR can be connected to ground, or vdd or left floating to change the i2c address + +// The address will be different depending on whether you let +// the ADDR pin float (addr 0x39), or tie it to ground or vcc. In those cases +// use TSL2561_ADDR_LOW (0x29) or TSL2561_ADDR_HIGH (0x49) respectively +TSL2561 tsl(TSL2561_ADDR_FLOAT); + +void setup(void) { + Serial.begin(9600); + + if (tsl.begin()) { + Serial.println("Found sensor"); + } else { + Serial.println("No sensor?"); + while (1); + } + + // You can change the gain on the fly, to adapt to brighter/dimmer light situations + //tsl.setGain(TSL2561_GAIN_0X); // set no gain (for bright situtations) + tsl.setGain(TSL2561_GAIN_16X); // set 16x gain (for dim situations) + + // Changing the integration time gives you a longer time over which to sense light + // longer timelines are slower, but are good in very low light situtations! + tsl.setTiming(TSL2561_INTEGRATIONTIME_13MS); // shortest integration time (bright light) + //tsl.setTiming(TSL2561_INTEGRATIONTIME_101MS); // medium integration time (medium light) + //tsl.setTiming(TSL2561_INTEGRATIONTIME_402MS); // longest integration time (dim light) + + // Now we're ready to get readings! +} + +void loop(void) { + // Simple data read example. Just read the infrared, fullspecrtrum diode + // or 'visible' (difference between the two) channels. + // This can take 13-402 milliseconds! Uncomment whichever of the following you want to read + uint16_t x = tsl.getLuminosity(TSL2561_VISIBLE); + //uint16_t x = tsl.getLuminosity(TSL2561_FULLSPECTRUM); + //uint16_t x = tsl.getLuminosity(TSL2561_INFRARED); + + Serial.println(x, DEC); + + // More advanced data read example. Read 32 bits with top 16 bits IR, bottom 16 bits full spectrum + // That way you can do whatever math and comparisons you want! + uint32_t lum = tsl.getFullLuminosity(); + uint16_t ir, full; + ir = lum >> 16; + full = lum & 0xFFFF; + Serial.print("IR: "); Serial.print(ir); Serial.print("\t\t"); + Serial.print("Full: "); Serial.print(full); Serial.print("\t"); + Serial.print("Visible: "); Serial.print(full - ir); Serial.print("\t"); + + Serial.print("Lux: "); Serial.println(tsl.calculateLux(full, ir)); + + delay(100); +} diff --git a/lib/TSL2561-Arduino-Library/library.properties b/lib/TSL2561-Arduino-Library/library.properties new file mode 100644 index 000000000..06d22f721 --- /dev/null +++ b/lib/TSL2561-Arduino-Library/library.properties @@ -0,0 +1,9 @@ +name=TSL2561 Arduino Library +version=1.0.0 +author=Adafruit +maintainer=Adafruit +sentence=Arduino library for using the TSL2561 Luminosity sensor +paragraph=Arduino library for using the TSL2561 Luminosity sensor +category=Sensors +url=https://github.com/adafruit/TSL2561-Arduino-Library +architectures=* diff --git a/sonoff/user_config.h b/sonoff/user_config.h index 5a35fcfd0..5c4edab7b 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -175,6 +175,7 @@ #define USE_BMP // Add I2C code for BMP/BME280 sensor (+4k code) #define USE_BH1750 // Add I2C code for BH1750 sensor (+0k5 code) // #define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0k5 code) +// #define USE_TSL2561 // Add I2C code for TSL2561 sensor using library Adafruit TSL2561 Arduino (+1k2 code) // #define USE_ADS1115 // Add I2C code for ADS1115 16 bit A/D converter based on Adafruit ADS1x15 library (library not needed) (+0k7 code) // #define USE_ADS1115_I2CDEV // Add I2C code for ADS1115 16 bit A/D converter using library i2cdevlib-Core and i2cdevlib-ADS1115 (+2k code) // #define USE_INA219 // Add I2C code for INA219 Low voltage and current sensor (+1k code) diff --git a/sonoff/xsns_16_tsl2561.ino b/sonoff/xsns_16_tsl2561.ino new file mode 100644 index 000000000..24c9468fd --- /dev/null +++ b/sonoff/xsns_16_tsl2561.ino @@ -0,0 +1,113 @@ +/* + xsns_16_tsl2561.ino - TSL2561 light sensor support for Sonoff-Tasmota + + Copyright (C) 2017 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_I2C +#ifdef USE_TSL2561 +/*********************************************************************************************\ + * TSL2561 - Light Intensity + * + * I2C Addresses: 0x29 (low), 0x39 (float) or 0x49 (high) + * + * Using library https://github.com/adafruit/TSL2561-Arduino-Library +\*********************************************************************************************/ + +#include + +uint8_t tsl2561_address; +uint8_t tsl2561_addresses[] = { TSL2561_ADDR_LOW, TSL2561_ADDR_FLOAT, TSL2561_ADDR_HIGH }; +uint8_t tsl2561_type = 0; + +//TSL2561 tsl(TSL2561_ADDR_FLOAT); +TSL2561 *tsl; + +void Tsl2561Detect() +{ + if (tsl2561_type) { + return; + } + + for (byte i = 0; i < sizeof(tsl2561_addresses); i++) { + tsl2561_address = tsl2561_addresses[i]; + tsl = new TSL2561(tsl2561_address); + if (tsl->begin()) { + tsl->setGain(TSL2561_GAIN_16X); + tsl->setTiming(TSL2561_INTEGRATIONTIME_101MS); + tsl2561_type = 1; + snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "TSL2561", tsl2561_address); + AddLog(LOG_LEVEL_DEBUG); + break; + } + } +} + +#ifdef USE_WEBSERVER +const char HTTP_SNS_TSL2561[] PROGMEM = + "%s{s}TSL2561 " D_ILLUMINANCE "{m}%d " D_UNIT_LUX "{e}"; // {s} = , {m} = , {e} = +#endif // USE_WEBSERVER + +void Tsl2561Show(boolean json) +{ + if (tsl2561_type) { + uint16_t illuminance = tsl->getLuminosity(TSL2561_VISIBLE); + + if (json) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"TSL2561\":{\"" D_ILLUMINANCE "\":%d}"), mqtt_data, illuminance); +#ifdef USE_DOMOTICZ + DomoticzSensor(DZ_ILLUMINANCE, illuminance); +#endif // USE_DOMOTICZ +#ifdef USE_WEBSERVER + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TSL2561, mqtt_data, illuminance); +#endif // USE_WEBSERVER + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +#define XSNS_16 + +boolean Xsns16(byte function) +{ + boolean result = false; + + if (i2c_flg) { + switch (function) { +// case FUNC_XSNS_INIT: +// break; + case FUNC_XSNS_PREP: + Tsl2561Detect(); + break; + case FUNC_XSNS_JSON_APPEND: + Tsl2561Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_XSNS_WEB: + Tsl2561Show(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_TSL2561 +#endif // USE_I2C