文章目录
- 前言
- 一、基础介绍
- 二、电路图
-
- [2.1 电路图1](#2.1 电路图1)
- [2.2 电路图2------实际采用](#2.2 电路图2——实际采用)
- 三、代码
- 四、编译
- 五、刷机
- 六、测试结果
- 小结
前言
本章介绍如何在涂鸦T2-U开发板上添加光感bh1750驱动并实现定时读取数据。
一、基础介绍
这篇文章有bh1750的基础介绍。
我这里总结一下。
bh1750采用i2c通信,有5个引脚,vcc,gnd,sda,scl,add。
其中add接gnd时i2c地址为0x23,接vcc为0x5c。
模式:
三种分辨率模式,H(1lx),H2(0.5lx),L(41lx),其中1lx表示返回的数值1表示1lx,用于计算实际lx。
两种测试:连续,一次。
总共组合就是6中,常用的是一次H分辨率模式。
指令:
以一次H分辨率模式为例。
- 软重置:__bh1750_write_cmd(dev, BH1750_CMD_SOFT_RESET);
- 设置模式:__bh1750_write_cmd(dev, BH1750_CMD_ONE_H_RES_MODE);
- 等待采样:__bh1750_delay_ms(180);
- 读取采样值:__bh1750_read_data(dev, 2, buf);
如上述四步就可以读取到光感数据,剩下的就是实现接口和数据处理。
二、电路图
2.1 电路图1
一开始我打算使用默认的pin28和pin29作为sda和scl,但是不知道是不是和打开了串口调试开关有关,i2c通信失败,后续采用了20,22。
注意,虽然图上标的是p1和p0,但是对应的pin应该是28,29。
2.2 电路图2------实际采用
三、代码
代码基于tuyaos_sensor_hub_demo_quickstart实现的。
需要复制该项目,并仿照温感sht30的驱动,添加bh1750驱动。
tdd_sensor_light.h
c
/**
* @file tdd_sensor_light.h
* @brief tdd_sensor_light module is used to drive light & humidity sensor
* @version 0.1
* @date 2022-08-03
*/
#ifndef __TDD_SENSOR_LIGHT_H__
#define __TDD_SENSOR_LIGHT_H__
#include "tdl_sensor_type.h"
#include "tdd_sensor_i2c.h"
#ifdef __cplusplus
extern "C" {
#endif
/***********************************************************
************************macro define************************
***********************************************************/
/**
* @brief element list
*/
#define SR_LT_ELE_ID_LIGHT 0x00
#define SR_LT_ELE_NUM 0x01
/**
* @brief command list
*/
#define SR_LT_CMD_SOFT_RESET 0x00 // soft reset, param: none
#define SR_LT_CMD_GET_SERIAL_NBR 0x01 // read serial number, param: SR_LT_CMD_READ_SERIAL_NBR
#define SR_LT_CMD_SET_PREC 0x02 // set measurement precision, param: SR_LT_PREC_E
#define SR_LT_CMD_SET_FREQ 0x03 // set measurement frequency, param: SR_LT_FREQ_E
#define SR_LT_CMD_SET_ALT_LIMIT 0x04 // set alert thresholds, param: SR_LT_LIMIT_T
#define SR_LT_CMD_GET_ALT_LIMIT 0x05 // get alert thresholds, param: SR_LT_LIMIT_T
#define SR_LT_CMD_ENABLE_ALT_PIN 0x06 // enable alert pin, param: SR_LT_ALT_PIN_T
#define SR_LT_CMD_DISABLE_ALT_PIN 0x07 // disable alert pin, param: TKL_GPIO_NAME_E
#define SR_LT_CMD_GET_STATUS 0x08 // read status register, param: SR_LT_STATUS_U
#define SR_LT_CMD_CLR_STATUS 0x09 // clear status register, param: none
#define SR_LT_CMD_ENABLE_HEATER 0x0A // enable heater, param: none
#define SR_LT_CMD_DISABLE_HEATER 0x0B // disable heater, param: none
#define SR_LT_CMD_ACTIVATE_HEATER 0x0C // activate heater for a while, param: SR_LT_HEATER_T
/**
* @brief I2C address list
*/
#define SR_I2C_ADDR_BH1750_A 0x23 // BH1750 : ADDR pin - GND
#define SR_I2C_ADDR_BH1750_B 0x5c // BH1750 : ADDR pin - VCC
// #define SR_I2C_ADDR_SHT4X_A 0x44 // SHT4x-A */
// #define SR_I2C_ADDR_SHT4X_B 0x45 // SHT4x-B */
// #define SR_I2C_ADDR_CHT8305_A 0x40 // CHT8305 : AD0 pin - GND
// #define SR_I2C_ADDR_CHT8305_B 0x44 // CHT8305 : AD0 pin - VCC
// #define SR_I2C_ADDR_CHT8305_C 0x48 // CHT8305 : AD0 pin - SDA
// #define SR_I2C_ADDR_CHT8305_D 0x4C // CHT8305 : AD0 pin - SCL
/***********************************************************
***********************typedef define***********************
***********************************************************/
/**
* @brief measurement precision
* enum value for SR_LT_CMD_SET_PREC
*/
typedef BYTE_T SR_LT_PREC_E;
#define SR_LT_PREC_HIGH 0x00
#define SR_LT_PREC_MEDIUM 0x01
#define SR_LT_PREC_LOW 0x02
#define SR_LT_PREC_INVALID 0x03
/**
* @brief measurement frequency
* enum value for SR_LT_CMD_SET_FREQ
*/
typedef BYTE_T SR_LT_FREQ_E;
#define SR_LT_FREQ_ONE 0x00
#define SR_LT_FREQ_CON 0x01
#define SR_LT_FREQ_INVALID 0x02
/**
* @brief heater work power
* enum value for SR_LT_CMD_ACTIVATE_HEATER
*/
typedef BYTE_T SR_LT_HEATER_PWR_E;
#define SR_LT_HEATER_PWR_HIGH 0x00
#define SR_LT_HEATER_PWR_MEDIUM 0x01
#define SR_LT_HEATER_PWR_LOW 0x02
#define SR_LT_HEATER_PWR_INVALID 0x03
/**
* @brief heater work time
* enum value for SR_LT_CMD_ACTIVATE_HEATER
*/
typedef BYTE_T SR_LT_HEATER_TIM_E;
#define SR_LT_HEATER_TIM_LONG 0x00
#define SR_LT_HEATER_TIM_SHORT 0x01
#define SR_LT_HEATER_TIM_INVALID 0x02
/**
* @brief I2C configuration
*/
typedef struct {
UCHAR_T port;
UCHAR_T addr;
SR_I2C_GPIO_T gpio;
} SR_LT_I2C_CFG_T;
/**
* @brief measurement configuration
* param type for tdd_sensor_bh1750_register
*/
typedef struct {
SR_LT_PREC_E prec;
SR_LT_FREQ_E freq;
} SR_LT_MEAS_CFG_T;
/**
* @brief alert limit
* param type for SR_LT_CMD_SET_ALT_LIMIT
* and SR_LT_CMD_GET_ALT_LIMIT
* light_range: -40 ~ 125 (°C)
* humi_range: 0 ~ 100 (%RH)
*/
typedef struct {
SR_VAL_U light_high_set;
SR_VAL_U light_high_clear;
SR_VAL_U light_low_set;
SR_VAL_U light_low_clear;
} SR_LT_LIMIT_T;
/**
* @brief alert pin configuration
* param type for SR_LT_CMD_ENABLE_ALT_PIN
*/
typedef struct {
TUYA_GPIO_NUM_E pin;
TUYA_GPIO_IRQ_T irq;
} SR_LT_ALT_CFG_T;
/**
* @brief heater configuration
* param type for SR_LT_CMD_ACTIVATE_HEATER
*/
typedef struct {
SR_LT_HEATER_PWR_E power;
SR_LT_HEATER_TIM_E time;
} SR_LT_HEATER_T;
/**
* @brief status register value
* param type for SR_LT_CMD_GET_STATUS
*/
typedef union {
// little-endian
struct {
USHORT_T crc_status : 1;
USHORT_T cmd_status : 1;
USHORT_T reserve0 : 2;
USHORT_T reset_detected : 1;
USHORT_T reserve1 : 5;
USHORT_T light_alert : 1;
USHORT_T humi_alert : 1;
USHORT_T reserve2 : 1;
USHORT_T heater_status : 1;
USHORT_T reserve3 : 1;
USHORT_T alert_pending : 1;
} bit;
// can use "word" directly
USHORT_T word;
} SR_LT_STATUS_U;
/**
* @brief serial number
* param type for SR_LT_CMD_READ_SERIAL_NBR
*/
typedef struct {
UINT_T val;
} SR_LT_SERIAL_NBR_T;
/***********************************************************
********************function declaration********************
***********************************************************/
/**
* @brief register bh1750 device
*
* @param[in] name: device name
* @param[in] i2c_cfg: i2c configuration
* @param[in] meas_cfg: measurement configuration
*
* @return OPRT_OK on success, others on error
*/
OPERATE_RET tdd_sensor_bh1750_register(IN CHAR_T *name, IN SR_LT_I2C_CFG_T i2c_cfg, IN SR_LT_MEAS_CFG_T meas_cfg);
#ifdef __cplusplus
}
#endif
#endif /* __TDD_SENSOR_LIGHT_H__ */
app_light.h
c
/**
* @file app_light.h
* @brief RH-T sensor application demo
* @version 0.1
* @date 2022-09-01
*/
#ifndef __APP_LIGHT_H__
#define __APP_LIGHT_H__
#include "tuya_cloud_com_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/***********************************************************
************************macro define************************
***********************************************************/
/*
*@brief product id define
*/
#define PID "8q46zzdfuofastqr"
/**
* @brief function define
*/
#define APP_LIGHT_READ_CYCLE 2 * 1000 // units:ms
#define APP_LIGHT_REPORT_CYCLE 10 * 1000 // units:ms
/**
* @brief pin define
*/
#define BH1750_SCL_PIN GPIO_NUM_20
#define BH1750_SDA_PIN GPIO_NUM_22
#define BH1750_ALT_PIN GPIO_NUM_14
/**
* @brief DP list
*/
#define DP_ID_LIGHT 1
#define DP_ID_LIGHT_MAX 10
#define DP_ID_LIGHT_MIN 11
#define DP_ID_LIGHT_ALT 12
#define DP_ID_SWITCH 21
#define MAX_DP_NUM 9
/**
* @brief Data scale
*/
#define LIGHT_SCALE 1 // raw-data * 10
/**
*@brief report interval
*/
#define APP_LIGHT_REPORT_INTERVAL 20 // default: 2.0 ℃
/**
*@brief kv key name
*/
#define KEY_NAME "light"
/***********************************************************
***********************typedef define***********************
***********************************************************/
/***********************************************************
********************function declaration********************
***********************************************************/
/**
* @brief light main
*
* @param none
*
* @return OPRT_OK on success. Others on error, please refer to "tuya_error_code.h"
*/
OPERATE_RET app_light_init(VOID_T);
/**
* @brief DP processing
*
* @param[in] dp: dp data
*
* @return none
*/
VOID_T app_light_dp_proc(CONST TY_OBJ_DP_S *dp);
/**
* @brief report all DP data
*
* @param none
*
* @return none
*/
VOID_T app_light_repo_all_dp(VOID_T);
#ifdef __cplusplus
}
#endif
#endif /* __APP_LIGHT_H__ */
tdd_sensor_bh1750.c
c
/**
* @file tdd_sensor_bh1750.c
* @brief tdd_sensor_bh1750 module is used to drive bh1750 chip
* @version 0.1
* @date 2022-08-03
*/
#include "tdl_sensor_driver.h"
#include "tdd_sensor_light.h"
#include "tkl_gpio.h"
#include "tal_system.h"
#include "tal_log.h"
/***********************************************************
************************macro define************************
***********************************************************/
/**
* @brief CRC result
*/
#define CRC_OK (0)
#define CRC_ERR (-1)
/**
* @brief work status
*/
#define BH1750_CLOSE 0
#define BH1750_OPEN (!BH1750_CLOSE)
/**
* @brief resource array index
*/
#define BH1750_RSRC_INDEX_STAT 0
#define BH1750_RSRC_INDEX_ADDR 1
#define BH1750_RSRC_INDEX_PREC 2 // H-Resolution Mode/H-Resolution Mode2/L-Resolution
#define BH1750_RSRC_INDEX_FREQ 3 // one/continue
#define BH1750_RSRC_INDEX_RESL 4 // mode match value, such as H=1,H2=0.5,L=41
/***********************************************************
***********************typedef define***********************
***********************************************************/
/**
* @brief bh1750 command
*/
typedef USHORT_T BH1750_CMD_E;
#define BH1750_CMD_POWER_DOWN 0x00 // power down
#define BH1750_CMD_POWER_ON 0x01 // power on
#define BH1750_CMD_SOFT_RESET 0x07 // reset
#define BH1750_CMD_CON_H_RES_MODE 0x10 // Continuously H-Resolution Mode
#define BH1750_CMD_CON_H_RES_MODE2 0x11 // Continuously H-Resolution Mode2
#define BH1750_CMD_CON_L_RES_MODE 0x13 // Continuously L-Resolution Mode
#define BH1750_CMD_ONE_H_RES_MODE 0x20 // One Time H-Resolution Mode
#define BH1750_CMD_ONE_H_RES_MODE2 0x21 // One Time H-Resolution Mode2
#define BH1750_CMD_ONE_L_RES_MODE 0x23 // One Time L-Resolution Mode
// #define BH1750_CMD_SOFT_RESET 0x30A2 // soft reset
#define BH1750_CMD_READ_SERIALNBR 0x3780 // read serial number
#define BH1750_CMD_HEATER_ENABLE 0x306D // enabled heater
#define BH1750_CMD_HEATER_DISABLE 0x3066 // disable heater
#define BH1750_CMD_READ_STATUS 0xF32D // read status register
#define BH1750_CMD_CLEAR_STATUS 0x3041 // clear status register
#define BH1750_CMD_ART 0x2B32 // activate ART
#define BH1750_CMD_BREAK 0x3093 // stop periodic data acquisition mode
#define BH1750_CMD_FETCH_DATA 0xE000 // readout measurements for periodic mode
#define BH1750_CMD_MEAS_PERI_05_H 0x2032 // measurement: periodic 0.5 mps, high repeatability
#define BH1750_CMD_MEAS_PERI_05_M 0x2024 // measurement: periodic 0.5 mps, medium repeatability
#define BH1750_CMD_MEAS_PERI_05_L 0x202F // measurement: periodic 0.5 mps, low repeatability
#define BH1750_CMD_MEAS_PERI_1_H 0x2130 // measurement: periodic 1 mps, high repeatability
#define BH1750_CMD_MEAS_PERI_1_M 0x2126 // measurement: periodic 1 mps, medium repeatability
#define BH1750_CMD_MEAS_PERI_1_L 0x212D // measurement: periodic 1 mps, low repeatability
#define BH1750_CMD_MEAS_PERI_2_H 0x2236 // measurement: periodic 2 mps, high repeatability
#define BH1750_CMD_MEAS_PERI_2_M 0x2220 // measurement: periodic 2 mps, medium repeatability
#define BH1750_CMD_MEAS_PERI_2_L 0x222B // measurement: periodic 2 mps, low repeatability
#define BH1750_CMD_MEAS_PERI_4_H 0x2334 // measurement: periodic 4 mps, high repeatability
#define BH1750_CMD_MEAS_PERI_4_M 0x2322 // measurement: periodic 4 mps, medium repeatability
#define BH1750_CMD_MEAS_PERI_4_L 0x2329 // measurement: periodic 4 mps, low repeatability
#define BH1750_CMD_MEAS_PERI_10_H 0x2737 // measurement: periodic 10 mps, high repeatability
#define BH1750_CMD_MEAS_PERI_10_M 0x2721 // measurement: periodic 10 mps, medium repeatability
#define BH1750_CMD_MEAS_PERI_10_L 0x272A // measurement: periodic 10 mps, low repeatability
#define BH1750_CMD_MEAS_POLLING_H 0x2400 // measurement: polling, high repeatability
#define BH1750_CMD_MEAS_POLLING_M 0x240B // measurement: polling, medium repeatability
#define BH1750_CMD_MEAS_POLLING_L 0x2416 // measurement: polling, low repeatability
#define BH1750_CMD_MEAS_CLOCKSTR_H 0x2C06 // measurement: clock stretching, high repeatability
#define BH1750_CMD_MEAS_CLOCKSTR_M 0x2C0D // measurement: clock stretching, medium repeatability
#define BH1750_CMD_MEAS_CLOCKSTR_L 0x2C10 // measurement: clock stretching, low repeatability
#define BH1750_CMD_W_AL_LIM_HS 0x611D // write alert limits, high set
#define BH1750_CMD_W_AL_LIM_HC 0x6116 // write alert limits, high clear
#define BH1750_CMD_W_AL_LIM_LC 0x610B // write alert limits, low clear
#define BH1750_CMD_W_AL_LIM_LS 0x6100 // write alert limits, low set
#define BH1750_CMD_R_AL_LIM_LS 0xE102 // read alert limits, low set
#define BH1750_CMD_R_AL_LIM_LC 0xE109 // read alert limits, low clear
#define BH1750_CMD_R_AL_LIM_HS 0xE11F // read alert limits, high set
#define BH1750_CMD_R_AL_LIM_HC 0xE114 // read alert limits, high clear
/***********************************************************
********************function declaration********************
***********************************************************/
/***********************************************************
***********************variable define**********************
***********************************************************/
/**
* @brief element value type
*/
#if (SR_CONFIG_NO_FPU == 1)
STATIC SR_ELE_CFG_T sg_ele_val_tp[SR_LT_ELE_NUM] = {
{
.id = SR_LT_ELE_ID_LIGHT,
.val_tp = SR_VAL_TP_INT,
}
};
#else
STATIC SR_ELE_CFG_T sg_ele_val_tp[SR_LT_ELE_NUM] = {
{
.id = SR_LT_ELE_ID_LIGHT,
.val_tp = SR_VAL_TP_FLOAT,
}
};
#endif
/***********************************************************
***********************function define**********************
***********************************************************/
/**
* @brief delay (ms)
*
* @param[in] tm: delay time
*
* @return none
*/
STATIC VOID_T __bh1750_delay_ms(IN CONST ULONG_T tm)
{
tal_system_sleep(tm);
}
/**
* @brief get CRC8 value for bh1750
*
* @param[in] data: data to be calculated
* @param[in] len: data length
*
* @return CRC8 value
*/
STATIC UCHAR_T __bh1750_get_crc8(IN CONST UCHAR_T *data, IN USHORT_T len)
{
UCHAR_T i;
UCHAR_T crc = 0xFF;
while (len--) {
crc ^= *data;
for (i = 8; i > 0; --i) {
if (crc & 0x80) {
crc = (crc << 1) ^ 0x31;
} else {
crc = (crc << 1);
}
}
data++;
}
return crc;
}
/**
* @brief check CRC8
*
* @param[in] data: data to be checked
* @param[in] len: data length
* @param[in] crc_val: crc value
*
* @return check result
*/
STATIC INT_T __bh1750_check_crc8(IN CONST UCHAR_T *data, IN CONST USHORT_T len, IN CONST UCHAR_T crc_val)
{
if (__bh1750_get_crc8(data, len) != crc_val) {
return CRC_ERR;
}
return CRC_OK;
}
/**
* @brief read data from bh1750
*
* @param[in] dev: device resource
* @param[in] len: data length
* @param[out] data: data received from bh1750
*
* @return none
*/
STATIC OPERATE_RET __bh1750_read_data(IN CONST SR_RSRC_T *dev, IN CONST USHORT_T len, OUT UCHAR_T *data)
{
SR_I2C_MSG_T rd_msg = {
.flags = SR_I2C_FLAG_RD,
.addr = dev->info[BH1750_RSRC_INDEX_ADDR],
.len = len,
.buff = data
};
return tdd_sensor_i2c_xfer(dev->port, &rd_msg);
}
/**
* @brief write command to bh1750
*
* @param[in] dev: device resource
* @param[in] cmd: control command
*
* @return none
*/
STATIC OPERATE_RET __bh1750_write_cmd2(IN CONST SR_RSRC_T *dev, IN CONST BH1750_CMD_E cmd)
{
UCHAR_T cmd_bytes[2];
cmd_bytes[0] = (UCHAR_T)(cmd >> 8);
cmd_bytes[1] = (UCHAR_T)(cmd & 0x00FF);
SR_I2C_MSG_T wr_msg = {
.flags = SR_I2C_FLAG_WR,
.addr = dev->info[BH1750_RSRC_INDEX_ADDR],
.len = 2,
.buff = cmd_bytes
};
return tdd_sensor_i2c_xfer(dev->port, &wr_msg);
}
STATIC OPERATE_RET __bh1750_write_cmd(IN CONST SR_RSRC_T *dev, IN CONST BH1750_CMD_E cmd)
{
UCHAR_T cmd_bytes;
cmd_bytes = (UCHAR_T)(cmd & 0xFF);
SR_I2C_MSG_T wr_msg = {
.flags = SR_I2C_FLAG_WR,
.addr = dev->info[BH1750_RSRC_INDEX_ADDR],
.len = 1,
.buff = &cmd_bytes
};
// TAL_PR_ERR("[BH1750] addr=0x%02x, cmd=0x%02x",dev->info[BH1750_RSRC_INDEX_ADDR], cmd_bytes);
return tdd_sensor_i2c_xfer(dev->port, &wr_msg);
}
/**
* @brief write command and data to bh1750
*
* @param[in] dev: device resource
* @param[in] cmd: control command
* @param[in] data: data to be written
*
* @return none
*/
STATIC VOID_T __bh1750_write_2bytes_data(IN CONST SR_RSRC_T *dev, IN CONST BH1750_CMD_E cmd, IN CONST USHORT_T data)
{
UCHAR_T buf[5];
buf[0] = (UCHAR_T)(cmd >> 8);
buf[1] = (UCHAR_T)(cmd & 0x00FF);
buf[2] = (UCHAR_T)(data >> 8);
buf[3] = (UCHAR_T)(data & 0x00FF);
buf[4] = __bh1750_get_crc8(buf+2, 2);
SR_I2C_MSG_T wr_msg = {
.flags = SR_I2C_FLAG_WR,
.addr = dev->info[BH1750_RSRC_INDEX_ADDR],
.len = 5,
.buff = buf
};
tdd_sensor_i2c_xfer(dev->port, &wr_msg);
}
/**
* @brief start periodic measurement
*
* @param[in] dev: device resource
*
* @return none
*/
STATIC VOID_T __bh1750_start_periodic_measurement(IN CONST SR_RSRC_T *dev)
{
switch (dev->info[BH1750_RSRC_INDEX_PREC]) {
default:
case SR_LT_PREC_HIGH:
switch (dev->info[BH1750_RSRC_INDEX_FREQ]) {
case SR_LT_FREQ_ONE:
__bh1750_write_cmd(dev, BH1750_CMD_ONE_H_RES_MODE);
break;
case SR_LT_FREQ_CON:
__bh1750_write_cmd(dev, BH1750_CMD_CON_H_RES_MODE);
break;
}
break;
case SR_LT_PREC_MEDIUM:
switch (dev->info[BH1750_RSRC_INDEX_FREQ]) {
case SR_LT_FREQ_ONE:
__bh1750_write_cmd(dev, BH1750_CMD_ONE_H_RES_MODE);
break;
case SR_LT_FREQ_CON:
__bh1750_write_cmd(dev, BH1750_CMD_CON_H_RES_MODE);
break;
}
break;
case SR_LT_PREC_LOW:
switch (dev->info[BH1750_RSRC_INDEX_FREQ]) {
case SR_LT_FREQ_ONE:
__bh1750_write_cmd(dev, BH1750_CMD_ONE_L_RES_MODE);
break;
case SR_LT_FREQ_CON:
__bh1750_write_cmd(dev, BH1750_CMD_CON_L_RES_MODE);
break;
}
break;
}
}
/**
* @brief stop periodic measurement
*
* @param[in] dev: device resource
*
* @return none
*/
STATIC VOID_T __bh1750_stop_periodic_measurement(IN CONST SR_RSRC_T *dev)
{
__bh1750_write_cmd(dev, BH1750_CMD_ONE_L_RES_MODE);
}
/**
* @brief set precision
*
* @param[inout] dev: device resource
* @param[in] prec: precision level
*
* @return OPRT_OK on success, others on error
*/
STATIC OPERATE_RET __bh1750_set_precision(INOUT SR_RSRC_T *dev, IN CONST SR_LT_PREC_E *prec)
{
if ((prec == NULL) || (*prec >= SR_LT_PREC_INVALID)) {
return OPRT_INVALID_PARM;
}
dev->info[BH1750_RSRC_INDEX_PREC] = *prec;
__bh1750_start_periodic_measurement(dev);
return OPRT_OK;
}
/**
* @brief set frequency
*
* @param[inout] dev: device resource
* @param[in] freq: frequency
*
* @return OPRT_OK on success, others on error
*/
STATIC OPERATE_RET __bh1750_set_frequency(INOUT SR_RSRC_T *dev, IN CONST SR_LT_PREC_E *freq)
{
if ((freq == NULL) || (*freq >= SR_LT_FREQ_INVALID)) {
return OPRT_INVALID_PARM;
}
dev->info[BH1750_RSRC_INDEX_PREC] = *freq;
__bh1750_start_periodic_measurement(dev);
return OPRT_OK;
}
/**
* @brief calculate light
*
* @param[in] light: light raw data from sensor
* @param[out] light_val: light value in °C
*
* @return none
*/
STATIC VOID_T __bh1750_calc_light(IN CONST USHORT_T light, OUT SR_VAL_U *light_val,IN USHORT_T resl)
{
#if (SR_CONFIG_NO_FPU == 1)
light_val->sr_int = light * resl / 2;
TAL_PR_ERR("light_val->sr_int=%d",light_val->sr_int);
// light_val->sr_int = light * 175 / 65535 - 45;
#else
// light_val->sr_float = light * 175.0f / 65535.0f - 45.0f;
light_val->sr_float = light * resl / 2.0F;
TAL_PR_ERR("light_val->sr_float=%0.1f",light_val->sr_float);
#endif
}
/**
* @brief read light and humidity from bh1750
*
* @param[in] dev: device resource
* @param[out] light: light value
*
* @return OPRT_OK on success, others on error
*/
STATIC OPERATE_RET __bh1750_read_light(IN CONST SR_RSRC_T *dev, OUT USHORT_T *light)
{
UCHAR_T buf[2] = {0};
OPERATE_RET ret = OPRT_OK;
TAL_PR_ERR("[BH1750] __bh1750_read_light");
// reset
__bh1750_write_cmd(dev, BH1750_CMD_SOFT_RESET);
// set mode
// __bh1750_write_cmd(dev, dev->info[BH1750_RSRC_INDEX_MODE]);
// __bh1750_start_periodic_measurement(dev);
__bh1750_write_cmd(dev, BH1750_CMD_ONE_H_RES_MODE);
// delay -- wait value return
__bh1750_delay_ms(180);
ret = __bh1750_read_data(dev, 2, buf);
if(ret != OPRT_OK)
return ret;
*light = ((USHORT_T)buf[0] << 8) | buf[1];
TAL_PR_ERR("[BH1750] buf = %0x %0x light= %d",buf[0],buf[1],*light);
return OPRT_OK;
}
/**
* @brief soft reset
*
* @param[in] dev: device resource
*
* @return OPRT_OK on success, others on error
*/
STATIC OPERATE_RET __bh1750_soft_reset(IN CONST SR_RSRC_T *dev)
{
__bh1750_write_cmd(dev, BH1750_CMD_SOFT_RESET);
__bh1750_delay_ms(50);
return OPRT_OK;
}
// /**
// * @brief read serial number
// *
// * @param[in] dev: device resource
// * @param[out] serial_nbr: serial number
// *
// * @return OPRT_OK on success, others on error
// */
// STATIC OPERATE_RET __bh1750_read_serial_number(IN CONST SR_RSRC_T *dev, OUT SR_LT_SERIAL_NBR_T *serial_nbr)
// {
// UCHAR_T buf[6] = {0};
// OPERATE_RET ret = OPRT_OK;
// __bh1750_write_cmd(dev, BH1750_CMD_READ_SERIALNBR);
// __bh1750_delay_ms(20);
// ret = __bh1750_read_data(dev, 6, buf);
// if(ret != OPRT_OK)
// return ret;
// if ((CRC_ERR == __bh1750_check_crc8(buf, 2, buf[2])) ||\
// (CRC_ERR == __bh1750_check_crc8(buf+3, 2, buf[5]))) {
// TAL_PR_ERR("[BH1750] The received serial number can't pass the CRC8 check.");
// return OPRT_CRC32_FAILED;
// }
// serial_nbr->val = ((UINT_T)buf[0] << 24) | ((UINT_T)buf[1] << 16) |\
// ((UINT_T)buf[3] << 8) | ((UINT_T)buf[4]);
// return OPRT_OK;
// }
/**
* @brief open bh1750 device
*
* @param[inout] dev: device resource
*
* @return OPRT_OK on success, others on error
*/
STATIC OPERATE_RET __tdd_sensor_bh1750_open(INOUT SR_RSRC_T *dev)
{
__bh1750_write_cmd(dev, BH1750_CMD_POWER_ON); // power on
// __bh1750_start_periodic_measurement(dev);
dev->info[BH1750_RSRC_INDEX_STAT] = BH1750_OPEN;
return OPRT_OK;
}
/**
* @brief close bh1750 device
*
* @param[inout] dev: device resource
*
* @return OPRT_OK on success, others on error
*/
STATIC OPERATE_RET __tdd_sensor_bh1750_close(INOUT SR_RSRC_T *dev)
{
// __bh1750_stop_periodic_measurement(dev);
__bh1750_write_cmd(dev, BH1750_CMD_POWER_DOWN); // power down
dev->info[BH1750_RSRC_INDEX_STAT] = BH1750_CLOSE;
return OPRT_OK;
}
/**
* @brief control bh1750 device
*
* @param[inout] dev: device resource
* @param[in] cmd: control command
* @param[inout] param: command parameter, data type depends on the specified command
*
* @return OPRT_OK on success, others on error
*/
STATIC OPERATE_RET __tdd_sensor_bh1750_control(INOUT SR_RSRC_T* dev, IN UCHAR_T cmd, INOUT VOID_T *param)
{
OPERATE_RET op_ret = OPRT_OK;
if ((BH1750_OPEN == dev->info[BH1750_RSRC_INDEX_STAT]) &&\
(cmd == SR_LT_CMD_SET_PREC ||\
cmd == SR_LT_CMD_SET_FREQ ||\
cmd == SR_LT_CMD_SOFT_RESET )) {
TAL_PR_ERR("[BH1750] Command <%d> is only supported when acquisition is closed.");
return OPRT_COM_ERROR;
}
switch (cmd) {
case SR_LT_CMD_SOFT_RESET:
op_ret = __bh1750_soft_reset(dev);
break;
// case SR_LT_CMD_GET_SERIAL_NBR:
// op_ret = __bh1750_read_serial_number(dev, (SR_LT_SERIAL_NBR_T *)param);
// break;
case SR_LT_CMD_SET_PREC:
op_ret = __bh1750_set_precision(dev, (SR_LT_PREC_E *)param);
break;
case SR_LT_CMD_SET_FREQ:
op_ret = __bh1750_set_frequency(dev, (SR_LT_FREQ_E *)param);
break;
// case SR_LT_CMD_SET_ALT_LIMIT:
// op_ret = __bh1750_set_alert_limit(dev, (SR_LT_LIMIT_T *)param);
// break;
// case SR_LT_CMD_GET_ALT_LIMIT:
// op_ret = __bh1750_get_alert_limit(dev, (SR_LT_LIMIT_T *)param);
// break;
// case SR_LT_CMD_ENABLE_ALT_PIN:
// op_ret = __bh1750_enable_alert(dev, (SR_LT_ALT_CFG_T *)param);
// break;
// case SR_LT_CMD_DISABLE_ALT_PIN:
// op_ret = __bh1750_disable_alert(dev, (TUYA_GPIO_NUM_E *)param);
// break;
// case SR_LT_CMD_GET_STATUS:
// op_ret = __bh1750_read_status(dev, (SR_LT_STATUS_U *)param);
// break;
// case SR_LT_CMD_CLR_STATUS:
// op_ret = __bh1750_clear_status(dev);
// break;
// case SR_LT_CMD_ENABLE_HEATER:
// op_ret = __bh1750_set_heater(dev, TRUE);
// break;
// case SR_LT_CMD_DISABLE_HEATER:
// op_ret = __bh1750_set_heater(dev, FALSE);
// break;
default:
op_ret = OPRT_INVALID_PARM;
TAL_PR_ERR("[BH1750] Command <%d> is invalid.", cmd);
break;
}
return op_ret;
}
/**
* @brief read data from bh1750 device
*
* @param[in] dev: device
* @param[out] ele_data: element data
* @param[in] ele_num: number of elements
*
* @return OPRT_OK on success, others on error
*/
STATIC OPERATE_RET __tdd_sensor_bh1750_read(IN SR_RSRC_T* dev, OUT SR_ELE_DATA_T *ele_data, IN UCHAR_T ele_num)
{
USHORT_T light = 0;
TAL_PR_ERR("[BH1750] __tdd_sensor_bh1750_read");
OPERATE_RET op_ret = __bh1750_read_light(dev, &light);
if (op_ret != OPRT_OK) {
return op_ret;
}
for (UCHAR_T i = 0; i < ele_num; i++) {
switch (ele_data[i].id) {
case SR_LT_ELE_ID_LIGHT:
TAL_PR_ERR("[BH1750] get value. resl=%d",dev->info[BH1750_RSRC_INDEX_RESL]);
__bh1750_calc_light(light, &ele_data[i].val, (USHORT_T)dev->info[BH1750_RSRC_INDEX_RESL]);
// ele_data[i].val = ele_data[i].val * (SR_VAL_U)(dev->info[BH1750_RSRC_INDEX_RESL]);
break;
default:
TAL_PR_ERR("[BH1750] Element ID: %d is invalid.", ele_data[i].id);
break;
}
}
return OPRT_OK;
}
/**
* @brief register bh1750 device
*
* @param[in] name: device name
* @param[in] i2c_cfg: i2c configuration
* @param[in] meas_cfg: measurement configuration
*
* @return OPRT_OK on success, others on error
*/
OPERATE_RET tdd_sensor_bh1750_register(IN CHAR_T *name, IN SR_LT_I2C_CFG_T i2c_cfg, IN SR_LT_MEAS_CFG_T meas_cfg)
{
// check param
if (i2c_cfg.gpio.scl == i2c_cfg.gpio.sda) {
return OPRT_INVALID_PARM;
}
// I2C init
tdd_sensor_i2c_init(i2c_cfg.port, i2c_cfg.gpio);
// save resourse information
SR_RSRC_T resource = {0};
resource.port = i2c_cfg.port;
resource.handle = NULL;
resource.info[BH1750_RSRC_INDEX_STAT] = BH1750_CLOSE;
resource.info[BH1750_RSRC_INDEX_ADDR] = i2c_cfg.addr;
resource.info[BH1750_RSRC_INDEX_PREC] = meas_cfg.prec;
resource.info[BH1750_RSRC_INDEX_FREQ] = meas_cfg.freq;
switch (meas_cfg.prec) {
case SR_LT_PREC_HIGH:
resource.info[BH1750_RSRC_INDEX_RESL] = 2;//1
break;
case SR_LT_PREC_MEDIUM:
resource.info[BH1750_RSRC_INDEX_RESL] = 1;//0.5
break;
case SR_LT_PREC_LOW:
resource.info[BH1750_RSRC_INDEX_RESL] = 82;//41
break;
default:
resource.info[BH1750_RSRC_INDEX_RESL] = 1;//2
break;
}
// define driver interfaces
STATIC SR_INTFS_T s_intfs;
s_intfs.open = __tdd_sensor_bh1750_open;
s_intfs.close = __tdd_sensor_bh1750_close;
s_intfs.control = __tdd_sensor_bh1750_control;
s_intfs.read_ele = __tdd_sensor_bh1750_read;
// register the device
OPERATE_RET op_ret = tdl_sensor_register(name, &s_intfs, SR_LT_ELE_NUM, sg_ele_val_tp, &resource);
if (OPRT_OK != op_ret) {
return op_ret;
}
return OPRT_OK;
}
app_light.c
c
/**
* @file app_light.c
* @brief RH-T sensor application demo
* @version 0.1
* @date 2022-09-07
*/
#include "app_light.h"
#include "tdl_sensor_hub.h"
#include "tdd_sensor_light.h"
#include "tkl_memory.h"
#include "tal_sw_timer.h"
#include "tal_log.h"
#include "tuya_iot_com_api.h"
#include "tuya_wifi_status.h"
#include "tuya_ws_db.h"
/***********************************************************
************************macro define************************
***********************************************************/
/**
* @brief alert code
*/
#define ALT_LOWER 0
#define ALT_UPPER 1
#define ALT_CANCEL 2
/***********************************************************
***********************typedef define***********************
***********************************************************/
/**
* @brief DP data typedef
*/
typedef struct {
TY_OBJ_DP_VALUE_U light;
TY_OBJ_DP_VALUE_U light_alert;
} LT_DP_DATA_T;
/**
* @brief flag typedef
*/
typedef struct {
UCHAR_T turn_on : 1;
UCHAR_T light_change : 1;
UCHAR_T alert : 1;
UCHAR_T reserved : 4;
} LT_FLAG_T;
/***********************************************************
********************function declaration********************
***********************************************************/
/***********************************************************
***********************variable define**********************
***********************************************************/
/**
* @brief bh1750 process
*/
STATIC SENSOR_HANDLE_T sg_bh1750_handle = NULL;
STATIC SR_LT_STATUS_U sg_bh1750_status;
STATIC SR_LT_LIMIT_T sg_bh1750_alert_limit;
STATIC LT_FLAG_T sg_bh1750_flag;
STATIC TIMER_ID sg_bh1750_report_timer;
/**
* @brief DP process
*/
STATIC LT_DP_DATA_T sg_lt_dp_data;
/***********************************************************
***********************function define**********************
***********************************************************/
/**
* @brief report one dp data
*
* @param[in] dp_id: DP ID
* @param[in] dp_type: DP type
* @param[in] dp_value: DP value
*
* @return none
*/
STATIC VOID_T __repo_one_dp_data(CONST UCHAR_T dp_id, CONST UCHAR_T dp_type, CONST TY_OBJ_DP_VALUE_U dp_value)
{
GW_WIFI_NW_STAT_E wifi_stat = STAT_LOW_POWER;
get_wf_gw_nw_status(&wifi_stat);
if (wifi_stat <= STAT_AP_STA_DISC || wifi_stat == STAT_STA_DISC) {
return;
}
TY_OBJ_DP_S dp_repo;
dp_repo.dpid = dp_id;
dp_repo.type = dp_type;
dp_repo.time_stamp = 0;
switch (dp_type) {
case PROP_BOOL:
dp_repo.value.dp_bool = dp_value.dp_bool;
break;
case PROP_VALUE:
dp_repo.value.dp_value = dp_value.dp_value;
break;
case PROP_ENUM:
dp_repo.value.dp_enum = dp_value.dp_enum;
break;
case PROP_STR:
dp_repo.value.dp_str = dp_value.dp_str;
break;
case PROP_BITMAP:
dp_repo.value.dp_bitmap = dp_value.dp_bitmap;
break;
default:
break;
}
TAL_PR_INFO("repo_one_dp_data ID:%d", dp_repo.dpid);
OPERATE_RET op_ret = dev_report_dp_json_async(NULL, &dp_repo, 1);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("__repo_one_dp_data -- dev_report_dp_json_async, error code: %d.", op_ret);
}
}
/**
* @brief data ready inform
*
* @param[in] name: device name
* @param[in] ele_num: number of elements
* @param[in] ele_data: element data
*
* @return none
*/
STATIC VOID_T __bh1750_inform_cb(CHAR_T* name, UCHAR_T ele_num, SR_ELE_BUFF_T *ele_data)
{
INT_T light;
for (UCHAR_T i = 0; i < ele_num; i++) {
if (ele_data[i].id == SR_LT_ELE_ID_LIGHT) {
light = (INT_T)(ele_data[i].val[0].sr_float * LIGHT_SCALE);
TAL_PR_INFO("Light: %d sg_lt_dp_data.light.dp_value: %d", light, sg_lt_dp_data.light.dp_value);
if (light != sg_lt_dp_data.light.dp_value) {
if ((light > (sg_lt_dp_data.light.dp_value + APP_LIGHT_REPORT_INTERVAL)) || \
((light + APP_LIGHT_REPORT_INTERVAL) < sg_lt_dp_data.light.dp_value)) {
sg_lt_dp_data.light.dp_value = light;
sg_bh1750_flag.light_change = TRUE;
TAL_PR_INFO("Light change. Enable report");
}
}
}
}
}
/**
* @brief bh1750 alert callback
*
* @param none
*
* @return none
*/
STATIC VOID_T __bh1750_alert_cb(VOID_T *args)
{
sg_bh1750_flag.alert = TRUE;
}
/**
* @brief bh1750 register
*
* @param none
*
* @return OPRT_OK on success, others on error
*/
STATIC OPERATE_RET __bh1750_register(VOID_T)
{
OPERATE_RET op_ret;
TAL_PR_DEBUG("Youkai __bh1750_register");
SR_I2C_GPIO_T i2c_gpio = {
.scl = BH1750_SCL_PIN,
.sda = BH1750_SDA_PIN
};
SR_LT_I2C_CFG_T bh1750_i2c_cfg = {
.port = 0,
.addr = SR_I2C_ADDR_BH1750_A, // GND
.gpio = i2c_gpio
};
SR_LT_MEAS_CFG_T bh1750_meas_cfg = {
.prec = SR_LT_PREC_HIGH,
.freq = SR_LT_FREQ_CON,
// .mode = BH1750_CMD_CON_H_RES_MODE
};
op_ret = tdd_sensor_bh1750_register("BH1750", bh1750_i2c_cfg, bh1750_meas_cfg);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("tdd_sensor_bh1750_register, error code: %d.", op_ret);
return op_ret;
}
op_ret = tdl_sensor_dev_find("BH1750", &sg_bh1750_handle);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("tdl_sensor_dev_find, error code: %d.", op_ret);
return op_ret;
}
return OPRT_OK;
}
/**
* @brief clear status
*
* @param none
*
* @return OPRT_OK on success, others on error
*/
STATIC OPERATE_RET __bh1750_clear_status(VOID_T)
{
OPERATE_RET op_ret;
op_ret = tdl_sensor_dev_config(sg_bh1750_handle, SR_LT_CMD_CLR_STATUS, NULL);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("SR_LT_CMD_CLR_STATUS, error code: %d.", op_ret);
return op_ret;
}
op_ret = tdl_sensor_dev_config(sg_bh1750_handle, SR_LT_CMD_GET_STATUS, &sg_bh1750_status);
if (op_ret != OPRT_OK) {
TAL_PR_ERR("SR_LT_CMD_GET_STATUS, error code: %d.", op_ret);
return op_ret;
}
TAL_PR_DEBUG("Status <alert pending>: %d.", sg_bh1750_status.bit.alert_pending);
TAL_PR_DEBUG("Status <light alert>: %d.", sg_bh1750_status.bit.light_alert);
return OPRT_OK;
}
/**
* @brief bh1750 set alert
*
* @param none
*
* @return OPRT_OK on success, others on error
*/
STATIC OPERATE_RET __bh1750_set_alert(VOID_T)
{
OPERATE_RET op_ret;
// set alert limit
sg_bh1750_alert_limit.light_high_set.sr_float = 125.0f;
sg_bh1750_alert_limit.light_high_clear.sr_float = sg_bh1750_alert_limit.light_high_set.sr_float - 5.0f;
sg_bh1750_alert_limit.light_low_set.sr_float = -40.0f;
sg_bh1750_alert_limit.light_low_clear.sr_float = sg_bh1750_alert_limit.light_low_set.sr_float + 5.0f;
op_ret = tdl_sensor_dev_config(sg_bh1750_handle, SR_LT_CMD_SET_ALT_LIMIT, &sg_bh1750_alert_limit);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("SR_LT_CMD_SET_ALT_LIMIT, error code: %d.", op_ret);
return op_ret;
}
// clear alert status
op_ret = __bh1750_clear_status();
if (op_ret != OPRT_OK) {
return op_ret;
}
// enable alert function
SR_LT_ALT_CFG_T bh1750_alert_cfg;
bh1750_alert_cfg.pin = BH1750_ALT_PIN;
bh1750_alert_cfg.irq.mode = TUYA_GPIO_IRQ_RISE;
bh1750_alert_cfg.irq.cb = __bh1750_alert_cb;
bh1750_alert_cfg.irq.arg = NULL;
op_ret = tdl_sensor_dev_config(sg_bh1750_handle, SR_LT_CMD_ENABLE_ALT_PIN, &bh1750_alert_cfg);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("SR_LT_CMD_ENABLE_ALT_PIN, error code: %d.", op_ret);
return op_ret;
}
return OPRT_OK;
}
/**
* @brief bh1750 open
*
* @param none
*
* @return OPRT_OK on success, others on error
*/
STATIC OPERATE_RET __bh1750_open(VOID_T)
{
TAL_PR_DEBUG("Youkai __bh1750_open");
if (sg_bh1750_flag.turn_on) {
TAL_PR_ERR("The device is already turned on.");
return OPRT_COM_ERROR;
}
OPERATE_RET op_ret;
SR_DEV_CFG_T bh1750_cfg;
tkl_system_memset(&bh1750_cfg, 0, SIZEOF(SR_DEV_CFG_T));
bh1750_cfg.mode.trig_mode = SR_MODE_POLL_SOFT_TM;
bh1750_cfg.mode.poll_intv_ms = APP_LIGHT_READ_CYCLE;
bh1750_cfg.inform_cb.ele = __bh1750_inform_cb;
bh1750_cfg.fifo_size = 1;
bh1750_cfg.ele_sub = NULL;
op_ret = tdl_sensor_dev_open(sg_bh1750_handle, &bh1750_cfg);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("tdl_sensor_dev_open, error code: %d.", op_ret);
return op_ret;
}
sg_bh1750_flag.turn_on = TRUE;
TAL_PR_INFO("Open device successfully.");
return OPRT_OK;
}
/**
* @brief bh1750 close
*
* @param none
*
* @return OPRT_OK on success, others on error
*/
STATIC OPERATE_RET __bh1750_close(VOID_T)
{
if (!sg_bh1750_flag.turn_on) {
TAL_PR_ERR("The device is already turned off.");
return OPRT_COM_ERROR;
}
OPERATE_RET op_ret = tdl_sensor_dev_close(sg_bh1750_handle);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("tdl_sensor_dev_close, error code: %d.", op_ret);
return op_ret;
}
sg_bh1750_flag.turn_on = FALSE;
TAL_PR_INFO("Close device successfully.");
return OPRT_OK;
}
/**
* @brief get alert code
*
* @param[in] cur_val: current value
* @param[in] high_lim: high set limit
* @param[in] low_lim: low set limit
*
* @return alert code
*/
STATIC UINT_T __get_alert_code(CONST FLOAT_T cur_val, CONST FLOAT_T high_lim, CONST FLOAT_T low_lim)
{
UINT_T code;
FLOAT_T diff_abs_h, diff_abs_l;
if (cur_val >= high_lim) {
diff_abs_h = cur_val - high_lim;
} else {
diff_abs_h = high_lim - cur_val;
}
if (cur_val >= low_lim) {
diff_abs_l = cur_val - low_lim;
} else {
diff_abs_l = low_lim - cur_val;
}
if (diff_abs_h < diff_abs_l) {
code = ALT_UPPER;
} else {
code = ALT_LOWER;
}
return code;
}
/**
* @brief bh1750 alert occur handler
*
* @param none
*
* @return none
*/
STATIC VOID_T __bh1750_alert_occur_handler(VOID_T)
{
OPERATE_RET op_ret = tdl_sensor_dev_config(sg_bh1750_handle, SR_LT_CMD_GET_STATUS, &sg_bh1750_status);
if (op_ret != OPRT_OK) {
TAL_PR_ERR("SR_LT_CMD_GET_STATUS, error code: %d.", op_ret);
return;
}
FLOAT_T cur_val;
if (sg_bh1750_status.bit.light_alert) {
if (ALT_CANCEL == sg_lt_dp_data.light_alert.dp_enum) {
TAL_PR_INFO("Light alert occurred.");
cur_val = sg_lt_dp_data.light.dp_value / (10.0f * LIGHT_SCALE);
sg_lt_dp_data.light_alert.dp_enum = __get_alert_code(cur_val,\
sg_bh1750_alert_limit.light_high_set.sr_float,\
sg_bh1750_alert_limit.light_low_set.sr_float);
__repo_one_dp_data(DP_ID_LIGHT_ALT, PROP_ENUM, sg_lt_dp_data.light_alert);
}
} else {
if (sg_lt_dp_data.light_alert.dp_enum != ALT_CANCEL) {
TAL_PR_INFO("Light alert canceled.");
sg_lt_dp_data.light_alert.dp_enum = ALT_CANCEL;
__repo_one_dp_data(DP_ID_LIGHT_ALT, PROP_ENUM, sg_lt_dp_data.light_alert);
}
}
if (!sg_bh1750_status.bit.light_alert) {
sg_bh1750_flag.alert = FALSE;
}
}
/**
* @brief bh1750 report timer callback
*
* @param[in] timer_id: timer ID
* @param[in] arg: argument
*
* @return none
*/
STATIC VOID_T __bh1750_report_timer_cb(TIMER_ID timer_id, VOID_T *arg)
{
// if (sg_bh1750_flag.alert) {
// __bh1750_alert_occur_handler();
// }
if (sg_bh1750_flag.light_change) {
TAL_PR_INFO("light change report.");
sg_bh1750_flag.light_change = FALSE;
__repo_one_dp_data(DP_ID_LIGHT, PROP_VALUE, sg_lt_dp_data.light);
}
}
/**
* @brief light main
*
* @param none
*
* @return OPRT_OK on success, others on error
*/
OPERATE_RET app_light_init(VOID_T)
{
OPERATE_RET op_ret;
BOOL_T is_exist = FALSE;
tkl_system_memset(&sg_bh1750_flag, 0, SIZEOF(LT_FLAG_T));
TAL_PR_ERR("app_light_init");
sg_lt_dp_data.light.dp_value = 0;
sg_lt_dp_data.light_alert.dp_enum = ALT_CANCEL;
sg_bh1750_status.word = 0;
op_ret = __bh1750_register();
if (OPRT_OK != op_ret) {
return op_ret;
}
// op_ret = __bh1750_set_alert();
// if (OPRT_OK != op_ret) {
// return op_ret;
// }
op_ret = __bh1750_open();
if (OPRT_OK != op_ret) {
return op_ret;
}
op_ret = tal_sw_timer_create(__bh1750_report_timer_cb, NULL, &sg_bh1750_report_timer);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("tal_sw_timer_create -- sg_bh1750_report_timer, error code: %d.", op_ret);
return op_ret;
} else {
tal_sw_timer_start(sg_bh1750_report_timer, APP_LIGHT_REPORT_CYCLE, TAL_TIMER_CYCLE);
}
//read alert limit data
// wd_common_exist(KEY_NAME, &is_exist);
// if (TRUE == is_exist) {
// BYTE_T *read_buf = NULL;
// UINT_T read_len;
// op_ret = wd_common_read(KEY_NAME, &read_buf, &read_len);
// if (OPRT_OK != op_ret) {
// TAL_PR_ERR("wd_common_read %s error code: %d,", KEY_NAME, op_ret);
// return op_ret;
// }
// SR_LT_LIMIT_T *data = (SR_LT_LIMIT_T *)read_buf;
// sg_bh1750_alert_limit.light_high_set.sr_float = data->light_high_set.sr_float;
// sg_bh1750_alert_limit.light_low_set.sr_float = data->light_low_set.sr_float;
// if (NULL != read_buf) {
// wd_common_free_data(read_buf);
// read_buf = NULL;
// }
// } else {
// //set default value
// sg_bh1750_alert_limit.light_high_set.sr_float = 125.0f;
// sg_bh1750_alert_limit.light_low_set.sr_float = -40.0f;
// op_ret = wd_common_write(KEY_NAME, (BYTE_T *)&sg_bh1750_alert_limit, sizeof(sg_bh1750_alert_limit));
// if (OPRT_OK != op_ret) {
// TAL_PR_ERR("wd_common_write %s error code: %d,", KEY_NAME, op_ret);
// return op_ret;
// }
// }
return OPRT_OK;
}
/**
* @brief bh1750 set alert by cloud
*
* @param none
*
* @return OPRT_OK on success, others on error
*/
STATIC OPERATE_RET __bh1750_set_alert_by_cloud(VOID_T)
{
OPERATE_RET op_ret;
sg_bh1750_alert_limit.light_high_clear.sr_float = sg_bh1750_alert_limit.light_high_set.sr_float;
sg_bh1750_alert_limit.light_low_clear.sr_float = sg_bh1750_alert_limit.light_low_set.sr_float;
op_ret = wd_common_write(KEY_NAME, (BYTE_T *)&sg_bh1750_alert_limit, sizeof(sg_bh1750_alert_limit));
if (OPRT_OK != op_ret) {
TAL_PR_ERR("wd_common_write %s error code: %d,", KEY_NAME, op_ret);
return op_ret;
}
op_ret = tdl_sensor_dev_config(sg_bh1750_handle, SR_LT_CMD_SET_ALT_LIMIT, &sg_bh1750_alert_limit);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("SR_LT_CMD_SET_ALT_LIMIT, error code: %d.", op_ret);
return op_ret;
}
op_ret = __bh1750_clear_status();
if (OPRT_OK != op_ret) {
return op_ret;
}
return OPRT_OK;
}
/**
* @brief switch device
*
* @param[in] enabled: TRUE on enabled, FALSE on disabled
*
* @return OPRT_OK on success, others on error
*/
STATIC OPERATE_RET __switch_dev_by_cloud(CONST BOOL_T enabled)
{
OPERATE_RET op_ret;
if (enabled) {
op_ret = __bh1750_open();
} else {
op_ret = __bh1750_close();
}
return op_ret;
}
/**
* @brief DP processing
*
* @param[in] dp: dp data
*
* @return none
*/
VOID_T app_light_dp_proc(CONST TY_OBJ_DP_S *dp)
{
OPERATE_RET op_ret;
switch (dp->dpid) {
case DP_ID_LIGHT_MAX:
sg_bh1750_alert_limit.light_high_set.sr_float = dp->value.dp_value / (10.0f * LIGHT_SCALE);
TAL_PR_INFO("[APP] Set the maximum lighterature to %.1f.", sg_bh1750_alert_limit.light_high_set.sr_float);
op_ret = __bh1750_set_alert_by_cloud();
break;
case DP_ID_LIGHT_MIN:
sg_bh1750_alert_limit.light_low_set.sr_float = dp->value.dp_value / (10.0f * LIGHT_SCALE);
TAL_PR_INFO("[APP] Set the minimum lighterature to %.1f.", sg_bh1750_alert_limit.light_low_set.sr_float);
op_ret = __bh1750_set_alert_by_cloud();
break;
case DP_ID_SWITCH:
TAL_PR_INFO("[APP] Switch device: %d.", dp->value.dp_bool);
op_ret = __switch_dev_by_cloud(dp->value.dp_bool);
break;
default:
op_ret = OPRT_INVALID_PARM;
break;
}
if (OPRT_OK == op_ret) {
op_ret = dev_report_dp_json_async(NULL, dp, 1);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("app_light_dp_proc -- dev_report_dp_json_async, error code: %d.", op_ret);
}
}
TAL_PR_INFO("app_light_dp_proc: %d", op_ret);
}
/**
* @brief report all DP data
*
* @param none
*
* @return none
*/
VOID_T app_light_repo_all_dp(VOID_T)
{
GW_WIFI_NW_STAT_E wifi_stat = STAT_LOW_POWER;
get_wf_gw_nw_status(&wifi_stat);
if (wifi_stat <= STAT_AP_STA_DISC || wifi_stat == STAT_STA_DISC) {
return;
}
TY_OBJ_DP_S *dp_arr = (TY_OBJ_DP_S *)tkl_system_malloc(MAX_DP_NUM*SIZEOF(TY_OBJ_DP_S));
if (NULL == dp_arr) {
TAL_PR_ERR("dp_arr malloc failed.");
return;
}
tkl_system_memset(dp_arr, 0, MAX_DP_NUM*SIZEOF(TY_OBJ_DP_S));
dp_arr[0].dpid = DP_ID_LIGHT;
dp_arr[0].type = PROP_VALUE;
dp_arr[0].time_stamp = 0;
dp_arr[0].value.dp_value = sg_lt_dp_data.light.dp_value;
dp_arr[2].dpid = DP_ID_LIGHT_MAX;
dp_arr[2].type = PROP_VALUE;
dp_arr[2].time_stamp = 0;
dp_arr[2].value.dp_value = (INT_T)(sg_bh1750_alert_limit.light_high_set.sr_float * (10 * LIGHT_SCALE));
dp_arr[3].dpid = DP_ID_LIGHT_MIN;
dp_arr[3].type = PROP_VALUE;
dp_arr[3].time_stamp = 0;
dp_arr[3].value.dp_value = (INT_T)(sg_bh1750_alert_limit.light_low_set.sr_float * (10 * LIGHT_SCALE));
dp_arr[6].dpid = DP_ID_LIGHT_ALT;
dp_arr[6].type = PROP_ENUM;
dp_arr[6].time_stamp = 0;
dp_arr[6].value.dp_enum = sg_lt_dp_data.light_alert.dp_enum;
dp_arr[8].dpid = DP_ID_SWITCH;
dp_arr[8].type = PROP_BOOL;
dp_arr[8].time_stamp = 0;
dp_arr[8].value.dp_bool = sg_bh1750_flag.turn_on;
OPERATE_RET op_ret = dev_report_dp_json_async(NULL, dp_arr, MAX_DP_NUM);
if (OPRT_OK != op_ret) {
TAL_PR_ERR("app_light_repo_all_dp -- dev_report_dp_json_async, error code: %d.", op_ret);
} else {
TAL_PR_INFO("app_light_repo_all_dp: %d", op_ret);
}
tkl_system_free(dp_arr);
dp_arr = NULL;
}
tuya_app_main.c
c
/**
* @file tuya_app_main.c
* @author www.tuya.com
* @brief tuya_app_main module is used to
* @version 0.1
* @date 2022-10-28
*
* @copyright Copyright (c) tuya.inc 2022
*
*/
#include "tuya_cloud_types.h"
#include "tuya_iot_wifi_api.h"
#include "tuya_ws_db.h"
#include "gw_intf.h"
#include "tal_log.h"
#include "tal_wifi.h"
#include "tal_uart.h"
#include "mf_test.h"
#if defined(ENABLE_LWIP) && (ENABLE_LWIP == 1)
#include "lwip_init.h"
#endif
#include "app_led.h"
#include "app_key.h"
#include "app_light.h"
/***********************************************************
************************macro define************************
***********************************************************/
/* The registration code here does not work, you need to apply for a new one.
* https://developer.tuya.com/cn/docs/iot/lisence-management?id=Kb4qlem97idl0
*/
// #define UUID "f998xxxxxxxx2409"
// #define AUTHKEY "WEHAxxxxxxxxxxxxxxxxxxxxxxxxVVkf"
/* network button, LED pin */
#define KEY_PIN 7
#define LED_PIN 26
/* Compatible with TuyaOS 3.3.x */
#ifndef TUYA_UART_NUM_0
#define TUYA_UART_NUM_0 UART_NUM_0
#endif
/***********************************************************
***********************typedef define***********************
***********************************************************/
/***********************************************************
********************function declaration********************
***********************************************************/
/***********************************************************
***********************variable define**********************
***********************************************************/
/* app thread handle */
STATIC THREAD_HANDLE ty_app_thread = NULL;
/***********************************************************
***********************function define**********************
***********************************************************/
/**
* @brief SOC device upgrade entry
*
* @param[in] fw: firmware info
*
* @return OPRT_OK on success. Others on error, please refer to "tuya_error_code.h".
*/
STATIC OPERATE_RET __soc_dev_rev_upgrade_info_cb(IN CONST FW_UG_S *fw)
{
TAL_PR_DEBUG("SOC Rev Upgrade Info");
TAL_PR_DEBUG("fw->tp:%d", fw->tp);
TAL_PR_DEBUG("fw->fw_url:%s", fw->fw_url);
TAL_PR_DEBUG("fw->fw_hmac:%s", fw->fw_hmac);
TAL_PR_DEBUG("fw->sw_ver:%s", fw->sw_ver);
TAL_PR_DEBUG("fw->file_size:%u", fw->file_size);
return OPRT_OK;
}
/**
* @brief SOC device cloud state change callback
*
* @param[in] status: current status
*
* @return none
*/
STATIC VOID_T __soc_dev_status_changed_cb(IN CONST GW_STATUS_E status)
{
TAL_PR_DEBUG("SOC TUYA-Cloud Status:%d", status);
return;
}
/**
* @brief SOC device DP query entry
*
* @param[in] dp_qry: DP query list
*
* @return none
*/
STATIC VOID_T __soc_dev_dp_query_cb(IN CONST TY_DP_QUERY_S *dp_qry)
{
UINT32_T index = 0;
TAL_PR_DEBUG("SOC Rev DP Query Cmd");
if (dp_qry->cid != NULL) {
TAL_PR_ERR("soc not have cid.%s", dp_qry->cid);
}
if (dp_qry->cnt == 0) {
TAL_PR_DEBUG("soc rev all dp query");
app_light_repo_all_dp();
} else {
TAL_PR_DEBUG("soc rev dp query cnt:%d", dp_qry->cnt);
for (index = 0; index < dp_qry->cnt; index++) {
TAL_PR_DEBUG("rev dp query:%d", dp_qry->dpid[index]);
}
}
return;
}
/**
* @brief SOC device format command data delivery entry
*
* @param[in] dp: obj dp info
*
* @return none
*/
STATIC VOID_T __soc_dev_obj_dp_cmd_cb(IN CONST TY_RECV_OBJ_DP_S *dp)
{
UINT32_T index = 0;
TAL_PR_DEBUG("SOC Rev DP Obj Cmd t1:%d t2:%d CNT:%u", dp->cmd_tp, dp->dtt_tp, dp->dps_cnt);
if (dp->cid != NULL) {
TAL_PR_ERR("soc not have cid.%s", dp->cid);
}
for (index = 0; index < dp->dps_cnt; index++) {
app_light_dp_proc(&(dp->dps[index]));
}
return;
}
/**
* @brief SOC device transparently transmits command data delivery entry
*
* @param[in] dp: raw dp info
*
* @return none
*/
STATIC VOID_T __soc_dev_raw_dp_cmd_cb(IN CONST TY_RECV_RAW_DP_S *dp)
{
TAL_PR_DEBUG("SOC Rev DP Raw Cmd t1:%d t2:%d dpid:%d len:%u", dp->cmd_tp, dp->dtt_tp, dp->dpid, dp->len);
if (dp->cid != NULL) {
TAL_PR_ERR("soc not have cid.%s", dp->cid);
}
return;
}
/**
* @brief SOC device process restart request entry
*
* @param[in] type: gateway reset type
*
* @return none
*/
STATIC VOID_T __soc_dev_restart_req_cb(GW_RESET_TYPE_E type)
{
TAL_PR_DEBUG("SOC Rev Restart Req %d", type);
if (GW_RESET_DATA_FACTORY != type) {
// UserTODO Device process restart
tal_system_reset();
}
return;
}
/**
* @brief SOC external network status change callback
*
* @param[in] stat: curr network status
*
* @return none
*/
STATIC VOID __soc_dev_net_status_cb(IN CONST GW_WIFI_NW_STAT_E stat)
{
TAL_PR_DEBUG("network status:%d", stat);
STATIC BOOL_T proc_flag = FALSE;
if ((FALSE == proc_flag) &&\
(STAT_AP_STA_CONN == stat || STAT_STA_CONN <= stat)) {
app_light_repo_all_dp();
TAL_PR_INFO("WF");
proc_flag = TRUE;
}
if ((TRUE == proc_flag) &&\
(STAT_AP_STA_DISC == stat || STAT_STA_DISC == stat)) {
proc_flag = FALSE;
}
return;
}
/**
* @brief mf uart init
*
* @param[in] baud: Baud rate
* @param[in] bufsz: uart receive buffer size
*
* @return none
*/
VOID mf_uart_init_callback(UINT_T baud, UINT_T bufsz)
{
TAL_UART_CFG_T cfg;
memset(&cfg, 0, sizeof(TAL_UART_CFG_T));
cfg.base_cfg.baudrate = baud;
cfg.base_cfg.databits = TUYA_UART_DATA_LEN_8BIT;
cfg.base_cfg.parity = TUYA_UART_PARITY_TYPE_NONE;
cfg.base_cfg.stopbits = TUYA_UART_STOP_LEN_1BIT;
cfg.rx_buffer_size = bufsz;
tal_uart_init(TUYA_UART_NUM_0, &cfg);
return;
}
/**
* @brief mf uart free
*
* @param[in] none
*
* @return none
*/
VOID mf_uart_free_callback(VOID)
{
tal_uart_deinit(TUYA_UART_NUM_0);
return;
}
/**
* @brief mf uart send function
*
* @param[in] data: send data
* @param[in] len: send data length
*
* @return none
*/
VOID mf_uart_send_callback(IN BYTE_T *data, IN CONST UINT_T len)
{
tal_uart_write(TUYA_UART_NUM_0, data, len);
return;
}
/**
* @brief mf uart receive function
*
* @param[in] buf: receive buffer
* @param[in] len: receive buffer max length
*
* @return receive data length
*/
UINT_T mf_uart_recv_callback(OUT BYTE_T *buf, IN CONST UINT_T len)
{
return tal_uart_read(TUYA_UART_NUM_0, buf, len);
}
/**
* @brief Product test callback function
*
* @param[in] cmd: Command
* @param[in] data: data
* @param[out] ret_data: Resulting data
* @param[out] ret_len: Resulting data length
*
* @return OPRT_OK on success. Others on error, please refer to "tuya_error_code.h".
*/
OPERATE_RET mf_user_product_test_callback(USHORT_T cmd, UCHAR_T *data, UINT_T len, OUT UCHAR_T **ret_data, OUT USHORT_T *ret_len)
{
/* USER todo */
return OPRT_OK;
}
/**
* @brief mf configure write callback functions
*
* @param[in] none
*
* @return none
*/
VOID mf_user_callback(VOID)
{
return ;
}
/**
* @brief Callback function before entering the production test
*
* @param[in] none
*
* @return none
*/
VOID mf_user_enter_mf_callback(VOID)
{
return ;
}
BOOL_T mf_gpio_test_cb(IN CONST CHAR_T *in, OUT CHAR_T *out)
{
return TRUE;
}
BOOL_T mf_pre_gpio_test_cb(VOID)
{
return TRUE;
}
/**
* @brief SOC device initialization
*
* @param[in] none
*
* @return OPRT_OK on success. Others on error, please refer to "tuya_error_code.h".
*/
OPERATE_RET __soc_device_init(VOID_T)
{
OPERATE_RET rt = OPRT_OK;
#if (defined(UUID) && defined(AUTHKEY))
ws_db_init_mf();
/* Set authorization information
* Note that if you use the default authorization information of the code, there may be problems of multiple users and conflicts,
* so try to use all the authorizations purchased from the tuya iot platform.
* Buying guide: https://developer.tuya.com/cn/docs/iot/lisence-management?id=Kb4qlem97idl0.
* You can also apply for two authorization codes for free in the five-step hardware development stage of the Tuya IoT platform.
* Authorization information can also be written through the production testing tool.
* When the production testing function is started and the authorization is burned with the Tuya Cloud module tool,
* please comment out this piece of code.
*/
WF_GW_PROD_INFO_S prod_info = {UUID, AUTHKEY};
TUYA_CALL_ERR_RETURN(tuya_iot_set_wf_gw_prod_info(&prod_info));
#else
// 产测初始化, 注册函数需要应用实现,其中串口驱动不需要应用提供
MF_IMPORT_INTF_S intf = {0};
intf.uart_init = mf_uart_init_callback;
intf.uart_free = mf_uart_free_callback;
intf.uart_send = mf_uart_send_callback;
intf.uart_recv = mf_uart_recv_callback;
intf.gpio_test = mf_gpio_test_cb;
intf.mf_user_product_test = mf_user_product_test_callback;
intf.user_callback = mf_user_callback;
intf.user_enter_mf_callback = mf_user_enter_mf_callback;
intf.user_pre_gpio_test = mf_pre_gpio_test_cb;
TAL_PR_ERR("mf_init APP_BIN_NAME[%s] USER_SW_VER[%s]", APP_BIN_NAME, USER_SW_VER);
TUYA_CALL_ERR_RETURN(mf_init(&intf, APP_BIN_NAME, USER_SW_VER, TRUE));
#endif
/* Initialize TuyaOS product information */
TY_IOT_CBS_S iot_cbs = {0};
iot_cbs.gw_status_cb = __soc_dev_status_changed_cb;
iot_cbs.gw_ug_cb = __soc_dev_rev_upgrade_info_cb;
iot_cbs.gw_reset_cb = __soc_dev_restart_req_cb;
iot_cbs.dev_obj_dp_cb = __soc_dev_obj_dp_cmd_cb;
iot_cbs.dev_raw_dp_cb = __soc_dev_raw_dp_cmd_cb;
iot_cbs.dev_dp_query_cb = __soc_dev_dp_query_cb;
TUYA_CALL_ERR_RETURN(tuya_iot_wf_soc_dev_init(GWCM_OLD, WF_START_AP_FIRST, &iot_cbs, PID, USER_SW_VER));
TUYA_CALL_ERR_RETURN(tuya_iot_reg_get_wf_nw_stat_cb(__soc_dev_net_status_cb));
TAL_PR_DEBUG("Youkai init led & key");
/* Network button, LED initialization */
app_led_init(LED_PIN);
app_key_init(KEY_PIN);
// TAL_PR_DEBUG("Youkai init light\n");
// TUYA_CALL_ERR_RETURN(app_light_init());
return 0;
}
STATIC VOID_T user_main(VOID_T)
{
OPERATE_RET rt = OPRT_OK;
/* Initialization, because DB initialization takes a long time,
* which affects the startup efficiency of some devices,
* so special processing is performed during initialization to delay initialization of DB
*/
TY_INIT_PARAMS_S init_param = {0};
init_param.init_db = TRUE;
strcpy(init_param.sys_env, TARGET_PLATFORM);
TUYA_CALL_ERR_LOG(tuya_iot_init_params(NULL, &init_param));
tal_log_set_manage_attr(TAL_LOG_LEVEL_DEBUG);
/* Initialization device */
TAL_PR_DEBUG("device_init in");
// TUYA_CALL_ERR_LOG(__soc_device_init());
TUYA_CALL_ERR_LOG(app_light_init());
return;
}
/**
* @brief task thread
*
* @param[in] arg:Parameters when creating a task
* @return none
*/
STATIC VOID_T tuya_app_thread(VOID_T *arg)
{
/* Initialization LWIP first!!! */
#if defined(ENABLE_LWIP) && (ENABLE_LWIP == 1)
TUYA_LwIP_Init();
#endif
user_main();
tal_thread_delete(ty_app_thread);
ty_app_thread = NULL;
}
/**
* @brief user entry function
*
* @param[in] none:
*
* @return none
*/
VOID_T tuya_app_main(VOID_T)
{
THREAD_CFG_T thrd_param = {4096, 4, "tuya_app_main"};
tal_thread_create_and_start(&ty_app_thread, NULL, NULL, tuya_app_thread, NULL, &thrd_param);
}
四、编译
在ubuntu下使用vscode进行编译很方便。
五、刷机
六、测试结果
如图,其中buf显示的是bh1750返回的值,两个字节。
比如01,38合起来就是0x138=312。
c
[01-01 00:43:20 TUYA E][tdd_sensor_bh1750.c:861] [BH1750] __tdd_sensor_bh1750_read
[01-01 00:43:20 TUYA E][tdd_sensor_bh1750.c:425] [BH1750] __bh1750_read_light
[01-01 00:43:20 TUYA E][tdd_sensor_bh1750.c:450] [BH1750] buf = 1 38 light= 312
[01-01 00:43:20 TUYA E][tdd_sensor_bh1750.c:871] [BH1750] get value. resl=2
[01-01 00:43:20 TUYA E][tdd_sensor_bh1750.c:392] light_val->sr_float=312.0
[01-01 00:43:20 TUYA I][app_light.c:147] Light: 312 sg_lt_dp_data.light.dp_value: 312
[01-01 00:43:22 TUYA E][tdd_sensor_bh1750.c:861] [BH1750] __tdd_sensor_bh1750_read
[01-01 00:43:22 TUYA E][tdd_sensor_bh1750.c:425] [BH1750] __bh1750_read_light
[01-01 00:43:22 TUYA E][tdd_sensor_bh1750.c:450] [BH1750] buf = 4 3d light= 1085
[01-01 00:43:22 TUYA E][tdd_sensor_bh1750.c:871] [BH1750] get value. resl=2
[01-01 00:43:22 TUYA E][tdd_sensor_bh1750.c:392] light_val->sr_float=1085.0
[01-01 00:43:22 TUYA I][app_light.c:147] Light: 1085 sg_lt_dp_data.light.dp_value: 312
[01-01 00:43:22 TUYA I][app_light.c:154] Light change. Enable report
[01-01 00:43:24 TUYA E][tdd_sensor_bh1750.c:861] [BH1750] __tdd_sensor_bh1750_read
[01-01 00:43:24 TUYA E][tdd_sensor_bh1750.c:425] [BH1750] __bh1750_read_light
[01-01 00:43:24 TUYA E][tdd_sensor_bh1750.c:450] [BH1750] buf = 4 3d light= 1085
[01-01 00:43:24 TUYA E][tdd_sensor_bh1750.c:871] [BH1750] get value. resl=2
[01-01 00:43:24 TUYA E][tdd_sensor_bh1750.c:392] light_val->sr_float=1085.0
[01-01 00:43:24 TUYA I][app_light.c:147] Light: 1085 sg_lt_dp_data.light.dp_value: 1085
小结
本章只是基础的添加驱动,后续还是需要实现联网并上传到云端。
补充一下,除了前期遇到环境搭建的网络问题,涂鸦的开发还是很舒服的,一键编译和一键下载。