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

Dependents:   TweetTest NetworkThermometer GR-PEACH_TAMORI mDot_LoRa_Connect_ABPA_Lux ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TSL2561_I2C.cpp Source File

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 }