mirror of
https://github.com/openshwprojects/OpenBK7231T_App.git
synced 2026-02-20 00:32:37 +01:00
LTR-303 driver (#1970)
* LTR-303 driver * Forgot discovery --------- Co-authored-by: openshwprojects <85486843+openshwprojects@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
aeafcb0863
commit
e500ac88b4
@@ -124,6 +124,7 @@ set(OBKM_SRC
|
||||
${OBK_SRCS}driver/drv_sm16703P.c
|
||||
${OBK_SRCS}driver/drv_simpleEEPROM.c
|
||||
${OBK_SRCS}driver/drv_leds_shared.c
|
||||
${OBK_SRCS}driver/drv_ltr_als.c
|
||||
${OBK_SRCS}driver/drv_spi.c
|
||||
${OBK_SRCS}driver/drv_spiLED.c
|
||||
${OBK_SRCS}driver/drv_spi_flash.c
|
||||
|
||||
@@ -140,6 +140,7 @@ OBKM_SRC += $(OBK_SRCS)driver/drv_sm15155e.c
|
||||
OBKM_SRC += $(OBK_SRCS)driver/drv_sm16703P.c
|
||||
OBKM_SRC += $(OBK_SRCS)driver/drv_simpleEEPROM.c
|
||||
OBKM_SRC += $(OBK_SRCS)driver/drv_leds_shared.c
|
||||
OBKM_SRC += $(OBK_SRCS)driver/drv_ltr_als.c
|
||||
OBKM_SRC += $(OBK_SRCS)driver/drv_sm2135.c
|
||||
OBKM_SRC += $(OBK_SRCS)driver/drv_sm2235.c
|
||||
OBKM_SRC += $(OBK_SRCS)driver/drv_soft_i2c.c
|
||||
|
||||
@@ -287,3 +287,7 @@ void Bridge_driver_DeInit();
|
||||
void Bridge_driver_QuickFrame();
|
||||
void Bridge_driver_OnChannelChanged(int ch, int value);
|
||||
/*************************************************************/
|
||||
|
||||
void LTR_Init();
|
||||
void LTR_OnEverySecond();
|
||||
void LTR_AppendInformationToHTTPIndexPage(http_request_t* request, int bPreState);
|
||||
|
||||
206
src/driver/drv_ltr_als.c
Normal file
206
src/driver/drv_ltr_als.c
Normal file
@@ -0,0 +1,206 @@
|
||||
#include "../obk_config.h"
|
||||
|
||||
#if ENABLE_DRIVER_LTR_ALS
|
||||
|
||||
#include "../new_pins.h"
|
||||
#include "../logging/logging.h"
|
||||
#include "drv_local.h"
|
||||
#include "drv_ltr_als.h"
|
||||
|
||||
static softI2C_t g_softI2C;
|
||||
static bool is_init = false;
|
||||
|
||||
static int ch_lux = -1;
|
||||
|
||||
static uint16_t als_ch0 = 0;
|
||||
static uint16_t als_ch1 = 0;
|
||||
static float als_lux = 0.0f;
|
||||
|
||||
static byte sec_left = 0;
|
||||
static byte sec_cycle = 4;
|
||||
|
||||
static void LTR_WriteReg(byte reg, byte val)
|
||||
{
|
||||
Soft_I2C_Start(&g_softI2C, LTR_I2C_ADDR);
|
||||
Soft_I2C_WriteByte(&g_softI2C, reg);
|
||||
Soft_I2C_WriteByte(&g_softI2C, val);
|
||||
Soft_I2C_Stop(&g_softI2C);
|
||||
}
|
||||
|
||||
static byte LTR_Read8(byte reg)
|
||||
{
|
||||
byte v;
|
||||
Soft_I2C_Start(&g_softI2C, LTR_I2C_ADDR);
|
||||
Soft_I2C_WriteByte(&g_softI2C, reg);
|
||||
Soft_I2C_Stop(&g_softI2C);
|
||||
Soft_I2C_Start(&g_softI2C, LTR_I2C_ADDR | 1);
|
||||
v = Soft_I2C_ReadByte(&g_softI2C, true);
|
||||
Soft_I2C_Stop(&g_softI2C);
|
||||
return v;
|
||||
}
|
||||
|
||||
static void LTR_Reset()
|
||||
{
|
||||
LTR_WriteReg(LTR_REG_ALS_CONTR, 0x02);
|
||||
rtos_delay_milliseconds(10);
|
||||
}
|
||||
|
||||
static void LTR_Setup()
|
||||
{
|
||||
LTR_Reset();
|
||||
byte manufac = LTR_Read8(LTR_REG_MANUFAC_ID);
|
||||
if(manufac != 0x05)
|
||||
{
|
||||
// retry once
|
||||
manufac = LTR_Read8(LTR_REG_MANUFAC_ID);
|
||||
if(manufac != 0x05)
|
||||
{
|
||||
ADDLOG_ERROR(LOG_FEATURE_SENSOR, "LTR unknown manufacturer %i", manufac);
|
||||
is_init = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
LTR_WriteReg(LTR_REG_ALS_CONTR, 0x01);
|
||||
rtos_delay_milliseconds(20);
|
||||
// dummy read
|
||||
LTR_Read8(LTR_REG_STATUS);
|
||||
is_init = true;
|
||||
}
|
||||
|
||||
static void LTR_ReadData()
|
||||
{
|
||||
if(!(LTR_Read8(LTR_REG_STATUS) & 0x04)) return;
|
||||
|
||||
byte c1l = LTR_Read8(LTR_REG_CH1_0);
|
||||
byte c1h = LTR_Read8(LTR_REG_CH1_1);
|
||||
byte c0l = LTR_Read8(LTR_REG_CH0_0);
|
||||
byte c0h = LTR_Read8(LTR_REG_CH0_1);
|
||||
|
||||
als_ch1 = ((uint16_t)c1h << 8) | c1l;
|
||||
als_ch0 = ((uint16_t)c0h << 8) | c0l;
|
||||
}
|
||||
|
||||
static void LTR_CalcLux()
|
||||
{
|
||||
if(als_ch0 == 0 && als_ch1 == 0)
|
||||
{
|
||||
als_lux = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
float r = (float)als_ch1 / (float)(als_ch0 + als_ch1);
|
||||
|
||||
if(r < 0.45f) als_lux = 1.7743f * als_ch0 + 1.1059f * als_ch1;
|
||||
else if(r < 0.64f) als_lux = 4.2785f * als_ch0 - 1.9548f * als_ch1;
|
||||
else if(r < 0.85f) als_lux = 0.5926f * als_ch0 + 0.1185f * als_ch1;
|
||||
else als_lux = 0.0f;
|
||||
}
|
||||
|
||||
static void LTR_Measure()
|
||||
{
|
||||
if(!is_init) return;
|
||||
|
||||
LTR_ReadData();
|
||||
LTR_CalcLux();
|
||||
|
||||
if(ch_lux >= 0) CHANNEL_Set(ch_lux, (int)(als_lux * 10), 0);
|
||||
}
|
||||
|
||||
commandResult_t LTR_ALS(const void* ctx, const char* cmd, const char* args, int flags)
|
||||
{
|
||||
Tokenizer_TokenizeString(args, TOKENIZER_ALLOW_QUOTES | TOKENIZER_DONT_EXPAND);
|
||||
|
||||
if(Tokenizer_CheckArgsCountAndPrintWarning(cmd, 3)) return CMD_RES_NOT_ENOUGH_ARGUMENTS;
|
||||
|
||||
int gain = Tokenizer_GetArgInteger(0);
|
||||
int integ = Tokenizer_GetArgInteger(1);
|
||||
int rep = Tokenizer_GetArgInteger(2);
|
||||
|
||||
LTR_WriteReg(LTR_REG_ALS_CONTR, 0x01 | (gain << 2));
|
||||
LTR_WriteReg(LTR_REG_MEAS_RATE, (rep & 0x07) | ((integ & 0x07) << 3));
|
||||
return CMD_RES_OK;
|
||||
}
|
||||
|
||||
commandResult_t LTR_INT(const void* ctx, const char* cmd, const char* args, int flags)
|
||||
{
|
||||
Tokenizer_TokenizeString(args, TOKENIZER_ALLOW_QUOTES | TOKENIZER_DONT_EXPAND);
|
||||
|
||||
if(Tokenizer_CheckArgsCountAndPrintWarning(cmd, 4)) return CMD_RES_NOT_ENOUGH_ARGUMENTS;
|
||||
|
||||
int en = Tokenizer_GetArgInteger(0);
|
||||
int low = Tokenizer_GetArgInteger(1);
|
||||
int high = Tokenizer_GetArgInteger(2);
|
||||
int persist = Tokenizer_GetArgInteger(3);
|
||||
|
||||
LTR_WriteReg(LTR_REG_ALS_THRES_LOW_0, low & 0xFF);
|
||||
LTR_WriteReg(LTR_REG_ALS_THRES_LOW_1, low >> 8);
|
||||
LTR_WriteReg(LTR_REG_ALS_THRES_UP_0, high & 0xFF);
|
||||
LTR_WriteReg(LTR_REG_ALS_THRES_UP_1, high >> 8);
|
||||
LTR_WriteReg(LTR_REG_INTERRUPT_PERSIST, persist & 0x0F);
|
||||
LTR_WriteReg(LTR_REG_INTERRUPT, en ? 0x02 : 0x00);
|
||||
|
||||
return CMD_RES_OK;
|
||||
}
|
||||
|
||||
commandResult_t LTR_Cycle(const void* ctx, const char* cmd, const char* args, int flags)
|
||||
{
|
||||
Tokenizer_TokenizeString(args, TOKENIZER_ALLOW_QUOTES | TOKENIZER_DONT_EXPAND);
|
||||
|
||||
if(Tokenizer_CheckArgsCountAndPrintWarning(cmd, 1)) return CMD_RES_NOT_ENOUGH_ARGUMENTS;
|
||||
|
||||
int s = Tokenizer_GetArgInteger(0);
|
||||
if(s < 1) return CMD_RES_BAD_ARGUMENT;
|
||||
|
||||
sec_cycle = s;
|
||||
sec_left = s;
|
||||
return CMD_RES_OK;
|
||||
}
|
||||
|
||||
void LTR_Init()
|
||||
{
|
||||
g_softI2C.pin_clk = Tokenizer_GetPin(1, 9);
|
||||
g_softI2C.pin_data = Tokenizer_GetPin(2, 14);
|
||||
|
||||
ch_lux = Tokenizer_GetArgIntegerDefault(3, -1);
|
||||
|
||||
Soft_I2C_PreInit(&g_softI2C);
|
||||
rtos_delay_milliseconds(100);
|
||||
|
||||
LTR_Setup();
|
||||
|
||||
//cmddetail:{"name":"LTR_ALS","args":"[gain] [integration] [repeat]",
|
||||
//cmddetail:"descr":"ALS configuration. Gain mappings: 0-x1 1-x2 2-x4 3-x8 6-x48 7-x96. Integration mappings (ms): 0-100 1-50 2-200 3-400 4-150 5-250 6-300 7-350. Repeat mappings (ms): 0-50 1-100 2-200 3-500 4-1000 5-2000.",
|
||||
//cmddetail:"fn":"LTR_ALS","file":"driver/drv_ltr_als.c","requires":"",
|
||||
//cmddetail:"examples":LTR_ALS 3 0 3 <br /> gain 8x, integration 100ms, repeat 500ms"}
|
||||
CMD_RegisterCommand("LTR_ALS", LTR_ALS, NULL);
|
||||
//cmddetail:{"name":"LTR_INT","args":"[enable] [als_low] [als_high] [persistance]",
|
||||
//cmddetail:"descr":"Interrupt configuration. Enable = 0-1, persistance (oversampling) = 0-15. als_low/als_high - raw thresholds",
|
||||
//cmddetail:"fn":"LTR_INT","file":"driver/drv_ltr_als.c","requires":"",
|
||||
//cmddetail:"examples":"LTR_INT 1 200 2000 4 <br /> enable interrupt, when measurement is lower than 200 or higher than 2000 4 times"}
|
||||
CMD_RegisterCommand("LTR_INT", LTR_INT, NULL);
|
||||
//cmddetail:{"name":"LTR_Cycle","args":"[IntervalSeconds]",
|
||||
//cmddetail:"descr":"This is the interval between measurements in seconds, by default 1. Max is 255.",
|
||||
//cmddetail:"fn":"LTR_Cycle","file":"driver/drv_ltr_als.c","requires":"",
|
||||
//cmddetail:"examples":"LTR_Cycle 60 <br /> measurement is taken every 60 seconds"}
|
||||
CMD_RegisterCommand("LTR_Cycle", LTR_Cycle, NULL);
|
||||
}
|
||||
|
||||
void LTR_OnEverySecond()
|
||||
{
|
||||
if(sec_left-- <= 0)
|
||||
{
|
||||
LTR_Measure();
|
||||
sec_left = sec_cycle;
|
||||
}
|
||||
}
|
||||
|
||||
void LTR_AppendInformationToHTTPIndexPage(http_request_t* request, int bPreState)
|
||||
{
|
||||
if(bPreState)
|
||||
return;
|
||||
|
||||
if(!is_init) hprintf255(request, "<b>LTR sensor not detected</b>");
|
||||
else hprintf255(request, "<h2>LTR Lux=%.1f</h2>", als_lux);
|
||||
}
|
||||
|
||||
#endif
|
||||
27
src/driver/drv_ltr_als.h
Normal file
27
src/driver/drv_ltr_als.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#define LTR_I2C_ADDR (0x29 << 1)
|
||||
|
||||
#define LTR_REG_ALS_CONTR 0x80
|
||||
#define LTR_REG_PS_CONTR 0x81
|
||||
#define LTR_REG_PS_LED 0x82
|
||||
#define LTR_REG_PS_N_PULSES 0x83
|
||||
#define LTR_REG_PS_MEAS_RATE 0x84
|
||||
#define LTR_REG_MEAS_RATE 0x85
|
||||
#define LTR_REG_PART_ID 0x86
|
||||
#define LTR_REG_MANUFAC_ID 0x87
|
||||
#define LTR_REG_CH1_0 0x88
|
||||
#define LTR_REG_CH1_1 0x89
|
||||
#define LTR_REG_CH0_0 0x8A
|
||||
#define LTR_REG_CH0_1 0x8B
|
||||
#define LTR_REG_STATUS 0x8C
|
||||
#define LTR_REG_PS_DATA_0 0x8D
|
||||
#define LTR_REG_PS_DATA_1 0x8E
|
||||
#define LTR_REG_INTERRUPT 0x8F
|
||||
#define LTR_REG_PS_THRES_UP_0 0x90
|
||||
#define LTR_REG_PS_THRES_UP_1 0x91
|
||||
#define LTR_REG_PS_THRES_LOW_0 0x92
|
||||
#define LTR_REG_PS_THRES_LOW_1 0x93
|
||||
#define LTR_REG_ALS_THRES_UP_0 0x97
|
||||
#define LTR_REG_ALS_THRES_UP_1 0x98
|
||||
#define LTR_REG_ALS_THRES_LOW_0 0x99
|
||||
#define LTR_REG_ALS_THRES_LOW_1 0x9A
|
||||
#define LTR_REG_INTERRUPT_PERSIST 0x9E
|
||||
@@ -1401,6 +1401,22 @@ static driver_t g_drivers[] = {
|
||||
NULL, // onHassDiscovery
|
||||
false, // loaded
|
||||
},
|
||||
#endif
|
||||
#if ENABLE_DRIVER_LTR_ALS
|
||||
//drvdetail:{"name":"LTR_ALS",
|
||||
//drvdetail:"title":"TODO",
|
||||
//drvdetail:"descr":"LTR-303/329 ambient light sensor driver.",
|
||||
//drvdetail:"requires":""}
|
||||
{ "LTR_ALS", // Driver Name
|
||||
LTR_Init, // Init
|
||||
LTR_OnEverySecond, // onEverySecond
|
||||
LTR_AppendInformationToHTTPIndexPage, // appendInformationToHTTPIndexPage
|
||||
NULL, // runQuickTick
|
||||
NULL, // stopFunction
|
||||
NULL, // onChannelChanged
|
||||
NULL, // onHassDiscovery
|
||||
false, // loaded
|
||||
},
|
||||
#endif
|
||||
//{ "", NULL, NULL, NULL, NULL, NULL, NULL, NULL, false },
|
||||
};
|
||||
|
||||
@@ -2386,6 +2386,11 @@ void doHomeAssistantDiscovery(const char* topic, http_request_t* request) {
|
||||
dev_info = hass_createEnumChannelInfo(i);
|
||||
}
|
||||
break;
|
||||
case ChType_Illuminance_div10:
|
||||
{
|
||||
dev_info = hass_init_sensor_device_info(ILLUMINANCE_SENSOR, i, 2, 1, 1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
int numOptions;
|
||||
|
||||
@@ -1384,6 +1384,7 @@ int ChannelType_GetDivider(int type) {
|
||||
case ChType_Frequency_div10:
|
||||
case ChType_ReadOnly_div10:
|
||||
case ChType_Current_div10:
|
||||
case ChType_Illuminance_div10:
|
||||
return 10;
|
||||
case ChType_Frequency_div100:
|
||||
case ChType_Current_div100:
|
||||
@@ -1453,6 +1454,7 @@ const char *ChannelType_GetUnit(int type) {
|
||||
case ChType_ReactivePower:
|
||||
return "vAr";
|
||||
case ChType_Illuminance:
|
||||
case ChType_Illuminance_div10:
|
||||
return "Lux";
|
||||
case ChType_Ph:
|
||||
return "Ph";
|
||||
@@ -1510,6 +1512,7 @@ const char *ChannelType_GetTitle(int type) {
|
||||
case ChType_ReactivePower:
|
||||
return "ReactivePower";
|
||||
case ChType_Illuminance:
|
||||
case ChType_Illuminance_div10:
|
||||
return "Illuminance";
|
||||
case ChType_Ph:
|
||||
return "Ph Water Quality";
|
||||
@@ -2422,6 +2425,7 @@ const char* g_channelTypeNames[] = {
|
||||
"Enum",
|
||||
"ReadOnlyEnum",
|
||||
"Current_div10",
|
||||
"Illuminance_div10",
|
||||
"error",
|
||||
"error",
|
||||
"error",
|
||||
|
||||
@@ -1127,6 +1127,13 @@ typedef enum channelType_e {
|
||||
//chandetail:"file":"new_pins.h",
|
||||
//chandetail:"driver":""}
|
||||
ChType_Current_div10,
|
||||
//chandetail:{"name":"Illuminance_div10",
|
||||
//chandetail:"title":"Illuminance_div10",
|
||||
//chandetail:"descr":"Illuminance in Lux",
|
||||
//chandetail:"enum":"ChType_Illuminance_div10",
|
||||
//chandetail:"file":"new_pins.h",
|
||||
//chandetail:"driver":""}
|
||||
ChType_Illuminance_div10,
|
||||
//chandetail:{"name":"Max",
|
||||
//chandetail:"title":"TODO",
|
||||
//chandetail:"descr":"This is the current total number of available channel types.",
|
||||
|
||||
@@ -114,6 +114,8 @@
|
||||
#define ENABLE_DRIVER_NEO6M 1
|
||||
#define ENABLE_TIME_SUNRISE_SUNSET 1
|
||||
#define ENABLE_TIME_DST 1
|
||||
|
||||
#define ENABLE_DRIVER_LTR_ALS 1
|
||||
#define ENABLE_DRIVER_SM16703P 1
|
||||
#define ENABLE_DRIVER_PIXELANIM 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user