功能:添加 Wi-Fi 连接管理组件
在 wifi-connect.c 中实现了新的 Wi-Fi 连接管理模块,负责配网、连接及状态上报。 添加了用于 Wi-Fi 配置和状态显示的 HTML 界面。 集成了 NVS 用于存储 Wi-Fi 凭证。 更新了 CMakeLists.txt 以包含新模块的依赖项。 修改了 main.c 以初始化 Wi-Fi 连接管理并等待连接成功。
This commit is contained in:
3
components/bh1750/CMakeLists.txt
Normal file
3
components/bh1750/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "bh1750.c" "bh1750_use.c"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES "esp_driver_i2c")
|
||||
13
components/bh1750/README.md
Normal file
13
components/bh1750/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# 组件:BH1750
|
||||
|
||||
[](https://components.espressif.com/components/espressif/bh1750)
|
||||

|
||||
|
||||
:warning: **BH1750 组件按“现状”提供,不再进行后续开发及兼容性维护**
|
||||
|
||||
* 本组件将向您展示如何使用 I2C 模块读取外部 I2C 传感器数据,此处以 BH1750 光传感器(GY-30 模块)为例。
|
||||
* BH1750 测量模式:
|
||||
* 单次模式:BH1750 仅在接收到单次测量命令时测量一次,因此每次需要获取光照强度值时,都需要发送该命令。
|
||||
* 连续模式:BH1750 在接收到连续测量命令后将持续进行测量,只需发送一次该命令,之后反复调用 `bh1750_get_data()` 即可获取光照强度值。
|
||||
## 注意:
|
||||
* BH1750 在不同测量模式下的测量时间不同。可通过调用 `bh1750_change_measure_time()` 更改测量时间。
|
||||
144
components/bh1750/bh1750.c
Normal file
144
components/bh1750/bh1750.c
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "bh1750.h"
|
||||
#include "driver/i2c_master.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/projdefs.h" // for pdMS_TO_TICKS
|
||||
|
||||
#define BH_1750_MEASUREMENT_ACCURACY 1.2 /*!< BH1750 传感器的典型测量精度因子 */
|
||||
|
||||
#define BH1750_POWER_DOWN 0x00 /*!< 设置为掉电模式的命令 */
|
||||
#define BH1750_POWER_ON 0x01 /*!< 设置为上电模式的命令 */
|
||||
#define I2C_CLK_SPEED 400000 /*!< I2C 通信时钟频率 (400kHz) */
|
||||
|
||||
/**
|
||||
* @brief BH1750 设备私有结构体
|
||||
*/
|
||||
typedef struct {
|
||||
i2c_master_dev_handle_t i2c_handle; /*!< I2C 主设备句柄 */
|
||||
} bh1750_dev_t;
|
||||
|
||||
/**
|
||||
* @brief 向 BH1750 写入一个字节的辅助函数
|
||||
*/
|
||||
static esp_err_t bh1750_write_byte(const bh1750_dev_t *const sens, const uint8_t byte)
|
||||
{
|
||||
return i2c_master_transmit(sens->i2c_handle, &byte, 1, pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建并注册 BH1750 设备
|
||||
*
|
||||
* @param i2c_bus I2C 总线句柄
|
||||
* @param dev_addr 传感器 I2C 地址 (一般为 0x23 或 0x5C)
|
||||
* @param handle_ret [out] 返回创建好的设备句柄
|
||||
* @return esp_err_t 成功返回 ESP_OK
|
||||
*/
|
||||
esp_err_t bh1750_create(i2c_master_bus_handle_t i2c_bus, const uint8_t dev_addr, bh1750_handle_t *handle_ret)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
bh1750_dev_t *sensor = (bh1750_dev_t *) calloc(1, sizeof(bh1750_dev_t));
|
||||
if (!sensor) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
// 配置并添加新的 I2C 设备到总线
|
||||
const i2c_device_config_t i2c_dev_cfg = {
|
||||
.device_address = dev_addr,
|
||||
.scl_speed_hz = I2C_CLK_SPEED,
|
||||
};
|
||||
ret = i2c_master_bus_add_device(i2c_bus, &i2c_dev_cfg, &sensor->i2c_handle);
|
||||
if (ret != ESP_OK) {
|
||||
free(sensor);
|
||||
return ret;
|
||||
}
|
||||
|
||||
assert(sensor->i2c_handle);
|
||||
*handle_ret = sensor;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 删除 BH1750 设备并释放资源
|
||||
*/
|
||||
esp_err_t bh1750_delete(bh1750_handle_t sensor)
|
||||
{
|
||||
bh1750_dev_t *sens = (bh1750_dev_t *) sensor;
|
||||
if (sens->i2c_handle) {
|
||||
i2c_master_bus_rm_device(sens->i2c_handle);
|
||||
}
|
||||
free(sens);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 进入掉电模式(低功耗)
|
||||
*/
|
||||
esp_err_t bh1750_power_down(bh1750_handle_t sensor)
|
||||
{
|
||||
bh1750_dev_t *sens = (bh1750_dev_t *) sensor;
|
||||
return bh1750_write_byte(sens, BH1750_POWER_DOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 唤醒并进入上电模式
|
||||
*/
|
||||
esp_err_t bh1750_power_on(bh1750_handle_t sensor)
|
||||
{
|
||||
bh1750_dev_t *sens = (bh1750_dev_t *) sensor;
|
||||
return bh1750_write_byte(sens, BH1750_POWER_ON);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置测量时间倍率 (MTreg)
|
||||
* 用于改变传感器的测量灵敏度
|
||||
*/
|
||||
esp_err_t bh1750_set_measure_time(bh1750_handle_t sensor, const uint8_t measure_time)
|
||||
{
|
||||
bh1750_dev_t *sens = (bh1750_dev_t *) sensor;
|
||||
uint32_t i = 0;
|
||||
uint8_t buf[2] = {0x40, 0x60}; // MTreg 常量部分
|
||||
buf[0] |= measure_time >> 5;
|
||||
buf[1] |= measure_time & 0x1F;
|
||||
for (i = 0; i < 2; i++) {
|
||||
esp_err_t ret = bh1750_write_byte(sens, buf[i]);
|
||||
if (ESP_OK != ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置测量模式(连续测量或单词测量,以及分辨率选择)
|
||||
*/
|
||||
esp_err_t bh1750_set_measure_mode(bh1750_handle_t sensor, const bh1750_measure_mode_t cmd_measure)
|
||||
{
|
||||
bh1750_dev_t *sens = (bh1750_dev_t *) sensor;
|
||||
return bh1750_write_byte(sens, (uint8_t)cmd_measure);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取测量结果
|
||||
*
|
||||
* @param sensor 设备句柄
|
||||
* @param data [out] 返回转换后的光照强度值 (单位: Lux)
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t bh1750_get_data(bh1750_handle_t sensor, float *const data)
|
||||
{
|
||||
bh1750_dev_t *sens = (bh1750_dev_t *) sensor;
|
||||
uint8_t read_buffer[2];
|
||||
// 从 I2C 读取 2 字节原始数据
|
||||
esp_err_t ret = i2c_master_receive(sens->i2c_handle, read_buffer, sizeof(read_buffer), pdMS_TO_TICKS(1000));
|
||||
if (ESP_OK != ret) {
|
||||
return ret;
|
||||
}
|
||||
// 将原始数据转换为 Lux (公式: (高8位 << 8 | 低8位) / 1.2)
|
||||
*data = (( read_buffer[0] << 8 | read_buffer[1] ) / BH_1750_MEASUREMENT_ACCURACY);
|
||||
return ESP_OK;
|
||||
}
|
||||
131
components/bh1750/bh1750_use.c
Normal file
131
components/bh1750/bh1750_use.c
Normal file
@@ -0,0 +1,131 @@
|
||||
#include <stdio.h>
|
||||
#include "esp_log.h"
|
||||
#include "driver/i2c_master.h"
|
||||
#include "bh1750.h"
|
||||
#include "bh1750_use.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
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 总线
|
||||
*/
|
||||
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 (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "I2C 总线初始化失败: %s", esp_err_to_name(ret));
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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, "资源已释放");
|
||||
}
|
||||
136
components/bh1750/include/bh1750.h
Normal file
136
components/bh1750/include/bh1750.h
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief BH1750 driver
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "driver/i2c_types.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
typedef enum {
|
||||
BH1750_CONTINUE_1LX_RES = 0x10, /*!< Command to set measure mode as Continuously H-Resolution mode*/
|
||||
BH1750_CONTINUE_HALFLX_RES = 0x11, /*!< Command to set measure mode as Continuously H-Resolution mode2*/
|
||||
BH1750_CONTINUE_4LX_RES = 0x13, /*!< Command to set measure mode as Continuously L-Resolution mode*/
|
||||
BH1750_ONETIME_1LX_RES = 0x20, /*!< Command to set measure mode as One Time H-Resolution mode*/
|
||||
BH1750_ONETIME_HALFLX_RES = 0x21, /*!< Command to set measure mode as One Time H-Resolution mode2*/
|
||||
BH1750_ONETIME_4LX_RES = 0x23, /*!< Command to set measure mode as One Time L-Resolution mode*/
|
||||
} bh1750_measure_mode_t;
|
||||
|
||||
#define BH1750_I2C_ADDRESS_DEFAULT (0x23)
|
||||
typedef void *bh1750_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Set bh1750 as power down mode (low current)
|
||||
*
|
||||
* @param sensor object handle of bh1750
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_FAIL Fail
|
||||
*/
|
||||
esp_err_t bh1750_power_down(bh1750_handle_t sensor);
|
||||
|
||||
/**
|
||||
* @brief Set bh1750 as power on mode
|
||||
*
|
||||
* @param sensor object handle of bh1750
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_FAIL Fail
|
||||
*/
|
||||
esp_err_t bh1750_power_on(bh1750_handle_t sensor);
|
||||
|
||||
/**
|
||||
* @brief Get light intensity from bh1750
|
||||
*
|
||||
* @param sensor object handle of bh1750
|
||||
* @param[in] cmd_measure the instruction to set measurement mode
|
||||
*
|
||||
* @note
|
||||
* You should call this funtion to set measurement mode before call bh1750_get_data() to acquire data.
|
||||
* If you set onetime mode, you just can get one measurement result.
|
||||
* If you set continuous mode, you can call bh1750_get_data() to acquire data repeatedly.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_FAIL Fail
|
||||
*/
|
||||
esp_err_t bh1750_set_measure_mode(bh1750_handle_t sensor, const bh1750_measure_mode_t cmd_measure);
|
||||
|
||||
/**
|
||||
* @brief Get light intensity from BH1750
|
||||
*
|
||||
* Returns light intensity in [lx] corrected by typical BH1750 Measurement Accuracy (= 1.2).
|
||||
*
|
||||
* @see BH1750 datasheet Rev. D page 2
|
||||
*
|
||||
* @note
|
||||
* You should acquire data from the sensor after the measurement time is over,
|
||||
* so take care of measurement time in different modes.
|
||||
*
|
||||
* @param sensor object handle of bh1750
|
||||
* @param[out] data light intensity value got from bh1750 in [lx]
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_FAIL Fail
|
||||
*/
|
||||
esp_err_t bh1750_get_data(bh1750_handle_t sensor, float *const data);
|
||||
|
||||
/**
|
||||
* @brief Set measurement time
|
||||
*
|
||||
* This function is used to adjust BH1750 sensitivity, i.e. compensating influence from optical window.
|
||||
*
|
||||
* @see BH1750 datasheet Rev. D page 11
|
||||
*
|
||||
* @param sensor object handle of bh1750
|
||||
* @param[in] measure_time measurement time
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_FAIL Fail
|
||||
*/
|
||||
esp_err_t bh1750_set_measure_time(bh1750_handle_t sensor, const uint8_t measure_time);
|
||||
|
||||
/**
|
||||
* @brief Create and init sensor object and return a sensor handle
|
||||
*
|
||||
* @param[in] i2c_bus I2C bus handle. Obtained from i2c_new_master_bus().s
|
||||
* @param[in] dev_addr I2C device address of sensor. Use BH1750_I2C_ADDRESS_DEFAULT for default address.
|
||||
* @param[out] handle_ret Handle to created BH1750 driver object.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_NO_MEM Not enough memory for the driver
|
||||
* - ESP_ERR_NOT_FOUND Sensor not found on the I2C bus
|
||||
* - Others Error from underlying I2C driver
|
||||
*/
|
||||
esp_err_t bh1750_create(i2c_master_bus_handle_t i2c_bus, const uint8_t dev_addr, bh1750_handle_t *handle_ret);
|
||||
|
||||
/**
|
||||
* @brief Delete and release a sensor object
|
||||
*
|
||||
* @param sensor object handle of bh1750
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_FAIL Fail
|
||||
*/
|
||||
esp_err_t bh1750_delete(bh1750_handle_t sensor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
38
components/bh1750/include/bh1750_use.h
Normal file
38
components/bh1750/include/bh1750_use.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef BH1750_USE_H
|
||||
#define BH1750_USE_H
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// 定义使用的 I2C 引脚(根据你的硬件实际连接修改)
|
||||
#define BH1750_I2C_SCL_IO 1 // ESP32-S3 建议引脚
|
||||
#define BH1750_I2C_SDA_IO 2 // ESP32-S3 建议引脚
|
||||
|
||||
/**
|
||||
* @brief 初始化 BH1750 传感器及其所需的 I2C 总线
|
||||
*
|
||||
* @return esp_err_t 成功返回 ESP_OK
|
||||
*/
|
||||
esp_err_t bh1750_user_init(void);
|
||||
|
||||
/**
|
||||
* @brief 读取一次光照强度数据 (Lux)
|
||||
*
|
||||
* @param lux [out] 存储结果的指针
|
||||
* @return esp_err_t 成功返回 ESP_OK
|
||||
*/
|
||||
esp_err_t bh1750_user_read(float *lux);
|
||||
|
||||
/**
|
||||
* @brief 释放 BH1750 相关资源
|
||||
*/
|
||||
void bh1750_user_deinit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BH1750_USE_H
|
||||
Reference in New Issue
Block a user