完成对光照和温湿度的采集,显示到LCD上,并存放在变量
This commit is contained in:
@@ -8,124 +8,50 @@
|
||||
|
||||
static const char *TAG = "BH1750_USE";
|
||||
|
||||
#define BH1750_READ_RETRY_COUNT 3
|
||||
#define BH1750_MEASURE_DELAY_MS 200
|
||||
#define BH1750_RETRY_INTERVAL_MS 30
|
||||
|
||||
static i2c_master_bus_handle_t s_i2c_bus_handle = NULL;
|
||||
static bh1750_handle_t s_bh1750_handle = NULL;
|
||||
|
||||
/**
|
||||
* @brief 初始化 BH1750 传感器及其所需的 I2C 总线
|
||||
*/
|
||||
i2c_master_bus_handle_t bh1750_get_i2c_bus_handle(void)
|
||||
{
|
||||
return s_i2c_bus_handle;
|
||||
}
|
||||
|
||||
esp_err_t bh1750_user_init(void)
|
||||
{
|
||||
// 1. 配置并初始化 I2C 总线 (Master Bus)
|
||||
i2c_master_bus_config_t bus_config = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = I2C_NUM_0,
|
||||
.scl_io_num = BH1750_I2C_SCL_IO,
|
||||
.sda_io_num = BH1750_I2C_SDA_IO,
|
||||
.glitch_ignore_cnt = 7,
|
||||
};
|
||||
|
||||
esp_err_t ret = i2c_new_master_bus(&bus_config, &s_i2c_bus_handle);
|
||||
if (s_i2c_bus_handle == NULL) {
|
||||
i2c_master_bus_config_t bus_config = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = I2C_NUM_0,
|
||||
.scl_io_num = (gpio_num_t)BH1750_I2C_SCL_IO,
|
||||
.sda_io_num = (gpio_num_t)BH1750_I2C_SDA_IO,
|
||||
.glitch_ignore_cnt = 7,
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &s_i2c_bus_handle));
|
||||
}
|
||||
|
||||
esp_err_t ret = bh1750_create(s_i2c_bus_handle, BH1750_I2C_ADDRESS_DEFAULT, &s_bh1750_handle);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "I2C 总线初始化失败: %s", esp_err_to_name(ret));
|
||||
ESP_LOGE(TAG, "BH1750 设备创建失败");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 2. 创建 BH1750 设备句柄 (使用驱动默认地址 0x23)
|
||||
ret = bh1750_create(s_i2c_bus_handle, BH1750_I2C_ADDRESS_DEFAULT, &s_bh1750_handle);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "BH1750 设备创建失败: %s", esp_err_to_name(ret));
|
||||
if (s_i2c_bus_handle) {
|
||||
i2c_del_master_bus(s_i2c_bus_handle);
|
||||
s_i2c_bus_handle = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 3. 初始上电
|
||||
ret = bh1750_power_on(s_bh1750_handle);
|
||||
if (ret == ESP_OK) {
|
||||
ESP_LOGI(TAG, "BH1750 初始化成功");
|
||||
}
|
||||
|
||||
return ret;
|
||||
return bh1750_power_on(s_bh1750_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 读取一次光照强度数据 (Lux)
|
||||
*/
|
||||
esp_err_t bh1750_user_read(float *lux)
|
||||
{
|
||||
if (lux == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (s_bh1750_handle == NULL) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
for (int attempt = 1; attempt <= BH1750_READ_RETRY_COUNT; ++attempt) {
|
||||
// 单次模式每次读取前都先上电,避免传感器处于掉电状态导致返回 0
|
||||
ret = bh1750_power_on(s_bh1750_handle);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGW(TAG, "上电失败(第%d次): %s", attempt, esp_err_to_name(ret));
|
||||
vTaskDelay(pdMS_TO_TICKS(BH1750_RETRY_INTERVAL_MS));
|
||||
continue;
|
||||
}
|
||||
|
||||
// 设置测量模式:单次高分辨率模式 (1lx)
|
||||
ret = bh1750_set_measure_mode(s_bh1750_handle, BH1750_ONETIME_1LX_RES);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGW(TAG, "设置测量模式失败(第%d次): %s", attempt, esp_err_to_name(ret));
|
||||
vTaskDelay(pdMS_TO_TICKS(BH1750_RETRY_INTERVAL_MS));
|
||||
continue;
|
||||
}
|
||||
|
||||
// 根据数据手册,单次高分辨率模式需要约 120ms-180ms 测量时间
|
||||
vTaskDelay(pdMS_TO_TICKS(BH1750_MEASURE_DELAY_MS));
|
||||
|
||||
ret = bh1750_get_data(s_bh1750_handle, lux);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGW(TAG, "数据读取失败(第%d次): %s", attempt, esp_err_to_name(ret));
|
||||
vTaskDelay(pdMS_TO_TICKS(BH1750_RETRY_INTERVAL_MS));
|
||||
continue;
|
||||
}
|
||||
|
||||
// 在强光/室内环境下长期 0 Lux 通常不合理,重试一次可规避偶发总线抖动
|
||||
if (*lux <= 0.0f && attempt < BH1750_READ_RETRY_COUNT) {
|
||||
ESP_LOGW(TAG, "读取到 0 Lux,准备重试(第%d次)", attempt);
|
||||
vTaskDelay(pdMS_TO_TICKS(BH1750_RETRY_INTERVAL_MS));
|
||||
continue;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (ret == ESP_OK && *lux <= 0.0f) {
|
||||
ESP_LOGW(TAG, "连续读取均为 0 Lux,请优先检查 I2C 上拉电阻和传感器供电");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
if (s_bh1750_handle == NULL) return ESP_ERR_INVALID_STATE;
|
||||
|
||||
bh1750_power_on(s_bh1750_handle);
|
||||
bh1750_set_measure_mode(s_bh1750_handle, BH1750_ONETIME_1LX_RES);
|
||||
vTaskDelay(pdMS_TO_TICKS(180));
|
||||
return bh1750_get_data(s_bh1750_handle, lux);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 释放 BH1750 相关资源
|
||||
*/
|
||||
void bh1750_user_deinit(void)
|
||||
{
|
||||
if (s_bh1750_handle) {
|
||||
bh1750_delete(s_bh1750_handle);
|
||||
s_bh1750_handle = NULL;
|
||||
}
|
||||
if (s_i2c_bus_handle) {
|
||||
i2c_del_master_bus(s_i2c_bus_handle);
|
||||
s_i2c_bus_handle = NULL;
|
||||
}
|
||||
ESP_LOGI(TAG, "资源已释放");
|
||||
}
|
||||
|
||||
@@ -2,27 +2,28 @@
|
||||
#define BH1750_USE_H
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "driver/i2c_master.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// 定义使用的 I2C 引脚(根据你的硬件实际连接修改)
|
||||
#define BH1750_I2C_SCL_IO 1 // ESP32-S3 建议引脚
|
||||
#define BH1750_I2C_SDA_IO 2 // ESP32-S3 建议引脚
|
||||
// 定义使用的 I2C 引脚
|
||||
#define BH1750_I2C_SCL_IO 1
|
||||
#define BH1750_I2C_SDA_IO 2
|
||||
|
||||
/**
|
||||
* @brief 初始化 BH1750 传感器及其所需的 I2C 总线
|
||||
*
|
||||
* @return esp_err_t 成功返回 ESP_OK
|
||||
*/
|
||||
esp_err_t bh1750_user_init(void);
|
||||
|
||||
/**
|
||||
* @brief 获取 I2C 总线句柄,以便其他传感器(如 AHT30)共用总线
|
||||
*/
|
||||
i2c_master_bus_handle_t bh1750_get_i2c_bus_handle(void);
|
||||
|
||||
/**
|
||||
* @brief 读取一次光照强度数据 (Lux)
|
||||
*
|
||||
* @param lux [out] 存储结果的指针
|
||||
* @return esp_err_t 成功返回 ESP_OK
|
||||
*/
|
||||
esp_err_t bh1750_user_read(float *lux);
|
||||
|
||||
@@ -35,4 +36,4 @@ void bh1750_user_deinit(void);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BH1750_USE_H
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user