Library which provides functions to control a TAOS TSL2561 Light-To-Digital Converter via I2C.

Fork of TSL2561_I2C by Karl Maxwell

Committer:
merckeng
Date:
Sat Dec 03 22:04:22 2016 +0000
Revision:
7:c7725e28bdeb
Parent:
5:93782eb646de
use proper i2c address for our demo;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
karlmaxwell67 5:93782eb646de 1 #include "TSL2561_I2C.h"
karlmaxwell67 1:70d7d9f1af01 2
karlmaxwell67 5:93782eb646de 3 TSL2561_I2C::TSL2561_I2C( PinName sda, PinName scl ) : i2c( sda, scl ){
karlmaxwell67 5:93782eb646de 4 i2c.frequency(100000);
karlmaxwell67 5:93782eb646de 5 enablePower();
karlmaxwell67 1:70d7d9f1af01 6 }
karlmaxwell67 1:70d7d9f1af01 7
karlmaxwell67 5:93782eb646de 8 int TSL2561_I2C::writeSingleRegister( char address, char data ){
karlmaxwell67 1:70d7d9f1af01 9 char tx[2] = { address | 160, data }; //0d160 = 0b10100000
karlmaxwell67 5:93782eb646de 10 int ack = i2c.write( TSL_SLAVE_ADDRESS << 1, tx, 2 );
karlmaxwell67 3:6a89ac4a1979 11 return ack;
karlmaxwell67 3:6a89ac4a1979 12 }
karlmaxwell67 3:6a89ac4a1979 13
karlmaxwell67 5:93782eb646de 14 int TSL2561_I2C::writeMultipleRegisters( char address, char* data, int quantity ){
karlmaxwell67 3:6a89ac4a1979 15 char tx[ quantity + 1 ];
karlmaxwell67 3:6a89ac4a1979 16 tx[0] = address | 160;
karlmaxwell67 3:6a89ac4a1979 17 for ( int i = 1; i <= quantity; i++ ){
karlmaxwell67 3:6a89ac4a1979 18 tx[ i ] = data[ i - 1 ];
karlmaxwell67 3:6a89ac4a1979 19 }
karlmaxwell67 5:93782eb646de 20 int ack = i2c.write( TSL_SLAVE_ADDRESS << 1, tx, quantity + 1 );
karlmaxwell67 1:70d7d9f1af01 21 return ack;
karlmaxwell67 1:70d7d9f1af01 22 }
karlmaxwell67 1:70d7d9f1af01 23
karlmaxwell67 5:93782eb646de 24 char TSL2561_I2C::readSingleRegister( char address ){
karlmaxwell67 1:70d7d9f1af01 25 char output = 255;
karlmaxwell67 1:70d7d9f1af01 26 char command = address | 160; //0d160 = 0b10100000
karlmaxwell67 5:93782eb646de 27 i2c.write( TSL_SLAVE_ADDRESS << 1, &command, 1, true );
karlmaxwell67 5:93782eb646de 28 i2c.read( TSL_SLAVE_ADDRESS << 1, &output, 1 );
karlmaxwell67 1:70d7d9f1af01 29 return output;
karlmaxwell67 1:70d7d9f1af01 30 }
karlmaxwell67 1:70d7d9f1af01 31
karlmaxwell67 5:93782eb646de 32 int TSL2561_I2C::readMultipleRegisters( char address, char* output, int quantity ){
karlmaxwell67 1:70d7d9f1af01 33 char command = address | 160; //0d160 = 0b10100000
karlmaxwell67 5:93782eb646de 34 i2c.write( TSL_SLAVE_ADDRESS << 1, &command, 1, true );
karlmaxwell67 5:93782eb646de 35 int ack = i2c.read( TSL_SLAVE_ADDRESS << 1, output, quantity );
karlmaxwell67 1:70d7d9f1af01 36 return ack;
karlmaxwell67 1:70d7d9f1af01 37 }
karlmaxwell67 1:70d7d9f1af01 38
karlmaxwell67 5:93782eb646de 39 int TSL2561_I2C::getVisibleAndIR(){
karlmaxwell67 1:70d7d9f1af01 40 char buffer[2] = { 0 };
karlmaxwell67 5:93782eb646de 41 readMultipleRegisters( TSL_DATA0LOW, buffer, 2 );
karlmaxwell67 1:70d7d9f1af01 42 int reading = (int)buffer[1] << 8 | (int)buffer[0];
karlmaxwell67 1:70d7d9f1af01 43 return reading;
karlmaxwell67 1:70d7d9f1af01 44 }
karlmaxwell67 1:70d7d9f1af01 45
karlmaxwell67 5:93782eb646de 46 int TSL2561_I2C::getIROnly(){
karlmaxwell67 1:70d7d9f1af01 47 char buffer[2] = { 0 };
karlmaxwell67 5:93782eb646de 48 readMultipleRegisters( TSL_DATA1LOW, buffer, 2 );
karlmaxwell67 1:70d7d9f1af01 49 int reading = (int)buffer[1] << 8 | (int)buffer[0];
karlmaxwell67 1:70d7d9f1af01 50 return reading;
karlmaxwell67 2:38d5187a4e7b 51 }
karlmaxwell67 2:38d5187a4e7b 52
karlmaxwell67 5:93782eb646de 53 float TSL2561_I2C::getLux(){
karlmaxwell67 5:93782eb646de 54 float lux = 0;
karlmaxwell67 5:93782eb646de 55 int ch0 = getVisibleAndIR();
karlmaxwell67 5:93782eb646de 56 int ch1 = getIROnly();
karlmaxwell67 5:93782eb646de 57
karlmaxwell67 5:93782eb646de 58 // Determine if either sensor saturated (0xFFFF)
karlmaxwell67 5:93782eb646de 59 // If so, abandon ship (calculation will not be accurate)
karlmaxwell67 5:93782eb646de 60 if( (ch0 == 0xFFFF) || (ch1 == 0xFFFF) ){
karlmaxwell67 5:93782eb646de 61 return -1;
karlmaxwell67 5:93782eb646de 62 }
karlmaxwell67 5:93782eb646de 63
karlmaxwell67 5:93782eb646de 64 // Convert from unsigned integer to floating point
karlmaxwell67 5:93782eb646de 65 float d0 = ch0;
karlmaxwell67 5:93782eb646de 66 float d1 = ch1;
karlmaxwell67 4:5d1f8d7d81ff 67
karlmaxwell67 5:93782eb646de 68 // We will need the ratio for subsequent calculations
karlmaxwell67 5:93782eb646de 69 double ratio = d1 / d0;
karlmaxwell67 5:93782eb646de 70
karlmaxwell67 5:93782eb646de 71 // Normalize for integration time
karlmaxwell67 5:93782eb646de 72 int itime = readIntegrationTime();
karlmaxwell67 5:93782eb646de 73 d0 *= (402.0/itime);
karlmaxwell67 5:93782eb646de 74 d1 *= (402.0/itime);
karlmaxwell67 5:93782eb646de 75
karlmaxwell67 5:93782eb646de 76 // Normalize for gain
karlmaxwell67 5:93782eb646de 77 int gain = readGain();
karlmaxwell67 5:93782eb646de 78 d0 /= gain;
karlmaxwell67 5:93782eb646de 79 d1 /= gain;
karlmaxwell67 5:93782eb646de 80
karlmaxwell67 5:93782eb646de 81 // Determine lux per datasheet equations:
karlmaxwell67 3:6a89ac4a1979 82
karlmaxwell67 5:93782eb646de 83 if (ratio < 0.5)
karlmaxwell67 5:93782eb646de 84 {
karlmaxwell67 5:93782eb646de 85 lux = 0.0304 * d0 - 0.062 * d0 * pow(ratio,1.4);
karlmaxwell67 5:93782eb646de 86 }
karlmaxwell67 5:93782eb646de 87 else if (ratio < 0.61)
karlmaxwell67 5:93782eb646de 88 {
karlmaxwell67 5:93782eb646de 89 lux = 0.0224 * d0 - 0.031 * d1;
karlmaxwell67 5:93782eb646de 90 }
karlmaxwell67 5:93782eb646de 91 else if (ratio < 0.80)
karlmaxwell67 5:93782eb646de 92 {
karlmaxwell67 5:93782eb646de 93 lux = 0.0128 * d0 - 0.0153 * d1;
karlmaxwell67 5:93782eb646de 94 }
karlmaxwell67 5:93782eb646de 95 else if (ratio < 1.30)
karlmaxwell67 5:93782eb646de 96 {
karlmaxwell67 5:93782eb646de 97 lux = 0.00146 * d0 - 0.00112 * d1;
karlmaxwell67 5:93782eb646de 98 }
karlmaxwell67 5:93782eb646de 99
karlmaxwell67 5:93782eb646de 100 return lux;
karlmaxwell67 2:38d5187a4e7b 101 }
karlmaxwell67 2:38d5187a4e7b 102
karlmaxwell67 5:93782eb646de 103 int TSL2561_I2C::enablePower(){
karlmaxwell67 5:93782eb646de 104 int ack = writeSingleRegister( TSL_CONTROL, 3 );
karlmaxwell67 2:38d5187a4e7b 105 return ack;
karlmaxwell67 3:6a89ac4a1979 106 }
karlmaxwell67 3:6a89ac4a1979 107
karlmaxwell67 5:93782eb646de 108 int TSL2561_I2C::disablePower(){
karlmaxwell67 5:93782eb646de 109 int ack = writeSingleRegister( TSL_CONTROL, 0 );
karlmaxwell67 3:6a89ac4a1979 110 return ack;
karlmaxwell67 3:6a89ac4a1979 111 }
karlmaxwell67 3:6a89ac4a1979 112
karlmaxwell67 5:93782eb646de 113 bool TSL2561_I2C::isPowerEnabled(){
karlmaxwell67 5:93782eb646de 114 char control = readSingleRegister( TSL_CONTROL );
karlmaxwell67 5:93782eb646de 115 bool power = 0;
karlmaxwell67 5:93782eb646de 116 if( control == 3 ){
karlmaxwell67 5:93782eb646de 117 power = 1;
karlmaxwell67 3:6a89ac4a1979 118 }
karlmaxwell67 5:93782eb646de 119 return power;
karlmaxwell67 3:6a89ac4a1979 120 }
karlmaxwell67 3:6a89ac4a1979 121
karlmaxwell67 5:93782eb646de 122 int TSL2561_I2C::readGain(){
karlmaxwell67 5:93782eb646de 123 char timing = readSingleRegister( TSL_TIMING );
karlmaxwell67 5:93782eb646de 124 char gain_bit = ( timing << 3 ) >> 7; // keep only bit 4
karlmaxwell67 3:6a89ac4a1979 125 int gain;
karlmaxwell67 5:93782eb646de 126 switch (gain_bit) {
karlmaxwell67 3:6a89ac4a1979 127 case 0:
karlmaxwell67 3:6a89ac4a1979 128 gain = 1;
karlmaxwell67 3:6a89ac4a1979 129 break;
karlmaxwell67 3:6a89ac4a1979 130 case 1:
karlmaxwell67 3:6a89ac4a1979 131 gain = 16;
karlmaxwell67 3:6a89ac4a1979 132 break;
karlmaxwell67 3:6a89ac4a1979 133 default:
karlmaxwell67 3:6a89ac4a1979 134 gain = 0;
karlmaxwell67 3:6a89ac4a1979 135 break;
karlmaxwell67 3:6a89ac4a1979 136 }
karlmaxwell67 3:6a89ac4a1979 137 return gain;
karlmaxwell67 3:6a89ac4a1979 138 }
karlmaxwell67 3:6a89ac4a1979 139
karlmaxwell67 5:93782eb646de 140 int TSL2561_I2C::setGain( const int gain ){
karlmaxwell67 5:93782eb646de 141 char timing_old = readSingleRegister( TSL_TIMING );
karlmaxwell67 5:93782eb646de 142 char timing_new = 0;
karlmaxwell67 3:6a89ac4a1979 143 int ack = 0;
karlmaxwell67 3:6a89ac4a1979 144 switch (gain){
karlmaxwell67 3:6a89ac4a1979 145 case 1:
karlmaxwell67 5:93782eb646de 146 timing_new = timing_old & 239; // sets bit 4 to 0
karlmaxwell67 3:6a89ac4a1979 147 break;
karlmaxwell67 3:6a89ac4a1979 148 case 16:
karlmaxwell67 5:93782eb646de 149 timing_new = timing_old | 16; // sets bit 4 to 1
karlmaxwell67 3:6a89ac4a1979 150 break;
karlmaxwell67 3:6a89ac4a1979 151 default:
karlmaxwell67 3:6a89ac4a1979 152 ack = 2; // 2 used to indicate invalid entry
karlmaxwell67 3:6a89ac4a1979 153 break;
karlmaxwell67 3:6a89ac4a1979 154 }
karlmaxwell67 5:93782eb646de 155
karlmaxwell67 3:6a89ac4a1979 156 if ( ack != 2 ){
karlmaxwell67 5:93782eb646de 157 ack = writeSingleRegister( TSL_TIMING, timing_new );
karlmaxwell67 5:93782eb646de 158 }
karlmaxwell67 5:93782eb646de 159 return ack;
karlmaxwell67 5:93782eb646de 160 }
karlmaxwell67 5:93782eb646de 161
karlmaxwell67 5:93782eb646de 162 float TSL2561_I2C::readIntegrationTime(){
karlmaxwell67 5:93782eb646de 163 char timing = readSingleRegister( TSL_TIMING );
karlmaxwell67 5:93782eb646de 164 char integ = ( timing << 6 ) >> 6; // keep bits 0 & 1
karlmaxwell67 5:93782eb646de 165 int itime;
karlmaxwell67 5:93782eb646de 166 switch (integ) {
karlmaxwell67 5:93782eb646de 167 case 0:
karlmaxwell67 5:93782eb646de 168 itime = 13.7;
karlmaxwell67 5:93782eb646de 169 break;
karlmaxwell67 5:93782eb646de 170 case 1:
karlmaxwell67 5:93782eb646de 171 itime = 101;
karlmaxwell67 5:93782eb646de 172 break;
karlmaxwell67 5:93782eb646de 173 case 2:
karlmaxwell67 5:93782eb646de 174 itime = 402;
karlmaxwell67 5:93782eb646de 175 break;
karlmaxwell67 5:93782eb646de 176 default:
karlmaxwell67 5:93782eb646de 177 itime = 0;
karlmaxwell67 5:93782eb646de 178 break;
karlmaxwell67 5:93782eb646de 179 }
karlmaxwell67 5:93782eb646de 180 return itime;
karlmaxwell67 5:93782eb646de 181 }
karlmaxwell67 5:93782eb646de 182
karlmaxwell67 5:93782eb646de 183 int TSL2561_I2C::setIntegrationTime( const float itime ){
karlmaxwell67 5:93782eb646de 184 char timing_old = readSingleRegister( TSL_TIMING );
karlmaxwell67 5:93782eb646de 185 char timing_new = 0;
karlmaxwell67 5:93782eb646de 186 int ack = 0;
karlmaxwell67 5:93782eb646de 187 if( abs( itime - 13.7 ) <= 0.001 ){
karlmaxwell67 5:93782eb646de 188 timing_new = timing_old & 252; // set bits 0 & 1 (INTEG) to 00
karlmaxwell67 5:93782eb646de 189 }
karlmaxwell67 5:93782eb646de 190 else if( abs( itime - 101 ) <= 0.001 ){
karlmaxwell67 5:93782eb646de 191 timing_new = timing_old | 1; // sets bit 0 to 1
karlmaxwell67 5:93782eb646de 192 timing_new = timing_new & 253; // sets bit 1 to 0
karlmaxwell67 5:93782eb646de 193 }
karlmaxwell67 5:93782eb646de 194 else if( abs( itime - 402 ) <= 0.001 ){
karlmaxwell67 5:93782eb646de 195 timing_new = timing_old | 3; // sets bits 0 & 1 (INTEG) to 11
karlmaxwell67 5:93782eb646de 196 }
karlmaxwell67 5:93782eb646de 197 else {
karlmaxwell67 5:93782eb646de 198 ack = 2; // indicates invalid entry
karlmaxwell67 5:93782eb646de 199 }
karlmaxwell67 5:93782eb646de 200 if ( ack != 2 ){
karlmaxwell67 5:93782eb646de 201 ack = writeSingleRegister( TSL_TIMING, timing_new );
karlmaxwell67 3:6a89ac4a1979 202 }
karlmaxwell67 3:6a89ac4a1979 203 return ack;
karlmaxwell67 3:6a89ac4a1979 204 }
karlmaxwell67 3:6a89ac4a1979 205
karlmaxwell67 5:93782eb646de 206 int TSL2561_I2C::readLowInterruptThreshold(){
karlmaxwell67 5:93782eb646de 207 char buffer[2] = { 0 };
karlmaxwell67 5:93782eb646de 208 readMultipleRegisters( TSL_THRESHLOWLOW, buffer, 2 );
karlmaxwell67 5:93782eb646de 209 int reading = (int)buffer[1] << 8 | (int)buffer[0];
karlmaxwell67 5:93782eb646de 210 return reading;
karlmaxwell67 5:93782eb646de 211 }
karlmaxwell67 5:93782eb646de 212
karlmaxwell67 5:93782eb646de 213 int TSL2561_I2C::readHighInterruptThreshold(){
karlmaxwell67 5:93782eb646de 214 char buffer[2] = { 0 };
karlmaxwell67 5:93782eb646de 215 readMultipleRegisters( TSL_THRESHHIGHLOW, buffer, 2 );
karlmaxwell67 5:93782eb646de 216 int reading = (int)buffer[1] << 8 | (int)buffer[0];
karlmaxwell67 5:93782eb646de 217 return reading;
karlmaxwell67 3:6a89ac4a1979 218 }
karlmaxwell67 3:6a89ac4a1979 219
karlmaxwell67 5:93782eb646de 220 int TSL2561_I2C::setLowInterruptThreshold( const int threshold ){
karlmaxwell67 5:93782eb646de 221 char threshold_bytes[2];
karlmaxwell67 5:93782eb646de 222 threshold_bytes[0] = threshold; // take lowest 8 bits of threshold
karlmaxwell67 5:93782eb646de 223 threshold_bytes[1] = threshold >> 8; // take highest 8 bits of threshold
karlmaxwell67 5:93782eb646de 224 int ack = writeMultipleRegisters( TSL_THRESHLOWLOW, threshold_bytes, 2 );
karlmaxwell67 5:93782eb646de 225 return ack;
karlmaxwell67 5:93782eb646de 226 }
karlmaxwell67 5:93782eb646de 227
karlmaxwell67 5:93782eb646de 228 int TSL2561_I2C::setHighInterruptThreshold( const int threshold ){
karlmaxwell67 5:93782eb646de 229 char threshold_bytes[2];
karlmaxwell67 5:93782eb646de 230 threshold_bytes[0] = threshold;
karlmaxwell67 5:93782eb646de 231 threshold_bytes[1] = threshold >> 8;
karlmaxwell67 5:93782eb646de 232 int ack = writeMultipleRegisters( TSL_THRESHHIGHLOW, threshold_bytes, 2 );
karlmaxwell67 5:93782eb646de 233 return ack;
karlmaxwell67 5:93782eb646de 234 }
karlmaxwell67 5:93782eb646de 235
karlmaxwell67 5:93782eb646de 236 int TSL2561_I2C::readInterruptPersistence(){
karlmaxwell67 5:93782eb646de 237 char interrupt = readSingleRegister( TSL_INTERRUPT );
karlmaxwell67 5:93782eb646de 238 char persist = ( interrupt << 4 ) >> 4; // discard bits 4 to 7, keep only bits 0 to 3
karlmaxwell67 5:93782eb646de 239 return (int)persist;
karlmaxwell67 4:5d1f8d7d81ff 240 }
karlmaxwell67 4:5d1f8d7d81ff 241
karlmaxwell67 5:93782eb646de 242 int TSL2561_I2C::setInterruptPersistence( const int persistence ){
karlmaxwell67 5:93782eb646de 243 char interrupt_old = readSingleRegister( TSL_INTERRUPT );
karlmaxwell67 5:93782eb646de 244 char interrupt_new = interrupt_old | (char)persistence; // sets bits 1 to 3 (PERSIST) to the value of persistence
karlmaxwell67 5:93782eb646de 245 int ack = writeSingleRegister( TSL_INTERRUPT, interrupt_new );
karlmaxwell67 5:93782eb646de 246 return ack;
karlmaxwell67 5:93782eb646de 247 }
karlmaxwell67 5:93782eb646de 248
karlmaxwell67 5:93782eb646de 249 int TSL2561_I2C::readInterruptControl(){
karlmaxwell67 5:93782eb646de 250 char interrupt = readSingleRegister( TSL_INTERRUPT );
karlmaxwell67 5:93782eb646de 251 char control = ( interrupt << 2 ) >> 6; // keep only bits 4 & 5
karlmaxwell67 5:93782eb646de 252 return (int)control;
karlmaxwell67 5:93782eb646de 253 }
karlmaxwell67 5:93782eb646de 254
karlmaxwell67 5:93782eb646de 255 int TSL2561_I2C::setInterruptControl( const int control ){
karlmaxwell67 5:93782eb646de 256 char interrupt_old = readSingleRegister( TSL_INTERRUPT );
karlmaxwell67 5:93782eb646de 257 char interrupt_new = interrupt_old | (char)( control << 4 ); // sets bits 4 and 5 (INTR) to the value of control
karlmaxwell67 5:93782eb646de 258 int ack = writeSingleRegister( TSL_INTERRUPT, interrupt_new );
karlmaxwell67 5:93782eb646de 259 return ack;
karlmaxwell67 5:93782eb646de 260 }
karlmaxwell67 5:93782eb646de 261
karlmaxwell67 5:93782eb646de 262 int TSL2561_I2C::clearInterrupt(){
karlmaxwell67 5:93782eb646de 263 char tx = 192;
karlmaxwell67 5:93782eb646de 264 int ack = i2c.write( TSL_SLAVE_ADDRESS << 1, &tx, 1 ); // writes 0b11000000 to command register to clear interrupt
karlmaxwell67 5:93782eb646de 265 return ack;
karlmaxwell67 5:93782eb646de 266 }
karlmaxwell67 5:93782eb646de 267
karlmaxwell67 5:93782eb646de 268 int TSL2561_I2C::getPartNumber(){
karlmaxwell67 5:93782eb646de 269 char id = readSingleRegister( TSL_ID );
karlmaxwell67 5:93782eb646de 270 char partno = id >> 4; // keep upper 4 bits
karlmaxwell67 5:93782eb646de 271 return (int)partno;
karlmaxwell67 5:93782eb646de 272 }
karlmaxwell67 5:93782eb646de 273
karlmaxwell67 5:93782eb646de 274 int TSL2561_I2C::getRevisionNumber(){
karlmaxwell67 5:93782eb646de 275 char id = readSingleRegister( TSL_ID );
karlmaxwell67 5:93782eb646de 276 char revno = ( id << 4 ) >> 4; // keep lower 4 bits
karlmaxwell67 5:93782eb646de 277 return (int)revno;
karlmaxwell67 0:453a43c8bf2b 278 }