A lib in development for TSL2561 light sensor communication.
Dependents: TSL2561_Townsend TSL2561_Light_sensor Light
Revision 0:df9baf6459b7, committed 2013-09-10
- Comitter:
- anhnt2407
- Date:
- Tue Sep 10 15:13:49 2013 +0000
- Child:
- 1:ab906ac6e90b
- Commit message:
- 20130911-TSL2561_Townsend
Changed in this revision
TSL2561.cpp | Show annotated file Show diff for this revision Revisions of this file |
TSL2561.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TSL2561.cpp Tue Sep 10 15:13:49 2013 +0000 @@ -0,0 +1,236 @@ + +#include "TSL2561.h" +Serial DEBUG(USBTX, USBRX); + +#define DEBUG_PRINTX(z,x) if(z==1) DEBUG.printf(x); +#define DEBUG_PRINTLNX(z,x) if(z==1) {DEBUG.printf(x); DEBUG.printf("\r\n");} +#define DEBUG_PRINTXY(z,x, y) if(z==1) DEBUG.printf(x, y); +#define DEBUG_PRINTLNXY(z,x, y) if(z==1) {DEBUG.printf(x, y); DEBUG.printf("\r\n");} + +TSL2561::TSL2561():i2c(TSL2561_I2C_PINNAME_SDA,TSL2561_I2C_PINNAME_SCL){ + i2c.frequency (300); + _addr = TSL2561_ADDR_FLOAT<<1; + _initialized = false; + _integration = TSL2561_INTEGRATIONTIME_13MS; + _gain = TSL2561_GAIN_16X; +} + +TSL2561::TSL2561(uint8_t addr):i2c(TSL2561_I2C_PINNAME_SDA,TSL2561_I2C_PINNAME_SCL) { + + _addr = addr<<1; + _initialized = false; + _integration = TSL2561_INTEGRATIONTIME_13MS; + _gain = TSL2561_GAIN_16X; + // we cant do wire initialization till later, because we havent loaded Wire yet +} + +TSL2561::TSL2561(PinName sda, PinName scl):i2c(sda, scl) { + + _addr = TSL2561_ADDR_FLOAT<<1; + _initialized = false; + _integration = TSL2561_INTEGRATIONTIME_13MS; + _gain = TSL2561_GAIN_16X; + // we cant do wire initialization till later, because we havent loaded Wire yet +} + +TSL2561::TSL2561(PinName sda, PinName scl, uint8_t addr):i2c(sda, scl) { + + _addr = addr<<1; + _initialized = false; + _integration = TSL2561_INTEGRATIONTIME_13MS; + _gain = TSL2561_GAIN_16X; + // we cant do wire initialization till later, because we havent loaded Wire yet +} + +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; +} + +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: + wait_ms(14); + break; + case TSL2561_INTEGRATIONTIME_101MS: + wait_ms(102); + break; + default: + wait_ms(403); + break; + } + +DEBUG_PRINTLNXY(1," Integration:= %d",_integration); + + uint32_t x; + x = read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW); + + DEBUG_PRINTLNXY(1," x:= %d",x); + + x <<= 16; + x |= read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW); + + DEBUG_PRINTLNXY(1," x:= %d",x); + + wait(3); + disable(); + + return x; +} + + +bool TSL2561::begin(void) { + + char reg = TSL2561_REGISTER_ID; + char read; + + i2c.start(); + i2c.write(_addr); + i2c.write(reg); + + //i2c.start(); + //i2c.write(reg); + read = i2c.read(1); + i2c.stop(); + + if (read & 0x0A ) { + DEBUG_PRINTLNXY(1,"Read 0x%x => Found TSL2561",read); + } 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; + } + + uint16_t TSL2561::read16(uint8_t reg) +{ + uint16_t x; uint16_t t; + char _x;char _t;char r[1]; + r[0] = reg; + + i2c.start(); + i2c.write(_addr); + i2c.write(reg); + + //i2c.start(); + //i2c.write(reg); + _t = i2c.read(1); + _x = i2c.read(1); + + DEBUG_PRINTLNXY(0,"%x",_x); + DEBUG_PRINTLNXY(0,"%x",_t); + + i2c.stop(); + + t=(uint16_t)&_t; + x=(uint16_t)&_x; + x <<= 8; + x |= t; + return x; +} + + void TSL2561::write8 (uint8_t reg, uint8_t value) +{ + i2c.start(); + i2c.write(_addr); + i2c.write(reg); + i2c.write(value); + i2c.stop(); +} + +void TSL2561::setTiming(tsl2561IntegrationTime_t integration){ + +if (!_initialized) begin(); + +else DEBUG_PRINTLNX(1,"--------------Set Timing---------"); + + enable(); + + _integration = integration; + + DEBUG_PRINTLNXY(1,"Integration: 0x%x",_integration); + DEBUG_PRINTLNXY(1,"Gain: 0x%x",_gain); + DEBUG_PRINTLNXY(1,"Integration | Gain: 0x%x",_integration | _gain); + + write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _integration | _gain); + + disable(); + + DEBUG_PRINTLNX(1,"--------------Complete Set Timing-------------"); + + wait(1); + +} + +void TSL2561::setGain(tsl2561Gain_t gain) { + +if (!_initialized) begin(); +else DEBUG_PRINTLNX(1,"-------------Set Gain--------------"); + + + enable(); + + DEBUG_PRINTLNXY(1,"Intergration: 0x%x",_integration); + DEBUG_PRINTLNXY(1,"Gain: 0x%x",_gain); + DEBUG_PRINTLNXY(1,"Intergration | Gain: 0x%x",_integration | _gain); + + _gain = gain; + write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _integration | _gain); + //write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _gain); + disable(); + + DEBUG_PRINTLNX(1,"---------------Complete Set Gain----------------"); + wait(1); + +} + +void TSL2561::enable(void) +{ + if (!_initialized) begin(); + + // Enable the device by setting the control bit to 0x03 + DEBUG_PRINTLNX(1," Power On"); + 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 + DEBUG_PRINTLNX(1," Power Off"); + write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TSL2561.h Tue Sep 10 15:13:49 2013 +0000 @@ -0,0 +1,152 @@ + +#ifndef _TSL2561_H_ +#define _TSL2561_H_ + +#include "mbed.h" + +#define TSL2561_I2C_PINNAME_SDA p28 +#define TSL2561_I2C_PINNAME_SCL p27 + +#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: + //---CLASS CONSTRUCTOR---// + TSL2561(); + TSL2561(uint8_t addr); + TSL2561(PinName sda, PinName scl); + TSL2561(PinName sda, PinName scl, uint8_t addr); + + bool 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: + I2C i2c; + int8_t _addr; + tsl2561IntegrationTime_t _integration; + tsl2561Gain_t _gain; + + bool _initialized; +}; +#endif \ No newline at end of file