Address is changed to suit Grove Digital Light Sensor.
Fork of TSL2561_I2C by
TSL2561_I2C.cpp
00001 #include "TSL2561_I2C.h" 00002 00003 TSL2561_I2C::TSL2561_I2C( PinName sda, PinName scl ) : i2c( sda, scl ){ 00004 i2c.frequency(100000); 00005 enablePower(); 00006 } 00007 00008 int TSL2561_I2C::writeSingleRegister( char address, char data ){ 00009 char tx[2] = { address | 160, data }; //0d160 = 0b10100000 00010 int ack = i2c.write( TSL_SLAVE_ADDRESS << 1, tx, 2 ); 00011 return ack; 00012 } 00013 00014 int TSL2561_I2C::writeMultipleRegisters( char address, char* data, int quantity ){ 00015 char tx[ quantity + 1 ]; 00016 tx[0] = address | 160; 00017 for ( int i = 1; i <= quantity; i++ ){ 00018 tx[ i ] = data[ i - 1 ]; 00019 } 00020 int ack = i2c.write( TSL_SLAVE_ADDRESS << 1, tx, quantity + 1 ); 00021 return ack; 00022 } 00023 00024 char TSL2561_I2C::readSingleRegister( char address ){ 00025 char output = 255; 00026 char command = address | 160; //0d160 = 0b10100000 00027 i2c.write( TSL_SLAVE_ADDRESS << 1, &command, 1, true ); 00028 i2c.read( TSL_SLAVE_ADDRESS << 1, &output, 1 ); 00029 return output; 00030 } 00031 00032 int TSL2561_I2C::readMultipleRegisters( char address, char* output, int quantity ){ 00033 char command = address | 160; //0d160 = 0b10100000 00034 i2c.write( TSL_SLAVE_ADDRESS << 1, &command, 1, true ); 00035 int ack = i2c.read( TSL_SLAVE_ADDRESS << 1, output, quantity ); 00036 return ack; 00037 } 00038 00039 int TSL2561_I2C::getVisibleAndIR(){ 00040 char buffer[2] = { 0 }; 00041 readMultipleRegisters( TSL_DATA0LOW, buffer, 2 ); 00042 int reading = (int)buffer[1] << 8 | (int)buffer[0]; 00043 return reading; 00044 } 00045 00046 int TSL2561_I2C::getIROnly(){ 00047 char buffer[2] = { 0 }; 00048 readMultipleRegisters( TSL_DATA1LOW, buffer, 2 ); 00049 int reading = (int)buffer[1] << 8 | (int)buffer[0]; 00050 return reading; 00051 } 00052 00053 float TSL2561_I2C::getLux(){ 00054 float lux = 0; 00055 int ch0 = getVisibleAndIR(); 00056 int ch1 = getIROnly(); 00057 00058 // Determine if either sensor saturated (0xFFFF) 00059 // If so, abandon ship (calculation will not be accurate) 00060 if( (ch0 == 0xFFFF) || (ch1 == 0xFFFF) ){ 00061 return -1; 00062 } 00063 00064 // Convert from unsigned integer to floating point 00065 float d0 = ch0; 00066 float d1 = ch1; 00067 00068 // We will need the ratio for subsequent calculations 00069 double ratio = d1 / d0; 00070 00071 // Normalize for integration time 00072 int itime = readIntegrationTime(); 00073 d0 *= (402.0/itime); 00074 d1 *= (402.0/itime); 00075 00076 // Normalize for gain 00077 int gain = readGain(); 00078 d0 /= gain; 00079 d1 /= gain; 00080 00081 // Determine lux per datasheet equations: 00082 00083 if (ratio < 0.5) 00084 { 00085 lux = 0.0304 * d0 - 0.062 * d0 * pow(ratio,1.4); 00086 } 00087 else if (ratio < 0.61) 00088 { 00089 lux = 0.0224 * d0 - 0.031 * d1; 00090 } 00091 else if (ratio < 0.80) 00092 { 00093 lux = 0.0128 * d0 - 0.0153 * d1; 00094 } 00095 else if (ratio < 1.30) 00096 { 00097 lux = 0.00146 * d0 - 0.00112 * d1; 00098 } 00099 00100 return lux; 00101 } 00102 00103 int TSL2561_I2C::enablePower(){ 00104 int ack = writeSingleRegister( TSL_CONTROL, 3 ); 00105 return ack; 00106 } 00107 00108 int TSL2561_I2C::disablePower(){ 00109 int ack = writeSingleRegister( TSL_CONTROL, 0 ); 00110 return ack; 00111 } 00112 00113 bool TSL2561_I2C::isPowerEnabled(){ 00114 char control = readSingleRegister( TSL_CONTROL ); 00115 bool power = 0; 00116 if( control == 3 ){ 00117 power = 1; 00118 } 00119 return power; 00120 } 00121 00122 int TSL2561_I2C::readGain(){ 00123 char timing = readSingleRegister( TSL_TIMING ); 00124 char gain_bit = ( timing << 3 ) >> 7; // keep only bit 4 00125 int gain; 00126 switch (gain_bit) { 00127 case 0: 00128 gain = 1; 00129 break; 00130 case 1: 00131 gain = 16; 00132 break; 00133 default: 00134 gain = 0; 00135 break; 00136 } 00137 return gain; 00138 } 00139 00140 int TSL2561_I2C::setGain( const int gain ){ 00141 char timing_old = readSingleRegister( TSL_TIMING ); 00142 char timing_new = 0; 00143 int ack = 0; 00144 switch (gain){ 00145 case 1: 00146 timing_new = timing_old & 239; // sets bit 4 to 0 00147 break; 00148 case 16: 00149 timing_new = timing_old | 16; // sets bit 4 to 1 00150 break; 00151 default: 00152 ack = 2; // 2 used to indicate invalid entry 00153 break; 00154 } 00155 00156 if ( ack != 2 ){ 00157 ack = writeSingleRegister( TSL_TIMING, timing_new ); 00158 } 00159 return ack; 00160 } 00161 00162 float TSL2561_I2C::readIntegrationTime(){ 00163 char timing = readSingleRegister( TSL_TIMING ); 00164 char integ = ( timing << 6 ) >> 6; // keep bits 0 & 1 00165 int itime; 00166 switch (integ) { 00167 case 0: 00168 itime = 13.7; 00169 break; 00170 case 1: 00171 itime = 101; 00172 break; 00173 case 2: 00174 itime = 402; 00175 break; 00176 default: 00177 itime = 0; 00178 break; 00179 } 00180 return itime; 00181 } 00182 00183 int TSL2561_I2C::setIntegrationTime( const float itime ){ 00184 char timing_old = readSingleRegister( TSL_TIMING ); 00185 char timing_new = 0; 00186 int ack = 0; 00187 if( abs( itime - 13.7 ) <= 0.001 ){ 00188 timing_new = timing_old & 252; // set bits 0 & 1 (INTEG) to 00 00189 } 00190 else if( abs( itime - 101 ) <= 0.001 ){ 00191 timing_new = timing_old | 1; // sets bit 0 to 1 00192 timing_new = timing_new & 253; // sets bit 1 to 0 00193 } 00194 else if( abs( itime - 402 ) <= 0.001 ){ 00195 timing_new = timing_old | 3; // sets bits 0 & 1 (INTEG) to 11 00196 } 00197 else { 00198 ack = 2; // indicates invalid entry 00199 } 00200 if ( ack != 2 ){ 00201 ack = writeSingleRegister( TSL_TIMING, timing_new ); 00202 } 00203 return ack; 00204 } 00205 00206 int TSL2561_I2C::readLowInterruptThreshold(){ 00207 char buffer[2] = { 0 }; 00208 readMultipleRegisters( TSL_THRESHLOWLOW, buffer, 2 ); 00209 int reading = (int)buffer[1] << 8 | (int)buffer[0]; 00210 return reading; 00211 } 00212 00213 int TSL2561_I2C::readHighInterruptThreshold(){ 00214 char buffer[2] = { 0 }; 00215 readMultipleRegisters( TSL_THRESHHIGHLOW, buffer, 2 ); 00216 int reading = (int)buffer[1] << 8 | (int)buffer[0]; 00217 return reading; 00218 } 00219 00220 int TSL2561_I2C::setLowInterruptThreshold( const int threshold ){ 00221 char threshold_bytes[2]; 00222 threshold_bytes[0] = threshold; // take lowest 8 bits of threshold 00223 threshold_bytes[1] = threshold >> 8; // take highest 8 bits of threshold 00224 int ack = writeMultipleRegisters( TSL_THRESHLOWLOW, threshold_bytes, 2 ); 00225 return ack; 00226 } 00227 00228 int TSL2561_I2C::setHighInterruptThreshold( const int threshold ){ 00229 char threshold_bytes[2]; 00230 threshold_bytes[0] = threshold; 00231 threshold_bytes[1] = threshold >> 8; 00232 int ack = writeMultipleRegisters( TSL_THRESHHIGHLOW, threshold_bytes, 2 ); 00233 return ack; 00234 } 00235 00236 int TSL2561_I2C::readInterruptPersistence(){ 00237 char interrupt = readSingleRegister( TSL_INTERRUPT ); 00238 char persist = ( interrupt << 4 ) >> 4; // discard bits 4 to 7, keep only bits 0 to 3 00239 return (int)persist; 00240 } 00241 00242 int TSL2561_I2C::setInterruptPersistence( const int persistence ){ 00243 char interrupt_old = readSingleRegister( TSL_INTERRUPT ); 00244 char interrupt_new = interrupt_old | (char)persistence; // sets bits 1 to 3 (PERSIST) to the value of persistence 00245 int ack = writeSingleRegister( TSL_INTERRUPT, interrupt_new ); 00246 return ack; 00247 } 00248 00249 int TSL2561_I2C::readInterruptControl(){ 00250 char interrupt = readSingleRegister( TSL_INTERRUPT ); 00251 char control = ( interrupt << 2 ) >> 6; // keep only bits 4 & 5 00252 return (int)control; 00253 } 00254 00255 int TSL2561_I2C::setInterruptControl( const int control ){ 00256 char interrupt_old = readSingleRegister( TSL_INTERRUPT ); 00257 char interrupt_new = interrupt_old | (char)( control << 4 ); // sets bits 4 and 5 (INTR) to the value of control 00258 int ack = writeSingleRegister( TSL_INTERRUPT, interrupt_new ); 00259 return ack; 00260 } 00261 00262 int TSL2561_I2C::clearInterrupt(){ 00263 char tx = 192; 00264 int ack = i2c.write( TSL_SLAVE_ADDRESS << 1, &tx, 1 ); // writes 0b11000000 to command register to clear interrupt 00265 return ack; 00266 } 00267 00268 int TSL2561_I2C::getPartNumber(){ 00269 char id = readSingleRegister( TSL_ID ); 00270 char partno = id >> 4; // keep upper 4 bits 00271 return (int)partno; 00272 } 00273 00274 int TSL2561_I2C::getRevisionNumber(){ 00275 char id = readSingleRegister( TSL_ID ); 00276 char revno = ( id << 4 ) >> 4; // keep lower 4 bits 00277 return (int)revno; 00278 }
Generated on Wed Jul 20 2022 06:42:06 by 1.7.2