TSL2561

Dependents:   Hexi_TSL2561 HexiHeart_Main

Fork of TSL2561 by Kenji Arai

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TSL2561.cpp Source File

TSL2561.cpp

00001 /*
00002  * mbed library program
00003  *  Luminosity sensor -- LIGHT-TO-DIGITAL CONVERTER (light intensity to a digital signal output)
00004  *  TSL2561 by Texas Advanced Optoelectronic Solutions Inc.
00005  *
00006  * Copyright (c) 2015,'17 Kenji Arai / JH1PJL
00007  *  http://www.page.sannet.ne.jp/kenjia/index.html
00008  *  http://mbed.org/users/kenjiArai/
00009  *      Created: Feburary   21st, 2015
00010  *      Revised: August     23rd, 2017
00011  */
00012 
00013 #include "TSL2561.h"
00014 
00015 TSL2561::TSL2561 (PinName p_sda, PinName p_scl)
00016  : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
00017 {
00018     TSL2561_addr = TSL2561_ADDRESS_GND;
00019     init();
00020 }
00021 
00022 TSL2561::TSL2561 (PinName p_sda, PinName p_scl, uint8_t addr)
00023  : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
00024 {
00025     TSL2561_addr = addr;
00026     init();
00027 }
00028 
00029 TSL2561::TSL2561 (I2C& p_i2c)
00030  : _i2c(p_i2c)
00031 {
00032     TSL2561_addr = TSL2561_ADDRESS_GND;
00033     init();
00034 }
00035 
00036 TSL2561::TSL2561 (I2C& p_i2c, uint8_t addr)
00037  : _i2c(p_i2c)
00038 {
00039     TSL2561_addr = addr;
00040     init();
00041 }
00042 
00043 /////////////// Read Lux from sensor //////////////////////
00044 /*
00045 For 0    < CH1/CH0 < 0.50 Lux = 0.0304  x CH0-0.062  x CH0 x ((CH1/CH0)1.4)
00046 For 0.50 < CH1/CH0 < 0.61 Lux = 0.0224  x CH0-0.031  x CH1
00047 For 0.61 < CH1/CH0 < 0.80 Lux = 0.0128  x CH0-0.0153 x CH1
00048 For 0.80 < CH1/CH0 < 1.30 Lux = 0.00146 x CH0-0.00112x CH1
00049 For        CH1/CH0 > 1.30 Lux = 0
00050  */
00051 float TSL2561::lux()
00052 {
00053     double lux0, lux1;
00054     double ratio;
00055     double dlux;
00056 
00057     dt[0] = CMD_MULTI + TSL2561_DATA0LOW;
00058     _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);
00059     _i2c.read(TSL2561_addr, (char *)dt, 2, false);
00060     ch0 = dt[1] << 8 | dt[0];
00061     dt[0] = CMD_MULTI + TSL2561_DATA1LOW;
00062     _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);
00063     _i2c.read(TSL2561_addr, (char *)dt, 2, false);
00064     ch1 = dt[1] << 8 | dt[0];
00065     if (ch0 == 0xFFFF) {
00066         return 2500.0;
00067     }
00068     lux0 = (double)ch0;
00069     lux1 = (double)ch1;
00070     ratio = lux1 / lux0;
00071     read_timing_reg();
00072     lux0 *= (402.0/integ_time);
00073     lux1 *= (402.0/integ_time);
00074     lux0 /= gain;
00075     lux1 /= gain;
00076     if (ratio <= 0.5) {
00077         dlux = 0.03040 * lux0 - 0.06200 * lux0 * pow(ratio,1.4);
00078     } else if (ratio <= 0.61) {
00079         dlux = 0.02240 * lux0 - 0.03100 * lux1;
00080     } else if (ratio <= 0.80) {
00081         dlux = 0.01280 * lux0 - 0.01530 * lux1;
00082     } else if (ratio <= 1.30) {
00083         dlux = 0.00146 * lux0 - 0.00112 * lux1;
00084     } else {
00085         dlux = 0;
00086     }
00087     return (float)dlux;
00088 }
00089 
00090 /////////////// Initialize ////////////////////////////////
00091 void TSL2561::init()
00092 {
00093     _i2c.frequency(100000);
00094     power_up();
00095     set_timing_reg(TIMING_DEFAULT);
00096 }
00097 
00098 /////////////// Timing Register ///////////////////////////
00099 uint8_t TSL2561::set_timing_reg(uint8_t parameter)
00100 {
00101     dt[0] = CMD_SINGLE + TSL2561_TIMING;
00102     dt[1] = parameter;
00103     _i2c.write((int)TSL2561_addr, (char *)dt, 2, false);
00104     dt[0] = CMD_SINGLE + TSL2561_TIMING;
00105     _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);
00106     _i2c.read(TSL2561_addr, (char *)dt, 1, false);
00107     return dt[0];
00108 }
00109 
00110 uint8_t TSL2561::read_timing_reg(void)
00111 {
00112     uint8_t i;
00113 
00114     dt[0] = CMD_SINGLE + TSL2561_TIMING;
00115     _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);
00116     _i2c.read(TSL2561_addr, (char *)dt, 1, false);
00117     if (dt[0] & TIMING_GAIN_16){
00118         gain = 16;
00119     } else {
00120         gain = 1;
00121     }
00122     i = dt[0] & 0x3;
00123     switch (i) {
00124         case 0:
00125             integ_time = 13.7;
00126             break;
00127         case 1:
00128             integ_time = 101.0;
00129             break;
00130         case 2:
00131             integ_time = 402.0;
00132             break;
00133         default:
00134             integ_time = 0;
00135             break;
00136     }
00137     return dt[0];
00138 }
00139 
00140 /////////////// ID ////////////////////////////////////////
00141 uint16_t TSL2561::read_ID()
00142 {
00143     dt[0] = CMD_SINGLE + TSL2561_ID;
00144     _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);
00145     _i2c.read(TSL2561_addr, (char *)dt, 2, false);
00146     id_number = dt[0] << 8 | dt[1];
00147     return id_number;
00148 }
00149 
00150 uint8_t TSL2561::who_am_i()
00151 {
00152     read_ID();
00153     if ((id_number >> 8) == I_AM_TSL2561) {
00154         return 1;
00155     } else {
00156         return 0;
00157     }
00158 }
00159 
00160 /////////////// Power ON/OFF //////////////////////////////
00161 void TSL2561::power_up()
00162 {
00163     dt[0] = CMD_SINGLE + TSL2561_CONTROL;
00164     dt[1] = 3;
00165     _i2c.write((int)TSL2561_addr, (char *)dt, 2, false);
00166 }
00167 
00168 void TSL2561::power_down()
00169 {
00170     dt[0] = CMD_SINGLE + TSL2561_CONTROL;
00171     dt[1] = 0;
00172     _i2c.write((int)TSL2561_addr, (char *)dt, 2, false);
00173 }
00174 
00175 /////////////// I2C Freq. /////////////////////////////////
00176 void TSL2561::frequency(int hz)
00177 {
00178     _i2c.frequency(hz);
00179 }
00180