|
@@ -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, ®_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
|