소스 검색

TSL2561 works to read lux value

Thomas Chef 6 달 전
부모
커밋
75dd57e171
3개의 변경된 파일458개의 추가작업 그리고 82개의 파일을 삭제
  1. 7 8
      main/config.h
  2. 380 74
      main/lux.c
  3. 71 0
      main/lux.h

+ 7 - 8
main/config.h

@@ -10,19 +10,18 @@
 //#define RX_TIMER_ENABLED
 //#define TRANCEIVER_ENABLED
 
-#define WIFI_ENABLED
-#define MQTT_ENABLED
-#define ENABLE_DS18B20
+//#define WIFI_ENABLED
+//#define MQTT_ENABLED
+//#define ENABLE_DS18B20
 
-//#define MQTT_DEBUG              // Add an extra debug string to the beginning of the topic-string
+#define MQTT_DEBUG              // Add an extra debug string to the beginning of the topic-string
 
 #define ONE_WIRE_BUS_IO           GPIO_NUM_33   // Temp sensors
 
 
-//#define ENABLE_LUX_SENSOR
-#define I2C_MASTER_SCL  4   // GPIO number for I2C Master clock line.
-#define I2C_MASTER_SDA  5   // GPIO number for I2C Master data line.
-#define I2C_MASTER_FREQUENCY 400000  // I2C master clock frequency
+#define ENABLE_LUX_SENSOR
+#define I2C_MASTER_SCL  19   // GPIO number for I2C Master clock line.
+#define I2C_MASTER_SDA  18   // GPIO number for I2C Master data line.
 #define CONFIG_TSL2561_I2C_ADDRESS 0x39
 
 

+ 380 - 74
main/lux.c

@@ -1,32 +1,3 @@
-/*
- * MIT License
- *
- * Copyright (c) 2017 David Antliff
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/**
- * @file app_main.c
- * @brief Example application for the TSL2561 Light-to-Digital Converter.
- */
-
 
 #include <stdio.h>
 #include "freertos/FreeRTOS.h"
@@ -36,80 +7,415 @@
 #include "driver/i2c.h"
 #include "esp_log.h"
 #include "sdkconfig.h"
+#include "lux.h"
+#include "mqtt.h"
+
 
-#include "smbus.h"
-#include "tsl2561.h"
 #include "config.h"
 
+// Code from:
+// https://github.com/espressif/esp-idf/blob/release/v4.4/examples/peripherals/i2c/i2c_simple/main/i2c_simple_main.c
+
+
 #ifdef ENABLE_LUX_SENSOR
 
-#define TAG "app"
+static const char *TAG = "LUX";
+#include <stdbool.h>
+bool _tsl2561AutoGain = true;
+tsl2561IntegrationTime_t _tsl2561IntegrationTime = TSL2561_INTEGRATIONTIME_101MS;
+tsl2561Gain_t _tsl2561Gain = TSL2561_GAIN_1X;
+
+#define I2C_MASTER_SCL_IO           I2C_MASTER_SCL      /*!< GPIO number used for I2C master clock */
+#define I2C_MASTER_SDA_IO           I2C_MASTER_SDA      /*!< GPIO number used for I2C master data  */
+#define I2C_MASTER_NUM              0                          /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
+#define I2C_MASTER_FREQ_HZ          400000                     /*!< I2C master clock frequency */
+#define I2C_MASTER_TX_BUF_DISABLE   0                          /*!< I2C master doesn't need buffer */
+#define I2C_MASTER_RX_BUF_DISABLE   0                          /*!< I2C master doesn't need buffer */
+#define I2C_MASTER_TIMEOUT_MS       1000
 
-#define I2C_MASTER_NUM           I2C_NUM_0
-#define I2C_MASTER_TX_BUF_LEN    0                     // disabled
-#define I2C_MASTER_RX_BUF_LEN    0                     // disabled
-#define I2C_MASTER_FREQ_HZ       100000
-#define I2C_MASTER_SDA_IO        I2C_MASTER_SDA
-#define I2C_MASTER_SCL_IO        I2C_MASTER_SCL
+/** TSL2561 I2C Registers */
+enum {
+  TSL2561_REGISTER_CONTROL = 0x00,          // Control/power register
+  TSL2561_REGISTER_TIMING = 0x01,           // Set integration time register
+  TSL2561_REGISTER_THRESHHOLDL_LOW = 0x02,  // Interrupt low threshold low-byte
+  TSL2561_REGISTER_THRESHHOLDL_HIGH = 0x03, // Interrupt low threshold high-byte
+  TSL2561_REGISTER_THRESHHOLDH_LOW = 0x04,  // Interrupt high threshold low-byte
+  TSL2561_REGISTER_THRESHHOLDH_HIGH = 0x05, // Interrupt high threshold high-byte
+  TSL2561_REGISTER_INTERRUPT = 0x06,  // Interrupt settings
+  TSL2561_REGISTER_CRC = 0x08,        // Factory use only
+  TSL2561_REGISTER_ID = 0x0A,         // TSL2561 identification setting
+  TSL2561_REGISTER_CHAN0_LOW = 0x0C,  // Light data channel 0, low byte
+  TSL2561_REGISTER_CHAN0_HIGH = 0x0D, // Light data channel 0, high byte
+  TSL2561_REGISTER_CHAN1_LOW = 0x0E,  // Light data channel 1, low byte
+  TSL2561_REGISTER_CHAN1_HIGH = 0x0F  // Light data channel 1, high byte
+};
 
-static void i2c_master_init(void)
+static esp_err_t i2c_master_init(void)
 {
     int i2c_master_port = I2C_MASTER_NUM;
-    i2c_config_t conf;
-    conf.mode = I2C_MODE_MASTER;
-    conf.sda_io_num = I2C_MASTER_SDA_IO;
-    conf.sda_pullup_en = GPIO_PULLUP_DISABLE;  // GY-2561 provides 10kΩ pullups
-    conf.scl_io_num = I2C_MASTER_SCL_IO;
-    conf.scl_pullup_en = GPIO_PULLUP_DISABLE;  // GY-2561 provides 10kΩ pullups
-    conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
+
+    i2c_config_t conf = {
+        .mode = I2C_MODE_MASTER,
+        .sda_io_num = I2C_MASTER_SDA_IO,
+        .scl_io_num = I2C_MASTER_SCL_IO,
+        .sda_pullup_en = GPIO_PULLUP_ENABLE,
+        .scl_pullup_en = GPIO_PULLUP_ENABLE,
+        .master.clk_speed = I2C_MASTER_FREQ_HZ,
+    };
+
     i2c_param_config(i2c_master_port, &conf);
-    i2c_driver_install(i2c_master_port, conf.mode,
-                       I2C_MASTER_RX_BUF_LEN,
-                       I2C_MASTER_TX_BUF_LEN, 0);
+
+    return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
+}
+
+static esp_err_t tsl2561_register_read(uint8_t reg_addr, uint8_t *data, size_t len)
+{
+    return i2c_master_write_read_device(I2C_MASTER_NUM, CONFIG_TSL2561_I2C_ADDRESS, &reg_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS);
+}
+
+void write8(uint8_t reg, uint8_t value)
+{
+  uint8_t data[2];
+  data[0] = reg;
+  data[1] = value;
+  i2c_master_write_to_device(I2C_MASTER_NUM, CONFIG_TSL2561_I2C_ADDRESS, data, 2, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS);
+}
+
+uint16_t read16(uint8_t reg)
+{
+  uint8_t data[2];
+  tsl2561_register_read(reg, data, 2);
+  return (data[1] << 8) | data[0];
+}
+uint8_t read8(uint8_t reg)
+{
+  uint8_t data;
+  tsl2561_register_read(reg, &data, 1);
+  return data;
+}
+
+void setIntegrationTime(tsl2561IntegrationTime_t time)
+{
+  /* Enable the device by setting the control bit to 0x03 */
+
+  /* Update the timing register */
+  write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, time | _tsl2561Gain);
+
+  /* Update value placeholders */
+  _tsl2561IntegrationTime = time;
+}
+void setGain(tsl2561Gain_t gain)
+{
+  /* Update the timing register */
+  write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, _tsl2561IntegrationTime | gain);
+
+  /* Update value placeholders */
+  _tsl2561Gain = gain;
+}
+void enableAutoRange(bool enable)
+{
+   _tsl2561AutoGain = enable ? true : false;
+}
+void enable(void)
+{
+  /* Enable the device by setting the control bit to 0x03 */
+  write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON);
+}
+void delay(uint32_t ms)
+{
+  vTaskDelay(ms / portTICK_RATE_MS);
+}
+void getData (uint16_t *broadband, uint16_t *ir)
+{
+  /* Wait x ms for ADC to complete */
+  switch (_tsl2561IntegrationTime)
+  {
+    case TSL2561_INTEGRATIONTIME_13MS:
+      delay(TSL2561_DELAY_INTTIME_13MS);  // KTOWN: Was 14ms
+      break;
+    case TSL2561_INTEGRATIONTIME_101MS:
+      delay(TSL2561_DELAY_INTTIME_101MS); // KTOWN: Was 102ms
+      break;
+    default:
+      delay(TSL2561_DELAY_INTTIME_402MS); // KTOWN: Was 403ms
+      break;
+  }
+
+  /* Reads a two byte value from channel 0 (visible + infrared) */
+  *broadband = read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW);
+
+  /* Reads a two byte value from channel 1 (infrared) */
+  *ir = read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW);
+
+}
+void getLuminosity (uint16_t *broadband, uint16_t *ir)
+{
+  bool valid = false;
+
+  /* If Auto gain disabled get a single reading and continue */
+  if(!_tsl2561AutoGain)
+  {
+    getData (broadband, ir);
+    return;
+  }
+
+  /* Read data until we find a valid range */
+  bool _agcCheck = false;
+  do
+  {
+    uint16_t _b, _ir;
+    uint16_t _hi, _lo;
+    tsl2561IntegrationTime_t _it = _tsl2561IntegrationTime;
+
+    /* Get the hi/low threshold for the current integration time */
+    switch(_it)
+    {
+      case TSL2561_INTEGRATIONTIME_13MS:
+        _hi = TSL2561_AGC_THI_13MS;
+        _lo = TSL2561_AGC_TLO_13MS;
+        break;
+      case TSL2561_INTEGRATIONTIME_101MS:
+        _hi = TSL2561_AGC_THI_101MS;
+        _lo = TSL2561_AGC_TLO_101MS;
+        break;
+      default:
+        _hi = TSL2561_AGC_THI_402MS;
+        _lo = TSL2561_AGC_TLO_402MS;
+        break;
+    }
+
+    getData(&_b, &_ir);
+
+    /* Run an auto-gain check if we haven't already done so ... */
+    if (!_agcCheck)
+    {
+      if ((_b < _lo) && (_tsl2561Gain == TSL2561_GAIN_1X))
+      {
+        /* Increase the gain and try again */
+        setGain(TSL2561_GAIN_16X);
+        /* Drop the previous conversion results */
+        getData(&_b, &_ir);
+        /* Set a flag to indicate we've adjusted the gain */
+        _agcCheck = true;
+      }
+      else if ((_b > _hi) && (_tsl2561Gain == TSL2561_GAIN_16X))
+      {
+        /* Drop gain to 1x and try again */
+        setGain(TSL2561_GAIN_1X);
+        /* Drop the previous conversion results */
+        getData(&_b, &_ir);
+        /* Set a flag to indicate we've adjusted the gain */
+        _agcCheck = true;
+      }
+      else
+      {
+        /* Nothing to look at here, keep moving ....
+           Reading is either valid, or we're already at the chips limits */
+        *broadband = _b;
+        *ir = _ir;
+        valid = true;
+      }
+    }
+    else
+    {
+      /* If we've already adjusted the gain once, just return the new results.
+         This avoids endless loops where a value is at one extreme pre-gain,
+         and the the other extreme post-gain */
+      *broadband = _b;
+      *ir = _ir;
+      valid = true;
+    }
+  } while (!valid);
+}
+uint32_t calculateLux(uint16_t broadband, uint16_t ir)
+{
+  unsigned long chScale;
+  unsigned long channel1;
+  unsigned long channel0;  
+  
+  /* Make sure the sensor isn't saturated! */
+  uint16_t clipThreshold;
+  switch (_tsl2561IntegrationTime)
+  {
+    case TSL2561_INTEGRATIONTIME_13MS:
+      clipThreshold = TSL2561_CLIPPING_13MS;
+      break;
+    case TSL2561_INTEGRATIONTIME_101MS:
+      clipThreshold = TSL2561_CLIPPING_101MS;
+      break;
+    default:
+      clipThreshold = TSL2561_CLIPPING_402MS;
+      break;
+  }
+
+  /* Return 65536 lux if the sensor is saturated */
+  if ((broadband > clipThreshold) || (ir > clipThreshold))
+  {
+    return 65536;
+  }
+
+  /* Get the correct scale depending on the intergration time */
+  switch (_tsl2561IntegrationTime)
+  {
+    case TSL2561_INTEGRATIONTIME_13MS:
+      chScale = TSL2561_LUX_CHSCALE_TINT0;
+      break;
+    case TSL2561_INTEGRATIONTIME_101MS:
+      chScale = TSL2561_LUX_CHSCALE_TINT1;
+      break;
+    default: /* No scaling ... integration time = 402ms */
+      chScale = (1 << TSL2561_LUX_CHSCALE);
+      break;
+  }
+
+  /* Scale for gain (1x or 16x) */
+  if (!_tsl2561Gain) chScale = chScale << 4;
+
+  /* Scale the channel values */
+  channel0 = (broadband * chScale) >> TSL2561_LUX_CHSCALE;
+  channel1 = (ir * chScale) >> TSL2561_LUX_CHSCALE;
+
+  /* Find the ratio of the channel values (Channel1/Channel0) */
+  unsigned long ratio1 = 0;
+  if (channel0 != 0) ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE+1)) / channel0;
+
+  /* round the ratio value */
+  unsigned long ratio = (ratio1 + 1) >> 1;
+
+  unsigned int b, m;
+
+#ifdef TSL2561_PACKAGE_CS
+  if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C))
+    {b=TSL2561_LUX_B1C; m=TSL2561_LUX_M1C;}
+  else if (ratio <= TSL2561_LUX_K2C)
+    {b=TSL2561_LUX_B2C; m=TSL2561_LUX_M2C;}
+  else if (ratio <= TSL2561_LUX_K3C)
+    {b=TSL2561_LUX_B3C; m=TSL2561_LUX_M3C;}
+  else if (ratio <= TSL2561_LUX_K4C)
+    {b=TSL2561_LUX_B4C; m=TSL2561_LUX_M4C;}
+  else if (ratio <= TSL2561_LUX_K5C)
+    {b=TSL2561_LUX_B5C; m=TSL2561_LUX_M5C;}
+  else if (ratio <= TSL2561_LUX_K6C)
+    {b=TSL2561_LUX_B6C; m=TSL2561_LUX_M6C;}
+  else if (ratio <= TSL2561_LUX_K7C)
+    {b=TSL2561_LUX_B7C; m=TSL2561_LUX_M7C;}
+  else if (ratio > TSL2561_LUX_K8C)
+    {b=TSL2561_LUX_B8C; m=TSL2561_LUX_M8C;}
+#else
+  if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T))
+    {b=TSL2561_LUX_B1T; m=TSL2561_LUX_M1T;}
+  else if (ratio <= TSL2561_LUX_K2T)
+    {b=TSL2561_LUX_B2T; m=TSL2561_LUX_M2T;}
+  else if (ratio <= TSL2561_LUX_K3T)
+    {b=TSL2561_LUX_B3T; m=TSL2561_LUX_M3T;}
+  else if (ratio <= TSL2561_LUX_K4T)
+    {b=TSL2561_LUX_B4T; m=TSL2561_LUX_M4T;}
+  else if (ratio <= TSL2561_LUX_K5T)
+    {b=TSL2561_LUX_B5T; m=TSL2561_LUX_M5T;}
+  else if (ratio <= TSL2561_LUX_K6T)
+    {b=TSL2561_LUX_B6T; m=TSL2561_LUX_M6T;}
+  else if (ratio <= TSL2561_LUX_K7T)
+    {b=TSL2561_LUX_B7T; m=TSL2561_LUX_M7T;}
+  else if (ratio > TSL2561_LUX_K8T)
+    {b=TSL2561_LUX_B8T; m=TSL2561_LUX_M8T;}
+#endif
+
+  unsigned long temp;
+  temp = ((channel0 * b) - (channel1 * m));
+
+  /* Do not allow negative lux value */
+  if (temp < 0) temp = 0;
+
+  /* Round lsb (2^(LUX_SCALE-1)) */
+  temp += (1 << (TSL2561_LUX_LUXSCALE-1));
+
+  /* Strip off fractional portion */
+  uint32_t lux = temp >> TSL2561_LUX_LUXSCALE;
+
+  /* Signal I2C had no errors */
+  return lux;
+}
+uint32_t readLuxSensor(void)
+{
+  uint16_t broadband;
+  uint16_t ir;
+  
+  getLuminosity(&broadband, &ir);
+  uint32_t lux = calculateLux(broadband, ir);
+  if( lux > 65000 ) lux=65000; // Set a maximum value
+  return lux;
 }
 
+
 static void tsl2561_task(void * pvParameter)
 {
-    // Set up I2C
-    i2c_master_init();
-    i2c_port_t i2c_num = I2C_MASTER_NUM;
-    uint8_t address = CONFIG_TSL2561_I2C_ADDRESS;
+    uint8_t data[2];
+    static uint32_t totalLux = 0;
+    static uint16_t loopCnt = 0;
+    TickType_t vLastWakeTime = xTaskGetTickCount();
+
+    ESP_ERROR_CHECK(i2c_master_init());
+    ESP_LOGI(TAG, "I2C initialized successfully");
 
-    // Set up the SMBus
-    smbus_info_t * smbus_info = smbus_malloc();
-    smbus_init(smbus_info, i2c_num, address);
-    smbus_set_timeout(smbus_info, 1000 / portTICK_RATE_MS);
+    delay(200);
+    enable();
+    delay(200);
 
-    // Set up the TSL2561 device
-    tsl2561_info_t * tsl2561_info = tsl2561_malloc();
-    tsl2561_init(tsl2561_info, smbus_info);
+    /* Read the TSL2561_REGISTER_ID register, on power up the register should have the value 0x05
+        The returned value consists of:
+        Bit 7:4 = Part number
+        Bit 3:0 = Revision number
+        
+        0x50 = TSL2561T/FN/CL Rev:0
+        */
+    
+    uint8_t id = read8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_ID);
+    ESP_LOGI(TAG, "WHO_AM_I = %02X", id);
 
-    // Set sensor integration time and gain
-    tsl2561_set_integration_time_and_gain(tsl2561_info, TSL2561_INTEGRATION_TIME_402MS, TSL2561_GAIN_1X);
-    //tsl2561_set_integration_time_and_gain(tsl2561_info, TSL2561_INTEGRATION_TIME_402MS, TSL2561_GAIN_16X);
+    setIntegrationTime(TSL2561_INTEGRATIONTIME_101MS);
+    setGain(TSL2561_GAIN_1X);
+
+    // Do an initial delay to make the different tasks to work out of sync to each other (not send all data at same time)
+    vTaskDelayUntil( &vLastWakeTime, 5000 / portTICK_PERIOD_MS );
 
     while (1)
     {
-        tsl2561_visible_t visible = 0;
-        tsl2561_infrared_t infrared = 0;
-        tsl2561_read(tsl2561_info, &visible, &infrared);
+        uint32_t lux = readLuxSensor();
+        totalLux += lux;
+        loopCnt++;
+
+        ESP_LOGI(TAG, "Lux: %u", lux);
+
+        // Once every minute, calc mean lux and send to server.
+        if( loopCnt == 6 ) {
+
+            char mqtt_s[50];
+            char value_s[10];
+
+            totalLux /= 6;
 
-        printf("\nFull spectrum: %d\n", visible + infrared);
-        printf("Infrared:      %d\n", infrared);
-        printf("Visible:       %d\n", visible);
-        printf("Lux:           %d\n", tsl2561_compute_lux(tsl2561_info, visible, infrared));
+            sprintf(mqtt_s,"garage/lux");
+            sprintf(value_s,"%u",totalLux);
 
-        vTaskDelay(2000 / portTICK_RATE_MS);
+            ESP_LOGI(TAG, "Topic:%s   Data:%s", mqtt_s, value_s);
+
+            sendMQTTMessage(mqtt_s, value_s);
+
+            totalLux = 0;
+            loopCnt = 0;
+        }
+        
+
+        vTaskDelayUntil( &vLastWakeTime, 10000 / portTICK_PERIOD_MS );
     }
 }
 
 void init_tsl2561()
 {
+
+
     xTaskCreate(&tsl2561_task, "tsl2561_task", 2048, NULL, 5, NULL);
 
-    // I2C/SMBus Test application
-    //extern void test_smbus_task(void * pvParameter);
-    //xTaskCreate(&test_smbus_task, "test_smbus_task", 2048, NULL, 5, NULL);
 }
 
 #endif

+ 71 - 0
main/lux.h

@@ -7,6 +7,77 @@
 
 void init_tsl2561();
 
+typedef enum
+{
+  TSL2561_INTEGRATIONTIME_13MS      = 0x00,    // 13.7ms
+  TSL2561_INTEGRATIONTIME_101MS     = 0x01,    // 101ms
+  TSL2561_INTEGRATIONTIME_402MS     = 0x02     // 402ms
+}
+tsl2561IntegrationTime_t;
+
+typedef enum
+{
+  TSL2561_GAIN_1X                   = 0x00,    // No gain
+  TSL2561_GAIN_16X                  = 0x10,    // 16x gain
+}
+tsl2561Gain_t;
+
+#define TSL2561_COMMAND_BIT       (0x80)    // Must be 1
+#define TSL2561_CLEAR_BIT         (0x40)    // Clears any pending interrupt (write 1 to clear)
+#define TSL2561_WORD_BIT          (0x20)    // 1 = read/write word (rather than byte)
+#define TSL2561_BLOCK_BIT         (0x10)    // 1 = using block read/write
+
+#define TSL2561_CONTROL_POWERON   (0x03)
+#define TSL2561_CONTROL_POWEROFF  (0x00)
+
+// Auto-gain thresholds
+#define TSL2561_AGC_THI_13MS      (4850)    // Max value at Ti 13ms = 5047
+#define TSL2561_AGC_TLO_13MS      (100)
+#define TSL2561_AGC_THI_101MS     (36000)   // Max value at Ti 101ms = 37177
+#define TSL2561_AGC_TLO_101MS     (200)
+#define TSL2561_AGC_THI_402MS     (63000)   // Max value at Ti 402ms = 65535
+#define TSL2561_AGC_TLO_402MS     (500)
+
+#define TSL2561_DELAY_INTTIME_13MS    (15)
+#define TSL2561_DELAY_INTTIME_101MS   (120)
+#define TSL2561_DELAY_INTTIME_402MS   (450)
+
+#define TSL2561_CLIPPING_13MS     (4900)
+#define TSL2561_CLIPPING_101MS    (37000)
+#define TSL2561_CLIPPING_402MS    (65000)
+
+#define TSL2561_LUX_LUXSCALE      (14)      // Scale by 2^14
+#define TSL2561_LUX_RATIOSCALE    (9)       // Scale ratio by 2^9
+#define TSL2561_LUX_CHSCALE       (10)      // Scale channel values by 2^10
+#define TSL2561_LUX_CHSCALE_TINT0 (0x7517)  // 322/11 * 2^TSL2561_LUX_CHSCALE
+#define TSL2561_LUX_CHSCALE_TINT1 (0x0FE7)  // 322/81 * 2^TSL2561_LUX_CHSCALE
+
+// T, FN and CL package values
+#define TSL2561_LUX_K1T           (0x0040)  // 0.125 * 2^RATIO_SCALE
+#define TSL2561_LUX_B1T           (0x01f2)  // 0.0304 * 2^LUX_SCALE
+#define TSL2561_LUX_M1T           (0x01be)  // 0.0272 * 2^LUX_SCALE
+#define TSL2561_LUX_K2T           (0x0080)  // 0.250 * 2^RATIO_SCALE
+#define TSL2561_LUX_B2T           (0x0214)  // 0.0325 * 2^LUX_SCALE
+#define TSL2561_LUX_M2T           (0x02d1)  // 0.0440 * 2^LUX_SCALE
+#define TSL2561_LUX_K3T           (0x00c0)  // 0.375 * 2^RATIO_SCALE
+#define TSL2561_LUX_B3T           (0x023f)  // 0.0351 * 2^LUX_SCALE
+#define TSL2561_LUX_M3T           (0x037b)  // 0.0544 * 2^LUX_SCALE
+#define TSL2561_LUX_K4T           (0x0100)  // 0.50 * 2^RATIO_SCALE
+#define TSL2561_LUX_B4T           (0x0270)  // 0.0381 * 2^LUX_SCALE
+#define TSL2561_LUX_M4T           (0x03fe)  // 0.0624 * 2^LUX_SCALE
+#define TSL2561_LUX_K5T           (0x0138)  // 0.61 * 2^RATIO_SCALE
+#define TSL2561_LUX_B5T           (0x016f)  // 0.0224 * 2^LUX_SCALE
+#define TSL2561_LUX_M5T           (0x01fc)  // 0.0310 * 2^LUX_SCALE
+#define TSL2561_LUX_K6T           (0x019a)  // 0.80 * 2^RATIO_SCALE
+#define TSL2561_LUX_B6T           (0x00d2)  // 0.0128 * 2^LUX_SCALE
+#define TSL2561_LUX_M6T           (0x00fb)  // 0.0153 * 2^LUX_SCALE
+#define TSL2561_LUX_K7T           (0x029a)  // 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B7T           (0x0018)  // 0.00146 * 2^LUX_SCALE
+#define TSL2561_LUX_M7T           (0x0012)  // 0.00112 * 2^LUX_SCALE
+#define TSL2561_LUX_K8T           (0x029a)  // 1.3 * 2^RATIO_SCALE
+#define TSL2561_LUX_B8T           (0x0000)  // 0.000 * 2^LUX_SCALE
+#define TSL2561_LUX_M8T           (0x0000)  // 0.000 * 2^LUX_SCALE
+
 
 
 #endif