软硬件开源项目-智能路灯系统:OneNET云平台监测+Web网页控制+代码解析
智能路灯系统项目下载源码
本仓库提供了完整的智能路灯系统项目的源码,旨在帮助开发者快速搭建和理解智能路灯系统的实现过程。
项目地址:https://gitee.com/zhu-heyang/w55mh32-smart-street-light.git
1 前言
前两天晚上出去溜达的时候,路过路灯的时候,感觉灯光很强刺的人睁不开眼,而且那么高的亮度一直亮着也不省电,当时我就想要是我来设计路灯的话可能不会这样设计,如果是我的话一定会加上一个亮度自适应的功能,没人的时候就亮度低一点有人的时候就更亮一点人走一会才恢复原来的亮度,而且现在物联网那么发达,应该加上一个远程控制的功能。于是说干就干,挑硬件时在淘宝上发现了 W55MH32Q 这款开发板,它的性能跟我这个项目的需求特别对得上,然后就选择了这款开发板,我选它主要有三个原因:
一是自带以太网功能,无需额外挂载通信模块,就能稳定运行 MQTT 协议传输数据,省去了模块兼容调试的麻烦,数据传输的可靠性也更有保障。
二是接口设计合理,红外传感器器和光照传感器可直接通过标准接口连接,硬件层无需额外电平转换或隔离电路,适配过程很顺畅。
三是集成了串口芯片,无需外接 USB 转串口模块,直接通过串口助手就能打印调试信息,对嵌入式开发来说,这种无需外接模块的调试支持简直是太方便了。
以此搭建的系统通过红外和光照传感器每 5 秒采集一次环境数据,经开发板处理后上传 OneNET 平台。自动模式下,光照低于网页设定阈值时 LED 以 20% 初始亮度开启(初始亮度可通过网页端调节),红外检测到行人 / 车辆即升至 100%,离开 10 秒后恢复低亮;手动模式支持网页端直接控制LED灯的开关与亮度。开发板的接口兼容性与网络稳定性保障了系统精准响应与节能目标。
2 项目环境
2.1 硬件要求
- W55MH32Q开发板
- LED灯、光照传感器、红外传感器
- USB Type-C数据线
- 路由器
2.2 软件环境
- 编译器:Keil
- W55MH32驱动库
- HBuilder X
- OneNET云平台
- WIZ UartTool串口助手
3 硬件连接和方案
3.1 系统硬件连接
- LED灯正极连接开发板A0引脚
- 红外传感器数据采样引脚OUT接开发板A3引脚
- 光照传感器数据采样引脚AO连接开发板A4引脚
3.2 方案图示
4 MQTT连接OneNET云平台收发数据流程
4.1 准备阶段
注册账号在这里不进行赘述,下面我们看如何建立物模型。
创建产品和添加物模型:登录OneNET物联网平台,创建产品并在产品下添加以下物模型功能。
创建设备:在刚刚创建的产品下创建相应设备。
4.2 设备详情
设备详情:在设备详情页中可以查看设备密钥和产品ID等重要信息。
4.3 Token 密钥生成
设备与 OneNet 平台通信时,Token 作为身份凭证用于安全认证。需使用 Token 生成工具:
OneNET Token 生成工具文档
- res 字段:
products/{产品id}/devices/{设备名}
(使用设备级 Key)。替换{产品id}
和{设备名}
。 - et 字段: 访问过期时间 (Unix 时间戳)。可使用在线转换工具获取。
- key 字段: 填写设备的密钥。
- 点击
generate
生成 Token 密钥。
4.4 连接、订阅和发布消息
订阅主题:$sys/{pid}/{device-name}/thing/property/set
发布主题:$sys/{pid}/{device-name}/thing/property/post
pid是product_id的简称,即产品ID。
device-name是设备名称。
接着我们可以使用上面记录的连接参数进行连接,当连接成功后,订阅上面的订阅主题。并通过发布主题上报物模型数据。
在OneNET平台,如果产品创建阶段选择的数据格式为OneJSON格式时,接收和发送数据格式都会遵守下面这个格式:
{
"id": "123",
"version": "1.0",
"params": {
"temperature":"30.5"
}
}
id:值为"123",这是一个唯一的标识符;params是一个包含设备属性数据的对象用于上报物模型数据;version:值为 “1.0”,表示该消息所遵循的协议版本。
4.5 接收消息处理
接收消息:当接收到消息时,我们只需要按照上面的json格式进行解析,然后进行相应的处理即可。
5 HBuilder X
- HBuilder X工程下载:
- 链接: https://pan.baidu.com/s/1oIIr3oTnHG-we22AkLQu8w?pwd=6en9
- 提取码:
6en9
- 修改步骤:
- 下载后导入HBuilder X。
- 修改
index.vue
文件:- 修改 Token: 替换 const params = {
author_key: ‘’, //用户密钥
version: ‘2022-05-01’,
user_id: ‘’, //用户ID
} 中的author_key和user_id即可生成用户 Token。 - 修改产品 ID 和设备名: 在
url
中替换product_id
和device_name
参数为实际值。
- 修改 Token: 替换 const params = {
- 修改完毕后即可通过HBuilder X自带的发行功能对文件进行打包,可打包成网页或者APP根据需要可自行选择。
6 主要程序解析
6.1 main.c分析
在主函数中实现以下软硬件初始化:配置时钟、串口、定时器,初始化红外传感器、光照传感器和LED灯。
网络初始化:配置开发板和MQTT客户端,支持DHCP 动态获取IP。
数据采集与控制:每5秒采集一次光照强度和监测红外感应,调用LED灯控制函数。
数据上传:调用light_control()和do_mqtt()函数将传感器数据和设备状态发送到云平台。
#include "PWM.h"
#include "Timer.h"
#include "adc.h"
#include "bsp_rcc.h"
#include "bsp_tim.h"
#include "bsp_uart.h"
#include "delay.h"
#include "do_mqtt.h"
#include "infrared.h"
#include "light.h"
#include "w55mh32_gpio.h"
#include "wiz_interface.h"
#include "wizchip_conf.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SOCKET_ID 0
#define ETHERNET_BUF_MAX_SIZE (1024 * 2)
/* network information */
wiz_NetInfo default_net_info = {.mac = {0x00, 0x08, 0xdc, 0x12, 0x22, 0x12},
.ip = {192, 168, 1, 30},
.gw = {192, 168, 1, 1},
.sn = {255, 255, 255, 0},
.dns = {8, 8, 8, 8},
.dhcp = NETINFO_DHCP};
uint8_t ethernet_buf[ETHERNET_BUF_MAX_SIZE] = {0};
static uint8_t mqtt_send_ethernet_buf[ETHERNET_BUF_MAX_SIZE] = {0};
static uint8_t mqtt_recv_ethernet_buf[ETHERNET_BUF_MAX_SIZE] = {0};
int main(void) {
/* hardware initialization */
rcc_clk_config();
delay_init();
console_usart_init(115200);
tim3_init();
light_init();
infrared_init();
pwm_init();
timer_init();
ad_init();
printf("%s MQTT OneNET example\r\n", _WIZCHIP_ID_);
/* wiztoe init */
wiz_toe_init();
wiz_phy_link_check();
network_init(ethernet_buf, &default_net_info);
mqtt_init(SOCKET_ID, mqtt_send_ethernet_buf, mqtt_recv_ethernet_buf);
while (1) {
light_control();
do_mqtt();
}
}
6.2 do_mqtt.c分析
核心代码功能:通过MQTT协议实现设备、OneNET云平台的双向交互,包括传感器数据(红外感应、光照、LED灯状态)上报及命令下发。
/**
* @brief 解析JSON格式的控制消息,并根据消息内容控制硬件,最后回复处理结果
* @param msg 待解析的JSON格式字符串,包含控制指令(如LED开关、模式切换等)
* @note 该函数使用cJSON库解析JSON,提取相关控制参数后更新全局变量以控制硬件,
* 并通过MQTT协议向云平台回复处理结果
*/
void json_decode(char *msg)
{
int ret; // 函数返回值,用于判断MQTT发布是否成功
char replymsg[128] = {0}; // 存储回复云平台的JSON格式字符串
cJSON *id = NULL; // 指向JSON中"id"字段的cJSON对象(消息标识)
cJSON *jsondata = NULL; // 指向解析后的根cJSON对象
cJSON *params = NULL; // 指向JSON中"params"字段的cJSON对象(参数集合)
cJSON *LED = NULL; // 指向"params"中"LED"字段(LED开关控制)
cJSON *Mode_switch = NULL; // 指向"params"中"Mode_switch"字段(模式切换控制)
cJSON *Brightness_set = NULL; // 指向"params"中"Brightness_set"字段(亮度设置)
cJSON *light_threshold = NULL; // 指向"params"中"light_threshold"字段(光感阈值设置)
// 解析输入的JSON字符串,生成cJSON对象树
jsondata = cJSON_Parse(msg);
if (jsondata == NULL)
{
printf("json parse fail.\r\n"); // 解析失败(如格式错误),打印错误信息
return;
}
// 从根对象中获取各字段值
id = cJSON_GetObjectItem(jsondata, "id"); // 获取消息标识"id"
params = cJSON_GetObjectItem(jsondata, "params"); // 获取参数集合"params"
LED = cJSON_GetObjectItem(params, "LED"); // 从params中获取LED控制参数
Mode_switch = cJSON_GetObjectItem(params, "Mode_switch"); // 获取模式切换参数
Brightness_set = cJSON_GetObjectItem(params, "Brightness_set"); // 获取亮度设置参数
light_threshold = cJSON_GetObjectItem(params, "light_threshold"); // 获取光感阈值参数
// 根据LED参数控制LED开关(通过PWM占空比实现)
if (LED != NULL) // 仅当JSON中包含"LED"字段时处理
{
if (LED->valueint) // LED值为非0(通常1表示开启)
{
g_pwm_DutyCycle = 20; // 设置PWM占空比为20(LED开启,亮度20%)
}
else // LED值为0(表示关闭)
{
g_pwm_DutyCycle = 0; // PWM占空比设为0(LED关闭)
}
}
// 根据模式切换参数切换工作模式
if (Mode_switch != NULL) // 仅当JSON中包含"Mode_switch"字段时处理
{
if (Mode_switch->valueint) // 模式值为非0(通常1表示自动模式)
{
g_Modes_witch = 1; // 更新全局模式变量为自动模式
}
else // 模式值为0(表示手动模式/关闭自动)
{
g_Modes_witch = 0; // 更新全局模式变量为手动模式
g_pwm_DutyCycle = 0; // 同时关闭LED(手动模式初始状态)
}
}
// 根据亮度设置参数调整LED亮度
if (Brightness_set != NULL) // 仅当JSON中包含"Brightness_set"字段时处理
{
if (Brightness_set->valueint) // 亮度值有效(非0)
{
g_Brightness_set = Brightness_set->valueint; // 更新全局亮度设置变量
g_pwm_DutyCycle = Brightness_set->valueint; // 直接设置PWM占空比(控制亮度)
g_Low_bright = Brightness_set->valueint; // 更新低亮度阈值(可能用于自动模式)
}
}
// 根据光感阈值参数设置光感检测阈值
if (light_threshold != NULL) // 仅当JSON中包含"light_threshold"字段时处理
{
if (light_threshold->valueint) // 阈值有效(非0)
{
g_light_thres_low = light_threshold->valueint; // 更新全局光感低阈值变量
}
}
// 应用PWM占空比设置(硬件层面更新LED亮度)
PWM_SetCompare1(g_pwm_DutyCycle);
// 构建回复云平台的JSON消息(包含原消息id和成功状态)
pubmessage.qos = QOS0; // 设置MQTT消息的QoS等级为0(最多一次)
// 格式化回复消息,包含消息标识id和处理结果(200表示成功)
sprintf(replymsg, "{\"id\":\"%s\",\"code\":200,\"msg\":\"success\"}", id->valuestring);
printf("reply:%s\r\n", replymsg); // 打印回复消息用于调试
// 设置MQTT发布消息的负载(内容)及长度
pubmessage.payload = replymsg;
pubmessage.payloadlen = strlen(replymsg);
// 通过MQTT协议发布回复消息到指定主题
ret = MQTTPublish(&c, mqtt_params.subtopic_reply, &pubmessage);
if (ret != SUCCESSS) // 发布失败
{
run_status = MQTT_ERR; // 更新全局运行状态为MQTT错误
}
else // 发布成功
{
// 打印发布成功的信息(主题和消息内容)
printf("publish:%s,%s\r\n\r\n", mqtt_params.subtopic_reply, (char *)pubmessage.payload);
}
// 释放cJSON对象树,避免内存泄漏
cJSON_Delete(jsondata);
}
/**
* @brief 生成包含传感器数据和设备状态的JSON格式字符串
* @param json_buf 用于存储生成的JSON字符串的缓冲区
* @param buf_len 缓冲区的长度(字节)
* @return 1 - 生成成功;0 - 生成失败(参数无效或缓冲区过小)
* @note 该函数将当前传感器数据(如光照强度、人体检测状态)和设备状态(如LED开关、模式等)
* 格式化为JSON字符串,用于上报到云平台或其他系统
*/
static int generate_sensor_json(char *json_buf, uint16_t buf_len)
{
// 参数校验:缓冲区为空或长度不足(最小需256字节,确保能容纳JSON结构)
if (json_buf == NULL || buf_len < 256)
return 0;
sprintf(json_buf,
"{\"id\":\"123\",\"version\":\"1.0\",\"params\":{"
"\"light\":{\"value\":%d},"
"\"induct\":{\"value\":%s},"
"\"LED\":{\"value\":%s},"
"\"Mode_switch\":{\"value\":%s},"
"\"light_threshold\":{\"value\":%d},"
"\"Brightness_set\":{\"value\":%d}"
"}}",
g_light_Intensity, // 光照强度值(全局变量)
g_is_Person_Detected ? "true" : "false", // 人体检测状态(全局变量)
g_pwm_DutyCycle ? "true" : "false", // LED状态(通过PWM占空比判断)
g_Modes_witch ? "true" : "false", // 工作模式(全局变量)
g_light_thres_low, // 光感阈值(全局变量)
g_Brightness_set // 亮度设置(全局变量)
);
return 1; // 生成成功
}
6.3 Infraed.c分析
该文件实现红外传感器的红外感应功能,核心如下:
初始化:配置开发板的PA3引脚为上拉输入模式。
数据读取:读取经ADC转换滤波之后的数据。
功能:实时监测是否有人员及车辆经过。
#include "adc.h"
#include "bsp_uart.h"
#include "infrared.h"
#include "w55mh32_gpio.h"
#include "w55mh32_rcc.h"
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
/**
* @brief 初始化红外传感器(配置PA3为模拟输入模式)
* @note 红外传感器连接至PA3,复用为ADC输入通道3
*/
void infrared_init(void) {
GPIO_InitTypeDef gpio_init_structure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA时钟
// 配置PA3为模拟输入(用于读取红外传感器的模拟信号)
gpio_init_structure.GPIO_Pin = GPIO_Pin_3;
gpio_init_structure.GPIO_Mode = GPIO_Mode_AIN; // 模拟输入模式
GPIO_Init(GPIOA, &gpio_init_structure);
}
/**
* @brief 获取红外传感器检测结果(基于滤波后的AD值)
* @return 1-检测到物体(AD值<1500),0-未检测到物体(AD值≥1500)
* @note 依赖ADC模块的滤波功能(AD_FilterProcess),需先初始化ADC
*/
uint16_t infrared_get_data(void) {
uint16_t temp_data;
uint16_t temp;
ad_filter_process(); // 执行AD滤波,获取稳定值
temp = ad_filtered_value[0]; // 红外传感器对应ADC通道0的滤波后值
// 根据阈值判断是否检测到物体
if (temp < 1500) {
temp_data = 1; // 检测到物体
} else {
temp_data = 0; // 未检测到物体
}
return temp_data;
}
/**
* @brief 读取红外传感器原始AD值(未经过滤波)
* @return 原始AD采样值(直接取自ADC原始缓冲区)
*/
uint16_t infrared_read_raw(void) {
return ad_value[0]; // 红外传感器对应ADC通道0的原始值
}
6.4 light.c分析
该文件实现光照传感器的数据采集及灯光处理功能,核心如下:
初始化配置:使能GPIOA,将 PA4配置为模拟输入模式。
数据读取与转换:函数读取经ADC转换滤波之后的数值,通过取倒数并乘以500000的方式,转换为一个与光照强度成正比的浮点数,能为系统提供实时光照强度数据。
功能实现:自动模式下当光照强度低于设定的光照阈值时自动开启LED照明,初始亮度设定为20%(初始亮度可通过网页端调节);当红外传感器监测到行人或车辆经过时,LED照明亮度提升至100%,人离开后恢复至20%(10秒后恢复至低亮度),有效实现按需照明并避免资源浪费。在手动控制模式下,网页可直接设置LED的开关状态及亮度。亮度调节由网页端直接下发亮度值指令,无需在设备端中进行额外处理。
#include "PWM.h"
#include "Timer.h"
#include "adc.h"
#include "infrared.h"
#include "light.h"
#include "w55mh32_adc.h"
#include "w55mh32_gpio.h"
#include "w55mh32_rcc.h"
#include <stdbool.h>
#include <stdio.h>
// 灯光控制参数
#define FULL_BRIGHTNESS 100 // 全亮
#define LIGHT_OFF 0 // 关闭灯
/**
* 全局变量(加g_前缀,注明功能和取值范围)
*/
uint16_t g_light_intensity; // 全局光照强度
bool g_is_person_detected = false; // 红外传感器检测状态(true=检测到人员)
uint16_t g_pwm_duty_cycle = 0; // PWM占空比(0-100,控制LED亮度)
uint16_t g_mode_switch = 1; // 模式选择(0=手动模式,1=自动模式)
extern uint16_t g_low_bright; // 自动模式下LED低亮度设置(0-100)
extern uint16_t g_light_thres_low; // 光照阈值下限(用于自动模式判断)
/**
* 静态变量(加s_前缀,注明功能)
*/
static bool s_prev_person_state =
false; // 上一次人体检测状态(用于状态变化判断)
static bool s_delay_active = false; // 延迟状态标志(true=处于延迟阶段)
static uint32_t s_delay_timer = 0; // 延迟计时器(单位:ms,用于10秒延迟逻辑)
/**
* @brief 初始化光照传感器(配置PA4为模拟输入模式)
*/
void light_init(void) {
GPIO_InitTypeDef gpio_init_structure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
gpio_init_structure.GPIO_Pin = GPIO_Pin_4;
gpio_init_structure.GPIO_Mode = GPIO_Mode_AIN; // 模拟输入模式(用于ADC采样)
GPIO_Init(GPIOA, &gpio_init_structure);
}
/**
* @brief 读取光照强度(将AD值转换为物理量)
* @return 光照强度值(通过AD滤波值计算得到)
*/
float read_light_intensity(void) {
ad_filter_process(); // 获取滤波后的AD值
uint16_t raw = ad_filtered_value[1]; // 取通道1的滤波后值
if (raw == 0) {
raw = 1; // 避免除零错误
}
return 500000.0f / (float)raw; // 转换为物理量(公式取决于传感器特性)
}
/**
* @brief 读取光照传感器原始AD值(未滤波)
* @return 原始AD值(通道1的实时采样值)
*/
uint16_t light_read_raw(void) {
return ad_value[1]; // 直接返回通道1的原始AD值
}
/**
* @brief 智能灯光控制逻辑
* @note 自动模式逻辑:
* 1. 低光照:
* - 有人→全亮;无人→延迟10秒后变为微光(微光亮度可调)
* 2. 高光照→关灯
* 3. 其他情况→保持当前亮度
* 手动模式:通过外部指令直接控制,本函数不额外处理
*/
void light_control(void) {
g_light_intensity = (int)read_light_intensity(); // 更新光照强度
g_is_person_detected = infrared_get_data(); // 更新人体检测状态
uint16_t light_thres_high = g_light_thres_low + 50; // 光照阈值上限
if (g_mode_switch) // 自动模式
{
// 人离开(从有到无):激活延迟
if (s_prev_person_state && !g_is_person_detected) {
s_delay_active = true;
s_delay_timer = 10000; // 10秒延迟
}
// 人到来(从无到有):取消延迟
if (!s_prev_person_state && g_is_person_detected) {
s_delay_active = false;
}
// 灯光逻辑处理
if (g_light_intensity <= g_light_thres_low) {
if (g_is_person_detected) {
g_pwm_duty_cycle = FULL_BRIGHTNESS; // 有人→全亮
} else if (s_delay_active) {
g_pwm_duty_cycle = FULL_BRIGHTNESS; // 延迟期间→保持全亮
} else {
g_pwm_duty_cycle = g_low_bright; // 延迟结束→微光
}
} else if (g_light_intensity >= light_thres_high && !g_is_person_detected) {
s_delay_active = false;
g_pwm_duty_cycle = LIGHT_OFF; // 高光照且无人→关灯
}
// 其他情况保持当前亮度
}
// 手动模式:通过外部指令控制,无需处理
s_prev_person_state = g_is_person_detected; // 更新上一次状态
pwm_set_compare1(g_pwm_duty_cycle); // 应用PWM占空比
}
/**
* @brief TIM2中断服务函数(处理延迟计时)
* @note 每1ms触发一次,减少延迟计时器,为0时结束延迟
*/
void TIM2_IRQHandler(void) {
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) {
if (s_delay_active && s_delay_timer > 0) {
s_delay_timer--;
if (s_delay_timer == 0) {
s_delay_active = false; // 延迟结束
}
}
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除中断标志
}
}
6.5 PWM.C分析
初始化配置完成之后可通过pwm_set_compare1函数动态修改占空比 ,当compare=0时,LED完全熄灭;compare=100时,LED最亮。
#include "w55mh32_adc.h"
#include "w55mh32_gpio.h"
#include "w55mh32_rcc.h"
/**
* @brief 初始化PWM模块(TIM5定时器+PA0引脚)
* @note 配置步骤:
* 1. 使能TIM5和GPIOA时钟
* 2. 配置PA0为复用推挽输出(PWM信号输出)
* 3. 初始化TIM5:向上计数,周期100(0-99),分频2160(生成100kHz时钟)
* 4. 配置TIM5通道1为PWM1模式,初始占空比0
* 5. 使能TIM5定时器
*/
void pwm_init(void) {
// 使能TIM5和GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置PA0为复用推挽输出(PWM输出)
GPIO_InitTypeDef gpio_init_structure;
gpio_init_structure.GPIO_Mode = GPIO_Mode_AF_PP;
gpio_init_structure.GPIO_Pin = GPIO_Pin_0;
gpio_init_structure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio_init_structure);
// 配置TIM5内部时钟
TIM_InternalClockConfig(TIM5);
// 初始化TIM5时基参数
TIM_TimeBaseInitTypeDef tim_time_base_init_structure;
tim_time_base_init_structure.TIM_ClockDivision = TIM_CKD_DIV1;
tim_time_base_init_structure.TIM_CounterMode = TIM_CounterMode_Up;
tim_time_base_init_structure.TIM_Period = 100 - 1; // 周期100(0-99)
tim_time_base_init_structure.TIM_Prescaler =
2160 - 1; // 分频2180(216MHz/2160=100kHz)
tim_time_base_init_structure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM5, &tim_time_base_init_structure);
// 配置TIM5通道1为PWM模式
TIM_OCInitTypeDef tim_oc_init_structure;
TIM_OCStructInit(&tim_oc_init_structure); // 初始化默认参数
tim_oc_init_structure.TIM_OCMode =
TIM_OCMode_PWM1; // PWM1模式(计数器<比较值时输出有效)
tim_oc_init_structure.TIM_OCPolarity = TIM_OCPolarity_High; // 有效电平为高
tim_oc_init_structure.TIM_OutputState = TIM_OutputState_Enable; // 使能输出
tim_oc_init_structure.TIM_Pulse = 0; // 初始占空比0
TIM_OC1Init(TIM5, &tim_oc_init_structure);
// 使能TIM5定时器
TIM_Cmd(TIM5, ENABLE);
}
/**
* @brief 设置TIM5通道1的PWM占空比
* @param compare:占空比数值(0-100,对应0%-100%)
* @note 直接修改比较寄存器值,实时更新PWM输出
*/
void pwm_set_compare1(uint16_t compare){
TIM_SetCompare1(TIM5, compare);
}
7 功能验证
程序烧录完毕,硬件连接完成如下图
1.硬件连接完毕,上电通过串口助手打印如下信息:
2.通过串口每5S采集一次数据发送到云平台,自动模式下当我们遮挡光照传感器时,光照强度数值越来越小。当光照强度小于设定阈值时LED灯点亮。移除遮挡光照强度大于设定阈值时LED灯熄灭。手动模式下,我们可通过网页端手动控制LED灯的开关状态及亮度。
自动模式:
手动模式:
3.自动模式下当光照强度低于设定的光照阈值时,LED 灯自动点亮。此时红外传感器检测到遮挡信号后,LED 灯亮度提升至 100%;移除遮挡后,系统 10 秒后恢复亮度至低亮模式,该模式下 LED 灯亮度可通过网页端调节。
完整演示视频链接:https://www.bilibili.com/video/BV1gJtqzVEtD
8 总结
本系统以 W55MH32Q 开发板为核心控制中枢,集成红外传感器、光照传感器及 LED 照明模块,通过 MQTT 协议与 OneNET 云平台构建完整物联网通信链路,最终实现了动态模式切换、远程控制的智能LED灯控制系统。后续将会依据W55MH32Q芯片制作智能路灯系统的PCB板及其公模外壳,制作完成后我会继续更新,希望大家捧场,同时感谢大家阅读,如果有疑问可以在评论区留言,我会进行解答,为你的开发提供帮助。