Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of TSL2561_I2C by
Diff: TSL2561_I2C.cpp
- Revision:
- 5:93782eb646de
- Parent:
- 4:5d1f8d7d81ff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TSL2561_I2C.cpp Wed Apr 16 10:57:57 2014 +0000
@@ -0,0 +1,278 @@
+#include "TSL2561_I2C.h"
+
+TSL2561_I2C::TSL2561_I2C( PinName sda, PinName scl ) : i2c( sda, scl ){
+ i2c.frequency(100000);
+ enablePower();
+}
+
+int TSL2561_I2C::writeSingleRegister( char address, char data ){
+ char tx[2] = { address | 160, data }; //0d160 = 0b10100000
+ int ack = i2c.write( TSL_SLAVE_ADDRESS << 1, tx, 2 );
+ return ack;
+}
+
+int TSL2561_I2C::writeMultipleRegisters( char address, char* data, int quantity ){
+ char tx[ quantity + 1 ];
+ tx[0] = address | 160;
+ for ( int i = 1; i <= quantity; i++ ){
+ tx[ i ] = data[ i - 1 ];
+ }
+ int ack = i2c.write( TSL_SLAVE_ADDRESS << 1, tx, quantity + 1 );
+ return ack;
+}
+
+char TSL2561_I2C::readSingleRegister( char address ){
+ char output = 255;
+ char command = address | 160; //0d160 = 0b10100000
+ i2c.write( TSL_SLAVE_ADDRESS << 1, &command, 1, true );
+ i2c.read( TSL_SLAVE_ADDRESS << 1, &output, 1 );
+ return output;
+}
+
+int TSL2561_I2C::readMultipleRegisters( char address, char* output, int quantity ){
+ char command = address | 160; //0d160 = 0b10100000
+ i2c.write( TSL_SLAVE_ADDRESS << 1, &command, 1, true );
+ int ack = i2c.read( TSL_SLAVE_ADDRESS << 1, output, quantity );
+ return ack;
+}
+
+int TSL2561_I2C::getVisibleAndIR(){
+ char buffer[2] = { 0 };
+ readMultipleRegisters( TSL_DATA0LOW, buffer, 2 );
+ int reading = (int)buffer[1] << 8 | (int)buffer[0];
+ return reading;
+}
+
+int TSL2561_I2C::getIROnly(){
+ char buffer[2] = { 0 };
+ readMultipleRegisters( TSL_DATA1LOW, buffer, 2 );
+ int reading = (int)buffer[1] << 8 | (int)buffer[0];
+ return reading;
+}
+
+float TSL2561_I2C::getLux(){
+ float lux = 0;
+ int ch0 = getVisibleAndIR();
+ int ch1 = getIROnly();
+
+ // Determine if either sensor saturated (0xFFFF)
+ // If so, abandon ship (calculation will not be accurate)
+ if( (ch0 == 0xFFFF) || (ch1 == 0xFFFF) ){
+ return -1;
+ }
+
+ // Convert from unsigned integer to floating point
+ float d0 = ch0;
+ float d1 = ch1;
+
+ // We will need the ratio for subsequent calculations
+ double ratio = d1 / d0;
+
+ // Normalize for integration time
+ int itime = readIntegrationTime();
+ d0 *= (402.0/itime);
+ d1 *= (402.0/itime);
+
+ // Normalize for gain
+ int gain = readGain();
+ d0 /= gain;
+ d1 /= gain;
+
+ // Determine lux per datasheet equations:
+
+ if (ratio < 0.5)
+ {
+ lux = 0.0304 * d0 - 0.062 * d0 * pow(ratio,1.4);
+ }
+ else if (ratio < 0.61)
+ {
+ lux = 0.0224 * d0 - 0.031 * d1;
+ }
+ else if (ratio < 0.80)
+ {
+ lux = 0.0128 * d0 - 0.0153 * d1;
+ }
+ else if (ratio < 1.30)
+ {
+ lux = 0.00146 * d0 - 0.00112 * d1;
+ }
+
+ return lux;
+}
+
+int TSL2561_I2C::enablePower(){
+ int ack = writeSingleRegister( TSL_CONTROL, 3 );
+ return ack;
+}
+
+int TSL2561_I2C::disablePower(){
+ int ack = writeSingleRegister( TSL_CONTROL, 0 );
+ return ack;
+}
+
+bool TSL2561_I2C::isPowerEnabled(){
+ char control = readSingleRegister( TSL_CONTROL );
+ bool power = 0;
+ if( control == 3 ){
+ power = 1;
+ }
+ return power;
+}
+
+int TSL2561_I2C::readGain(){
+ char timing = readSingleRegister( TSL_TIMING );
+ char gain_bit = ( timing << 3 ) >> 7; // keep only bit 4
+ int gain;
+ switch (gain_bit) {
+ case 0:
+ gain = 1;
+ break;
+ case 1:
+ gain = 16;
+ break;
+ default:
+ gain = 0;
+ break;
+ }
+ return gain;
+}
+
+int TSL2561_I2C::setGain( const int gain ){
+ char timing_old = readSingleRegister( TSL_TIMING );
+ char timing_new = 0;
+ int ack = 0;
+ switch (gain){
+ case 1:
+ timing_new = timing_old & 239; // sets bit 4 to 0
+ break;
+ case 16:
+ timing_new = timing_old | 16; // sets bit 4 to 1
+ break;
+ default:
+ ack = 2; // 2 used to indicate invalid entry
+ break;
+ }
+
+ if ( ack != 2 ){
+ ack = writeSingleRegister( TSL_TIMING, timing_new );
+ }
+ return ack;
+}
+
+float TSL2561_I2C::readIntegrationTime(){
+ char timing = readSingleRegister( TSL_TIMING );
+ char integ = ( timing << 6 ) >> 6; // keep bits 0 & 1
+ int itime;
+ switch (integ) {
+ case 0:
+ itime = 13.7;
+ break;
+ case 1:
+ itime = 101;
+ break;
+ case 2:
+ itime = 402;
+ break;
+ default:
+ itime = 0;
+ break;
+ }
+ return itime;
+}
+
+int TSL2561_I2C::setIntegrationTime( const float itime ){
+ char timing_old = readSingleRegister( TSL_TIMING );
+ char timing_new = 0;
+ int ack = 0;
+ if( abs( itime - 13.7 ) <= 0.001 ){
+ timing_new = timing_old & 252; // set bits 0 & 1 (INTEG) to 00
+ }
+ else if( abs( itime - 101 ) <= 0.001 ){
+ timing_new = timing_old | 1; // sets bit 0 to 1
+ timing_new = timing_new & 253; // sets bit 1 to 0
+ }
+ else if( abs( itime - 402 ) <= 0.001 ){
+ timing_new = timing_old | 3; // sets bits 0 & 1 (INTEG) to 11
+ }
+ else {
+ ack = 2; // indicates invalid entry
+ }
+ if ( ack != 2 ){
+ ack = writeSingleRegister( TSL_TIMING, timing_new );
+ }
+ return ack;
+}
+
+int TSL2561_I2C::readLowInterruptThreshold(){
+ char buffer[2] = { 0 };
+ readMultipleRegisters( TSL_THRESHLOWLOW, buffer, 2 );
+ int reading = (int)buffer[1] << 8 | (int)buffer[0];
+ return reading;
+}
+
+int TSL2561_I2C::readHighInterruptThreshold(){
+ char buffer[2] = { 0 };
+ readMultipleRegisters( TSL_THRESHHIGHLOW, buffer, 2 );
+ int reading = (int)buffer[1] << 8 | (int)buffer[0];
+ return reading;
+}
+
+int TSL2561_I2C::setLowInterruptThreshold( const int threshold ){
+ char threshold_bytes[2];
+ threshold_bytes[0] = threshold; // take lowest 8 bits of threshold
+ threshold_bytes[1] = threshold >> 8; // take highest 8 bits of threshold
+ int ack = writeMultipleRegisters( TSL_THRESHLOWLOW, threshold_bytes, 2 );
+ return ack;
+}
+
+int TSL2561_I2C::setHighInterruptThreshold( const int threshold ){
+ char threshold_bytes[2];
+ threshold_bytes[0] = threshold;
+ threshold_bytes[1] = threshold >> 8;
+ int ack = writeMultipleRegisters( TSL_THRESHHIGHLOW, threshold_bytes, 2 );
+ return ack;
+}
+
+int TSL2561_I2C::readInterruptPersistence(){
+ char interrupt = readSingleRegister( TSL_INTERRUPT );
+ char persist = ( interrupt << 4 ) >> 4; // discard bits 4 to 7, keep only bits 0 to 3
+ return (int)persist;
+}
+
+int TSL2561_I2C::setInterruptPersistence( const int persistence ){
+ char interrupt_old = readSingleRegister( TSL_INTERRUPT );
+ char interrupt_new = interrupt_old | (char)persistence; // sets bits 1 to 3 (PERSIST) to the value of persistence
+ int ack = writeSingleRegister( TSL_INTERRUPT, interrupt_new );
+ return ack;
+}
+
+int TSL2561_I2C::readInterruptControl(){
+ char interrupt = readSingleRegister( TSL_INTERRUPT );
+ char control = ( interrupt << 2 ) >> 6; // keep only bits 4 & 5
+ return (int)control;
+}
+
+int TSL2561_I2C::setInterruptControl( const int control ){
+ char interrupt_old = readSingleRegister( TSL_INTERRUPT );
+ char interrupt_new = interrupt_old | (char)( control << 4 ); // sets bits 4 and 5 (INTR) to the value of control
+ int ack = writeSingleRegister( TSL_INTERRUPT, interrupt_new );
+ return ack;
+}
+
+int TSL2561_I2C::clearInterrupt(){
+ char tx = 192;
+ int ack = i2c.write( TSL_SLAVE_ADDRESS << 1, &tx, 1 ); // writes 0b11000000 to command register to clear interrupt
+ return ack;
+}
+
+int TSL2561_I2C::getPartNumber(){
+ char id = readSingleRegister( TSL_ID );
+ char partno = id >> 4; // keep upper 4 bits
+ return (int)partno;
+}
+
+int TSL2561_I2C::getRevisionNumber(){
+ char id = readSingleRegister( TSL_ID );
+ char revno = ( id << 4 ) >> 4; // keep lower 4 bits
+ return (int)revno;
+}
\ No newline at end of file
