A lux sensor library

Dependents:   Adafruit_TSL2561

Revision:
2:c45d34e9c3f0
Parent:
1:52b855c13204
Child:
3:5b5911bfc644
--- a/TSL2561.cpp	Tue Aug 04 17:15:01 2015 +0000
+++ b/TSL2561.cpp	Wed Aug 12 19:57:46 2015 +0000
@@ -26,260 +26,245 @@
 #include "TSL2561.h"
 
 TSL2561::TSL2561(PinName sda, PinName scl, char slave_address)
-:
-    i2c_p(new I2C(sda, scl)), 
+    :
+    i2c_p(new I2C(sda, scl)),
     i2c(*i2c_p),
     address(slave_address),
-    t_fine(0),
-    _integration(TSL2561_INTEGRATIONTIME_13MS),
-    _gain(TSL2561_GAIN_16X),
-    _initialized(false)
+    _integration(TSL2561_INTEGRATIONTIME_402MS),
+    _gain(TSL2561_GAIN_0X)
 {
-    //enable();
+    initialize();
 }
 
 TSL2561::TSL2561(I2C &i2c_obj, char slave_address)
-:
-    i2c_p(NULL), 
+    :
+    i2c_p(NULL),
     i2c(i2c_obj),
     address(slave_address),
-    t_fine(0),
-    _integration(TSL2561_INTEGRATIONTIME_13MS),
-    _gain(TSL2561_GAIN_16X),
-    _initialized(false)
+    _integration(TSL2561_INTEGRATIONTIME_402MS),
+    _gain(TSL2561_GAIN_0X)
 {
-    //enable();
+    initialize();
 }
 
-//TSL2561::~TSL2561()
-//{
-//    if (NULL != i2c_p)
-//        delete  i2c_p;
-//}
+TSL2561::~TSL2561()
+{
+    if (NULL != i2c_p) {
+        delete  i2c_p;
+    }
+}
 
 //The register addresses are all passed to i2c write via the bottum 4 bits of the command register
 //check and see if it is reading the correct id register (should read (0x10) for register value
 
-bool TSL2561::begin(void)
+bool TSL2561::initialize(void)
 {
-    //float idf;
+    float idf;    //debug
     uint16_t idu;
     char ID_REGISTER[1] = {TSL2561_REGISTER_ID};
     i2c.write(address, ID_REGISTER, 1, true);
     char DATA[1] = {0};
     i2c.read(address, DATA, 1, false);
     idu = DATA[0];
-    //idf = (float)idu;
-    
-    if (idu & 0x0A)
-    {
-        //pc.printf("FOUND TSL2561\r\n");
-    }
-    else
-    {
-        //pc.printf("NOT FOUND TSL2561\r\n");
-        //pc.printf("%4.0f ID\n",idf);
+    idf = (float)idu;    //debug
+
+    if (idu & 0x0A) {
+        pc.printf("FOUND TSL2561\r\n");    //debug
+    } else {
+        pc.printf("NOT FOUND TSL2561\r\n");    //debug
+        pc.printf("%4.0f ID\n",idf);    //debug
         return false;
     }
-    _initialized = true;
-    
+
     //set default integration time and gain
-    setTiming(_integration);
-    setGain(_gain);
-    
+    setTimingGain(_integration, _gain);
+
     disable();
-    
+
     return true;
 }
-        
-    
+
+
 
 void TSL2561::enable(void)
 {
-    if (!_initialized)
-    {
-        begin();
-    }
-    
     //power on device by writing 0x03 to the control register
     char CONTROL_ON[2] = {TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON};
     i2c.write(address, CONTROL_ON, 2);
-    
+    //***//Comment this wait out and the disable function to reduce read time, at the cost of power consumption.
+    //wait_ms(400);    //It takes a sec for the TSL to start up.
+    //***//
     //This sets everything to default values. (402ms integration time, interupts disabled etc.)
 }
-    
+
 void TSL2561::disable(void)
 {
-    if (!_initialized)
-    {
-        begin();
-    }
-    
-    //power off device by writing 0x00 in control register 
-    char CONTROL_OFF[2] = {TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF};
-    i2c.write(address, CONTROL_OFF, 2);
-}  
+    //power off device by writing 0x00 in control register
+    //***//
+    //char CONTROL_OFF[2] = {TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF};
+    //i2c.write(address, CONTROL_OFF, 2);
+    //***//
+}
 
-//function that sets gain to x16
-void TSL2561::setGain(tsl2561Gain_t gain)
+void TSL2561::setTimingGain(tsl2561IntegrationTime_t integration, tsl2561Gain_t gain)
 {
-    if(!_initialized)
-    {
-        begin();
-    }
-    enable();
-    _gain = gain;
-    
-    char GAIN_SETTING[2] = {TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _integration | _gain};
-    i2c.write(address, GAIN_SETTING, 2);
-    
-    disable();
-}   
-
-void TSL2561::setTiming(tsl2561IntegrationTime_t integration)
-{
-    if(!_initialized)
-    {
-        begin();
-    }
     enable();
     _integration = integration;
-    
+    _gain        = gain;
+
     char TIME_SETTING[2] = {TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _integration | _gain};
     i2c.write(address, TIME_SETTING, 2);
-    
+
     disable();
 }
 
+
+
+
+
+
+
+
+
+
 uint32_t TSL2561::calculateLux(uint16_t ch0, uint16_t ch1)
 {
     unsigned long chScale;
     unsigned long channel1;
     unsigned long channel0;
-    
+
     //scale the measurment if the integration time is not 402 ms
-    switch (_integration)
-    {
+    switch (_integration) {
         case TSL2561_INTEGRATIONTIME_13MS:
-        chScale = CHSCALE_TINT0;
-        break;
-        
+            chScale = CHSCALE_TINT0;
+            break;
+
         case TSL2561_INTEGRATIONTIME_101MS:
-        chScale = CHSCALE_TINT1;
-        break;
-        
+            chScale = CHSCALE_TINT1;
+            break;
+
         default: //No scaling when integration time is set to 402 ms
-        chScale = (1 << CH_SCALE);
-        break;
+            chScale = (1 << CH_SCALE);
+            break;
     }
-    
+
     //scale the measurment if gain is NOT x16
-    if(!_gain)
-    {
+    if(!_gain) {
         chScale = chScale << 4;
     }
-    
-    //scale the channel values 
+
+    //scale the channel values
     channel0 = (ch0 * chScale) >> CH_SCALE;
     channel1 = (ch1 * chScale) >> CH_SCALE;
-    
+
     //Find the ratio of the channel values (Channel 11/Channel 10) to set coeficients
     unsigned long ratio1 = 0;
-    if (channel0 != 0) 
-    {
+    if (channel0 != 0) {
         ratio1 = (channel1 << (RATIO_SCALE+1))/channel0;
     }
-    
+
     //round the ratio value
     unsigned long ratio = (ratio1 + 1) >> 1;
-    
+
     unsigned int b=0, m=0;
-    
+
     //check which coefficients the ratio dictates
-    
+
 #ifdef TSL2561_PACKAGE_CS //Adafruit sells the T package but these coefficients are for the CS package
-    if ((ratio >= 0) && (ratio <= K1C))
-    {b = B1C; m = M1C;}
-    else if (ratio <= K2C)
-    {b = B2C; m = M2C;}
-    else if (ratio <= K3C)
-    {b = B3C; m = M3C;}
-    else if (ratio <= K4C)
-    {b = B4C; m = M4C;}
-    else if (ratio <= K5C)
-    {b = B5C; m = M5C;}
-    else if (ratio <= K6C)
-    {b = B6C; m = M6C;}
-    else if (ratio <= K7C)
-    {b = B7C; m = M7C;}
-    else if (ratio <= K8C)
-    {b = B8C; m = M8C;}
+    if ((ratio >= 0) && (ratio <= K1C)) {
+        b = B1C;
+        m = M1C;
+    } else if (ratio <= K2C) {
+        b = B2C;
+        m = M2C;
+    } else if (ratio <= K3C) {
+        b = B3C;
+        m = M3C;
+    } else if (ratio <= K4C) {
+        b = B4C;
+        m = M4C;
+    } else if (ratio <= K5C) {
+        b = B5C;
+        m = M5C;
+    } else if (ratio <= K6C) {
+        b = B6C;
+        m = M6C;
+    } else if (ratio <= K7C) {
+        b = B7C;
+        m = M7C;
+    } else if (ratio <= K8C) {
+        b = B8C;
+        m = M8C;
+    }
 #else
-    if ((ratio >= 0) && (ratio <= K1T)) //Coefficients for all other packages, will probably use these
-    {b = B1T; m = M1T;}
-    else if (ratio <= K2T)
-    {b = B2T; m = M2T;}
-    else if (ratio <= K3T)
-    {b = B3T; m = M3T;}
-    else if (ratio <= K4T)
-    {b = B4T; m = M4T;}
-    else if (ratio <= K5T)
-    {b = B5T; m = M5T;}
-    else if (ratio <= K6T)
-    {b = B6T; m = M6T;}
-    else if (ratio <= K7T)
-    {b = B7T; m = M7T;}
-    else if (ratio <= K8T)
-    {b = B8T; m = M8T;}  
-#endif  
+    if ((ratio >= 0) && (ratio <= K1T)) { //Coefficients for all other packages, will probably use these
+        b = B1T;
+        m = M1T;
+    } else if (ratio <= K2T) {
+        b = B2T;
+        m = M2T;
+    } else if (ratio <= K3T) {
+        b = B3T;
+        m = M3T;
+    } else if (ratio <= K4T) {
+        b = B4T;
+        m = M4T;
+    } else if (ratio <= K5T) {
+        b = B5T;
+        m = M5T;
+    } else if (ratio <= K6T) {
+        b = B6T;
+        m = M6T;
+    } else if (ratio <= K7T) {
+        b = B7T;
+        m = M7T;
+    } else if (ratio <= K8T) {
+        b = B8T;
+        m = M8T;
+    }
+#endif
 
     unsigned long temp_val;
     temp_val = ((channel0*b) - (channel1*m));
-    
+
     //do not allow negative lux value
-    if (temp_val < 0) 
-    {
+    if (temp_val < 0) {
         temp_val = 0;
     }
-    
+
     //round lsb (2^(LUX_SCALE-1))
     temp_val += (1 << (LUX_SCALE-1));
-    
+
     //strip off fractional portion
     uint32_t lux = temp_val >> LUX_SCALE;
-    
+
     //signal I2C had no errors
     return lux;
 }
 
 uint32_t TSL2561::getFullLuminosity (void)
 {
-    if (_initialized)
-    {
-        begin();
-    }
     // Enable the device by setting the control bit to 0x03
     enable();
-    
+
     // Wait x ms for ADC to complete
-    switch (_integration)
-    {
+    switch (_integration) {
         case TSL2561_INTEGRATIONTIME_13MS:
-        wait(14/1000);
-        break;
+            wait(14/1000);
+            break;
         case TSL2561_INTEGRATIONTIME_101MS:
-        wait(102/1000);
-        break;
+            wait(102/1000);
+            break;
         default:
-        wait(403/1000);
-        break;
+            wait(403/1000);
+            break;
     }
-     
+
     uint32_t x; //will store data for luminosity
     //uint16_t x1; //will store data from channel 1 (optional to store data in steps)
     //uint16_t x0; //will store data from channel 0 (I just modified x)
-    
-    
+
+
     //Address the Ch1 lower data register and configure for Read Word
     char ch1_reg[1] = {TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW};
     //Create array to store data
@@ -289,7 +274,7 @@
     // Merge bytes
     x = ch1_data[0] | (ch1_data[1] << 8);    // int
     x <<= 16;
-    
+
     //Address the Ch1 lower data register and configure for Read Word
     char ch0_reg[1] = {TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW};
     //Create array to store data
@@ -298,50 +283,56 @@
     i2c.read(address, ch0_data, 2);
     // Merge bytes of channel 0 and channel 1
     x |= ch0_data[0] | (ch0_data[1] << 8);    // int
-    
+
     disable();
-    
+
     return x;
 }
-    
+
 uint16_t TSL2561::getLuminosity (uint8_t channel)
 {
     uint32_t x = getFullLuminosity();
-    
-    if (channel == 0)
-    {
-    // Reads two byte value from channel 0 (visible + infrared)
-    return (x & 0xFFFF);
-    }
-    else if (channel == 1) 
-    {
-    // Reads two byte value from channel 1 (infrared)
-    return (x >> 16);
-    }
-    else if (channel == 2) 
-    {
-    // Reads all and subtracts out just the visible
-    return ( (x & 0xFFFF) - (x >> 16));
+
+    if (channel == 0) {
+        // Reads two byte value from channel 0 (visible + infrared)
+        return (x & 0xFFFF);
+    } else if (channel == 1) {
+        // Reads two byte value from channel 1 (infrared)
+        return (x >> 16);
+    } else if (channel == 2) {
+        // Reads all and subtracts out just the visible
+        return ( (x & 0xFFFF) - (x >> 16));
     }
     
     // unknown channel
     return 0;
 }
-        
-    
-    
-    
-    
-    
-    
-    
 
-    
-    
-    
-    
+void TSL2561::read_lux(void)
+{
+    uint32_t full_lums;
+    //set to default gain (Note: going high gain to low is slower but more reliable, low gain to high gain is faster but less reliable)
+    setTimingGain(TSL2561_INTEGRATIONTIME_101MS, TSL2561_GAIN_16X); // start at high gain and long readings
+    //decreas gain/time if reading is to high (diable this block and change that^ line for fixed gain)
+    //take reading
+read_again:
+    full_lums = getFullLuminosity();
+    channal0 = (full_lums & 0xFFFF);
+    channal1  = (full_lums >> 16);
+    //If ir, or vis and ir, are within 5% of max then decreas the gain/time and repeat
+    //Pick the corect time to match ^
+    //if(((channal0 > 4794)  | (channal1 > 4792))  & (_gain != TSL2561_GAIN_0X)){ //13ms
+    if(((channal0 > 35318) | (channal1 > 35318)) & (_gain != TSL2561_GAIN_0X)){ //101ms
+    //if(((channal0 > 62258) | (channal1 > 62258)) & (_gain != TSL2561_GAIN_0X)){ //402ms
+        setTimingGain(_integration, TSL2561_GAIN_0X); 
+        goto read_again;
+    }
     
-    
+    //calculate lux from reading
+    lux = calculateLux(channal0, channal1);
     
+    pc.printf("gain: %d time: %d, lux:%d\r\n", _gain, _integration, lux);
     
-    
\ No newline at end of file
+}
+
+