TSL2561

Dependents:   Hexi_TSL2561 HexiHeart_Main

Fork of TSL2561 by Kenji Arai

Committer:
kenjiArai
Date:
Sat Mar 07 23:42:22 2015 +0000
Revision:
1:25a700e9b8ec
Parent:
0:eec7bcd27c52
Child:
2:17591031447b
Changed lux calculation way

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:eec7bcd27c52 1 /*
kenjiArai 0:eec7bcd27c52 2 * mbed library program
kenjiArai 0:eec7bcd27c52 3 * Luminosity sensor -- LIGHT-TO-DIGITAL CONVERTER (light intensity to a digital signal output)
kenjiArai 0:eec7bcd27c52 4 * TSL2561 by Texas Advanced Optoelectronic Solutions Inc.
kenjiArai 0:eec7bcd27c52 5 *
kenjiArai 0:eec7bcd27c52 6 * Copyright (c) 2015 Kenji Arai / JH1PJL
kenjiArai 0:eec7bcd27c52 7 * http://www.page.sannet.ne.jp/kenjia/index.html
kenjiArai 0:eec7bcd27c52 8 * http://mbed.org/users/kenjiArai/
kenjiArai 0:eec7bcd27c52 9 * Created: Feburary 21st, 2015
kenjiArai 1:25a700e9b8ec 10 * Revised: March 8th, 2015
kenjiArai 0:eec7bcd27c52 11 *
kenjiArai 0:eec7bcd27c52 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
kenjiArai 0:eec7bcd27c52 13 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
kenjiArai 0:eec7bcd27c52 14 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
kenjiArai 0:eec7bcd27c52 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kenjiArai 0:eec7bcd27c52 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
kenjiArai 0:eec7bcd27c52 17 */
kenjiArai 0:eec7bcd27c52 18
kenjiArai 0:eec7bcd27c52 19 #include "TSL2561.h"
kenjiArai 0:eec7bcd27c52 20
kenjiArai 0:eec7bcd27c52 21 TSL2561::TSL2561 (PinName p_sda, PinName p_scl) : _i2c(p_sda, p_scl)
kenjiArai 0:eec7bcd27c52 22 {
kenjiArai 0:eec7bcd27c52 23 TSL2561_addr = TSL2561_ADDRESS_GND;
kenjiArai 0:eec7bcd27c52 24 init();
kenjiArai 0:eec7bcd27c52 25 }
kenjiArai 0:eec7bcd27c52 26
kenjiArai 0:eec7bcd27c52 27 TSL2561::TSL2561 (PinName p_sda, PinName p_scl, uint8_t addr) : _i2c(p_sda, p_scl)
kenjiArai 0:eec7bcd27c52 28 {
kenjiArai 0:eec7bcd27c52 29 TSL2561_addr = addr;
kenjiArai 0:eec7bcd27c52 30 init();
kenjiArai 0:eec7bcd27c52 31 }
kenjiArai 0:eec7bcd27c52 32
kenjiArai 0:eec7bcd27c52 33 TSL2561::TSL2561 (I2C& p_i2c) : _i2c(p_i2c)
kenjiArai 0:eec7bcd27c52 34 {
kenjiArai 0:eec7bcd27c52 35 TSL2561_addr = TSL2561_ADDRESS_GND;
kenjiArai 0:eec7bcd27c52 36 init();
kenjiArai 0:eec7bcd27c52 37 }
kenjiArai 0:eec7bcd27c52 38
kenjiArai 0:eec7bcd27c52 39 TSL2561::TSL2561 (I2C& p_i2c, uint8_t addr) : _i2c(p_i2c)
kenjiArai 0:eec7bcd27c52 40 {
kenjiArai 0:eec7bcd27c52 41 TSL2561_addr = addr;
kenjiArai 0:eec7bcd27c52 42 init();
kenjiArai 0:eec7bcd27c52 43 }
kenjiArai 0:eec7bcd27c52 44
kenjiArai 0:eec7bcd27c52 45 /////////////// Read Lux from sensor //////////////////////
kenjiArai 0:eec7bcd27c52 46 /*
kenjiArai 0:eec7bcd27c52 47 For 0 < CH1/CH0 < 0.50 Lux = 0.0304 x CH0-0.062 x CH0 x ((CH1/CH0)1.4)
kenjiArai 0:eec7bcd27c52 48 For 0.50 < CH1/CH0 < 0.61 Lux = 0.0224 x CH0-0.031 x CH1
kenjiArai 0:eec7bcd27c52 49 For 0.61 < CH1/CH0 < 0.80 Lux = 0.0128 x CH0-0.0153 x CH1
kenjiArai 0:eec7bcd27c52 50 For 0.80 < CH1/CH0 < 1.30 Lux = 0.00146 x CH0-0.00112x CH1
kenjiArai 0:eec7bcd27c52 51 For CH1/CH0 > 1.30 Lux = 0
kenjiArai 0:eec7bcd27c52 52 */
kenjiArai 0:eec7bcd27c52 53 float TSL2561::lux()
kenjiArai 0:eec7bcd27c52 54 {
kenjiArai 0:eec7bcd27c52 55 double lux0, lux1;
kenjiArai 0:eec7bcd27c52 56 double ratio;
kenjiArai 0:eec7bcd27c52 57 double dlux;
kenjiArai 0:eec7bcd27c52 58
kenjiArai 0:eec7bcd27c52 59 dt[0] = CMD_MULTI + TSL2561_DATA0LOW;
kenjiArai 0:eec7bcd27c52 60 _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);
kenjiArai 0:eec7bcd27c52 61 _i2c.read(TSL2561_addr, (char *)dt, 2, false);
kenjiArai 0:eec7bcd27c52 62 ch0 = dt[1] << 8 | dt[0];
kenjiArai 0:eec7bcd27c52 63 dt[0] = CMD_MULTI + TSL2561_DATA1LOW;
kenjiArai 0:eec7bcd27c52 64 _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);
kenjiArai 0:eec7bcd27c52 65 _i2c.read(TSL2561_addr, (char *)dt, 2, false);
kenjiArai 0:eec7bcd27c52 66 ch1 = dt[1] << 8 | dt[0];
kenjiArai 1:25a700e9b8ec 67 if (ch0 == 0xFFFF) {
kenjiArai 1:25a700e9b8ec 68 return 2500.0;
kenjiArai 1:25a700e9b8ec 69 }
kenjiArai 1:25a700e9b8ec 70 lux0 = (double)ch0;
kenjiArai 1:25a700e9b8ec 71 lux1 = (double)ch1;
kenjiArai 0:eec7bcd27c52 72 ratio = lux1 / lux0;
kenjiArai 1:25a700e9b8ec 73 read_timing_reg();
kenjiArai 1:25a700e9b8ec 74 lux0 *= (402.0/integ_time);
kenjiArai 1:25a700e9b8ec 75 lux1 *= (402.0/integ_time);
kenjiArai 1:25a700e9b8ec 76 lux0 /= gain;
kenjiArai 1:25a700e9b8ec 77 lux1 /= gain;
kenjiArai 0:eec7bcd27c52 78 if (ratio <= 0.5) {
kenjiArai 0:eec7bcd27c52 79 dlux = 0.03040 * lux0 - 0.06200 * lux0 * pow(ratio,1.4);
kenjiArai 0:eec7bcd27c52 80 } else if (ratio <= 0.61) {
kenjiArai 0:eec7bcd27c52 81 dlux = 0.02240 * lux0 - 0.03100 * lux1;
kenjiArai 0:eec7bcd27c52 82 } else if (ratio <= 0.80) {
kenjiArai 0:eec7bcd27c52 83 dlux = 0.01280 * lux0 - 0.01530 * lux1;
kenjiArai 0:eec7bcd27c52 84 } else if (ratio <= 1.30) {
kenjiArai 0:eec7bcd27c52 85 dlux = 0.00146 * lux0 - 0.00112 * lux1;
kenjiArai 0:eec7bcd27c52 86 } else {
kenjiArai 0:eec7bcd27c52 87 dlux = 0;
kenjiArai 0:eec7bcd27c52 88 }
kenjiArai 0:eec7bcd27c52 89 return (float)dlux;
kenjiArai 0:eec7bcd27c52 90 }
kenjiArai 0:eec7bcd27c52 91
kenjiArai 0:eec7bcd27c52 92 /////////////// Initialize ////////////////////////////////
kenjiArai 0:eec7bcd27c52 93 void TSL2561::init()
kenjiArai 0:eec7bcd27c52 94 {
kenjiArai 0:eec7bcd27c52 95 _i2c.frequency(100000);
kenjiArai 0:eec7bcd27c52 96 power_up();
kenjiArai 1:25a700e9b8ec 97 set_timing_reg(TIMING_DEFAULT);
kenjiArai 1:25a700e9b8ec 98 }
kenjiArai 1:25a700e9b8ec 99
kenjiArai 1:25a700e9b8ec 100 /////////////// Timing Register ///////////////////////////
kenjiArai 1:25a700e9b8ec 101 uint8_t TSL2561::set_timing_reg(uint8_t parameter)
kenjiArai 1:25a700e9b8ec 102 {
kenjiArai 1:25a700e9b8ec 103 dt[0] = CMD_SINGLE + TSL2561_TIMING;
kenjiArai 1:25a700e9b8ec 104 dt[1] = parameter;
kenjiArai 1:25a700e9b8ec 105 _i2c.write((int)TSL2561_addr, (char *)dt, 2, false);
kenjiArai 1:25a700e9b8ec 106 dt[0] = CMD_SINGLE + TSL2561_TIMING;
kenjiArai 1:25a700e9b8ec 107 _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);
kenjiArai 1:25a700e9b8ec 108 _i2c.read(TSL2561_addr, (char *)dt, 1, false);
kenjiArai 1:25a700e9b8ec 109 return dt[0];
kenjiArai 1:25a700e9b8ec 110 }
kenjiArai 1:25a700e9b8ec 111
kenjiArai 1:25a700e9b8ec 112 uint8_t TSL2561::read_timing_reg(void)
kenjiArai 1:25a700e9b8ec 113 {
kenjiArai 1:25a700e9b8ec 114 uint8_t i;
kenjiArai 1:25a700e9b8ec 115
kenjiArai 1:25a700e9b8ec 116 dt[0] = CMD_SINGLE + TSL2561_TIMING;
kenjiArai 1:25a700e9b8ec 117 _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);
kenjiArai 1:25a700e9b8ec 118 _i2c.read(TSL2561_addr, (char *)dt, 1, false);
kenjiArai 1:25a700e9b8ec 119 if (dt[0] & TIMING_GAIN_16){
kenjiArai 1:25a700e9b8ec 120 gain = 16;
kenjiArai 1:25a700e9b8ec 121 } else {
kenjiArai 1:25a700e9b8ec 122 gain = 1;
kenjiArai 1:25a700e9b8ec 123 }
kenjiArai 1:25a700e9b8ec 124 i = dt[0] & 0x3;
kenjiArai 1:25a700e9b8ec 125 switch (i) {
kenjiArai 1:25a700e9b8ec 126 case 0:
kenjiArai 1:25a700e9b8ec 127 integ_time = 13.7;
kenjiArai 1:25a700e9b8ec 128 break;
kenjiArai 1:25a700e9b8ec 129 case 1:
kenjiArai 1:25a700e9b8ec 130 integ_time = 101.0;
kenjiArai 1:25a700e9b8ec 131 break;
kenjiArai 1:25a700e9b8ec 132 case 2:
kenjiArai 1:25a700e9b8ec 133 integ_time = 402.0;
kenjiArai 1:25a700e9b8ec 134 break;
kenjiArai 1:25a700e9b8ec 135 default:
kenjiArai 1:25a700e9b8ec 136 integ_time = 0;
kenjiArai 1:25a700e9b8ec 137 break;
kenjiArai 1:25a700e9b8ec 138 }
kenjiArai 1:25a700e9b8ec 139 return dt[0];
kenjiArai 0:eec7bcd27c52 140 }
kenjiArai 0:eec7bcd27c52 141
kenjiArai 0:eec7bcd27c52 142 /////////////// ID ////////////////////////////////////////
kenjiArai 0:eec7bcd27c52 143 uint16_t TSL2561::read_ID()
kenjiArai 0:eec7bcd27c52 144 {
kenjiArai 0:eec7bcd27c52 145 dt[0] = CMD_SINGLE + TSL2561_ID;
kenjiArai 0:eec7bcd27c52 146 _i2c.write((int)TSL2561_addr, (char *)dt, 1, true);
kenjiArai 0:eec7bcd27c52 147 _i2c.read(TSL2561_addr, (char *)dt, 2, false);
kenjiArai 0:eec7bcd27c52 148 id_number = dt[0] << 8 | dt[1];
kenjiArai 0:eec7bcd27c52 149 return id_number;
kenjiArai 0:eec7bcd27c52 150 }
kenjiArai 0:eec7bcd27c52 151
kenjiArai 0:eec7bcd27c52 152 uint8_t TSL2561::who_am_i()
kenjiArai 0:eec7bcd27c52 153 {
kenjiArai 0:eec7bcd27c52 154 read_ID();
kenjiArai 0:eec7bcd27c52 155 if ((id_number >> 4) == I_AM_TSL2561) {
kenjiArai 0:eec7bcd27c52 156 return 1;
kenjiArai 0:eec7bcd27c52 157 } else {
kenjiArai 0:eec7bcd27c52 158 return 0;
kenjiArai 0:eec7bcd27c52 159 }
kenjiArai 0:eec7bcd27c52 160 }
kenjiArai 0:eec7bcd27c52 161
kenjiArai 0:eec7bcd27c52 162 /////////////// Power ON/OFF //////////////////////////////
kenjiArai 0:eec7bcd27c52 163 void TSL2561::power_up()
kenjiArai 0:eec7bcd27c52 164 {
kenjiArai 0:eec7bcd27c52 165 dt[0] = CMD_SINGLE + TSL2561_CONTROL;
kenjiArai 0:eec7bcd27c52 166 dt[1] = 3;
kenjiArai 0:eec7bcd27c52 167 _i2c.write((int)TSL2561_addr, (char *)dt, 2, false);
kenjiArai 0:eec7bcd27c52 168 }
kenjiArai 0:eec7bcd27c52 169
kenjiArai 0:eec7bcd27c52 170 void TSL2561::power_down()
kenjiArai 0:eec7bcd27c52 171 {
kenjiArai 0:eec7bcd27c52 172 dt[0] = CMD_SINGLE + TSL2561_CONTROL;
kenjiArai 0:eec7bcd27c52 173 dt[1] = 0;
kenjiArai 0:eec7bcd27c52 174 _i2c.write((int)TSL2561_addr, (char *)dt, 2, false);
kenjiArai 0:eec7bcd27c52 175 }
kenjiArai 0:eec7bcd27c52 176
kenjiArai 0:eec7bcd27c52 177 /////////////// I2C Freq. /////////////////////////////////
kenjiArai 0:eec7bcd27c52 178 void TSL2561::frequency(int hz)
kenjiArai 0:eec7bcd27c52 179 {
kenjiArai 0:eec7bcd27c52 180 _i2c.frequency(hz);
kenjiArai 0:eec7bcd27c52 181 }