軟硬件開源項目-智能路燈系統(tǒng):OneNET云平臺監(jiān)測+Web網(wǎng)頁控制+代碼解析
智能路燈系統(tǒng)項目下載源碼
本倉庫提供了完整的智能路燈系統(tǒng)項目的源碼,旨在幫助開發(fā)者快速搭建和理解智能路燈系統(tǒng)的實現(xiàn)過程。
項目地址:https://gitee.com/zhu-heyang/w55mh32-smart-street-light.git
1 前言
前兩天晚上出去溜達的時候,路過路燈的時候,感覺燈光很強刺的人睜不開眼,而且那么高的亮度一直亮著也不省電,當時我就想要是我來設計路燈的話可能不會這樣設計,如果是我的話一定會加上一個亮度自適應的功能,沒人的時候就亮度低一點有人的時候就更亮一點人走一會才恢復原來的亮度,而且現(xiàn)在物聯(lián)網(wǎng)那么發(fā)達,應該加上一個遠程控制的功能。于是說干就干,挑硬件時在淘寶上發(fā)現(xiàn)了 W55MH32Q 這款開發(fā)板,它的性能跟我這個項目的需求特別對得上,然后就選擇了這款開發(fā)板,我選它主要有三個原因:
一是自帶以太網(wǎng)功能,無需額外掛載通信模塊,就能穩(wěn)定運行 MQTT 協(xié)議傳輸數(shù)據(jù),省去了模塊兼容調(diào)試的麻煩,數(shù)據(jù)傳輸?shù)目煽啃砸哺斜U稀?br /> 二是接口設計合理,紅外傳感器器和光照傳感器可直接通過標準接口連接,硬件層無需額外電平轉(zhuǎn)換或隔離電路,適配過程很順暢。
三是集成了串口芯片,無需外接 USB 轉(zhuǎn)串口模塊,直接通過串口助手就能打印調(diào)試信息,對嵌入式開發(fā)來說,這種無需外接模塊的調(diào)試支持簡直是太方便了。
以此搭建的系統(tǒng)通過紅外和光照傳感器每 5 秒采集一次環(huán)境數(shù)據(jù),經(jīng)開發(fā)板處理后上傳 OneNET 平臺。自動模式下,光照低于網(wǎng)頁設定閾值時 LED 以 20% 初始亮度開啟(初始亮度可通過網(wǎng)頁端調(diào)節(jié)),紅外檢測到行人 / 車輛即升至 100%,離開 10 秒后恢復低亮;手動模式支持網(wǎng)頁端直接控制LED燈的開關與亮度。開發(fā)板的接口兼容性與網(wǎng)絡穩(wěn)定性保障了系統(tǒng)精準響應與節(jié)能目標。
2 項目環(huán)境
2.1 硬件要求
- W55MH32Q開發(fā)板
- LED燈、光照傳感器、紅外傳感器
- USB Type-C數(shù)據(jù)線
- 路由器
2.2 軟件環(huán)境
3 硬件連接和方案
3.1 系統(tǒng)硬件連接
- LED燈正極連接開發(fā)板A0引腳
- 紅外傳感器數(shù)據(jù)采樣引腳OUT接開發(fā)板A3引腳
- 光照傳感器數(shù)據(jù)采樣引腳AO連接開發(fā)板A4引腳
3.2 方案圖示
4 MQTT連接OneNET云平臺收發(fā)數(shù)據(jù)流程
4.1 準備階段
注冊賬號在這里不進行贅述,下面我們看如何建立物模型。
創(chuàng)建產(chǎn)品和添加物模型:登錄OneNET物聯(lián)網(wǎng)平臺,創(chuàng)建產(chǎn)品并在產(chǎn)品下添加以下物模型功能。
創(chuàng)建設備:在剛剛創(chuàng)建的產(chǎn)品下創(chuàng)建相應設備。
4.2 設備詳情
設備詳情:在設備詳情頁中可以查看設備密鑰和產(chǎn)品ID等重要信息。
4.3 Token 密鑰生成
設備與 OneNet 平臺通信時,Token 作為身份憑證用于安全認證。需使用 Token 生成工具:
OneNET Token 生成工具文檔
- res 字段:
products/{產(chǎn)品id}/devices/{設備名}
(使用設備級 Key)。替換{產(chǎn)品id}
和{設備名}
。 - et 字段: 訪問過期時間 (Unix 時間戳)??墒褂迷诰€轉(zhuǎn)換工具獲取。
- key 字段: 填寫設備的密鑰。
- 點擊
generate
生成 Token 密鑰 。
4.4 連接、訂閱和發(fā)布消息
訂閱主題:$sys/{pid}/{device-name}/thing/property/set
發(fā)布主題:$sys/{pid}/{device-name}/thing/property/post
pid是product_id的簡稱,即產(chǎn)品ID。
device-name是設備名稱。
接著我們可以使用上面記錄的連接參數(shù)進行連接,當連接成功后,訂閱上面的訂閱主題。并通過發(fā)布主題上報物模型數(shù)據(jù)。
在OneNET平臺,如果產(chǎn)品創(chuàng)建階段選擇的數(shù)據(jù)格式為OneJSON格式時,接收和發(fā)送數(shù)據(jù)格式都會遵守下面這個格式:
{
"id": "123",
"version": "1.0",
"params": {
"temperature":"30.5"
}
}
id:值為"123",這是一個唯一的標識符;params是一個包含設備屬性數(shù)據(jù)的對象用于上報物模型數(shù)據(jù);version:值為 "1.0",表示該消息所遵循的協(xié)議版本。
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。 - 修改產(chǎn)品 ID 和設備名: 在
url
中替換product_id
和device_name
參數(shù)為實際值。
- 修改 Token: 替換 const params = {
- 修改完畢后即可通過HBuilder X自帶的發(fā)行功能對文件進行打包,可打包成網(wǎng)頁或者APP根據(jù)需要可自行選擇。
6 主要程序解析
6.1 main.c分析
在主函數(shù)中實現(xiàn)以下軟硬件初始化:配置時鐘、串口、定時器,初始化紅外傳感器、光照傳感器和LED燈。
網(wǎng)絡初始化:配置開發(fā)板和MQTT客戶端,支持DHCP 動態(tài)獲取IP。
數(shù)據(jù)采集與控制:每5秒采集一次光照強度和監(jiān)測紅外感應,調(diào)用LED燈控制函數(shù)。
數(shù)據(jù)上傳:調(diào)用light_control()和do_mqtt()函數(shù)將傳感器數(shù)據(jù)和設備狀態(tài)發(fā)送到云平臺。
#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 examplern", _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協(xié)議實現(xiàn)設備、OneNET云平臺的雙向交互,包括傳感器數(shù)據(jù)(紅外感應、光照、LED燈狀態(tài))上報及命令下發(fā)。
/**
* @brief 解析JSON格式的控制消息,并根據(jù)消息內(nèi)容控制硬件,最后回復處理結(jié)果
* @param msg 待解析的JSON格式字符串,包含控制指令(如LED開關、模式切換等)
* @note 該函數(shù)使用cJSON庫解析JSON,提取相關控制參數(shù)后更新全局變量以控制硬件,
* 并通過MQTT協(xié)議向云平臺回復處理結(jié)果
*/
void json_decode(char *msg)
{
int ret; // 函數(shù)返回值,用于判斷MQTT發(fā)布是否成功
char replymsg[128] = {0}; // 存儲回復云平臺的JSON格式字符串
cJSON *id = NULL; // 指向JSON中"id"字段的cJSON對象(消息標識)
cJSON *jsondata = NULL; // 指向解析后的根cJSON對象
cJSON *params = NULL; // 指向JSON中"params"字段的cJSON對象(參數(shù)集合)
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.rn"); // 解析失?。ㄈ绺袷藉e誤),打印錯誤信息
return;
}
// 從根對象中獲取各字段值
id = cJSON_GetObjectItem(jsondata, "id"); // 獲取消息標識"id"
params = cJSON_GetObjectItem(jsondata, "params"); // 獲取參數(shù)集合"params"
LED = cJSON_GetObjectItem(params, "LED"); // 從params中獲取LED控制參數(shù)
Mode_switch = cJSON_GetObjectItem(params, "Mode_switch"); // 獲取模式切換參數(shù)
Brightness_set = cJSON_GetObjectItem(params, "Brightness_set"); // 獲取亮度設置參數(shù)
light_threshold = cJSON_GetObjectItem(params, "light_threshold"); // 獲取光感閾值參數(shù)
// 根據(jù)LED參數(shù)控制LED開關(通過PWM占空比實現(xiàn))
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關閉)
}
}
// 根據(jù)模式切換參數(shù)切換工作模式
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(手動模式初始狀態(tài))
}
}
// 根據(jù)亮度設置參數(shù)調(diào)整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; // 更新低亮度閾值(可能用于自動模式)
}
}
// 根據(jù)光感閾值參數(shù)設置光感檢測閾值
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和成功狀態(tài))
pubmessage.qos = QOS0; // 設置MQTT消息的QoS等級為0(最多一次)
// 格式化回復消息,包含消息標識id和處理結(jié)果(200表示成功)
sprintf(replymsg, "{"id":"%s","code":200,"msg":"success"}", id- >valuestring);
printf("reply:%srn", replymsg); // 打印回復消息用于調(diào)試
// 設置MQTT發(fā)布消息的負載(內(nèi)容)及長度
pubmessage.payload = replymsg;
pubmessage.payloadlen = strlen(replymsg);
// 通過MQTT協(xié)議發(fā)布回復消息到指定主題
ret = MQTTPublish(&c, mqtt_params.subtopic_reply, &pubmessage);
if (ret != SUCCESSS) // 發(fā)布失敗
{
run_status = MQTT_ERR; // 更新全局運行狀態(tài)為MQTT錯誤
}
else // 發(fā)布成功
{
// 打印發(fā)布成功的信息(主題和消息內(nèi)容)
printf("publish:%s,%srnrn", mqtt_params.subtopic_reply, (char *)pubmessage.payload);
}
// 釋放cJSON對象樹,避免內(nèi)存泄漏
cJSON_Delete(jsondata);
}
/**
* @brief 生成包含傳感器數(shù)據(jù)和設備狀態(tài)的JSON格式字符串
* @param json_buf 用于存儲生成的JSON字符串的緩沖區(qū)
* @param buf_len 緩沖區(qū)的長度(字節(jié))
* @return 1 - 生成成功;0 - 生成失?。▍?shù)無效或緩沖區(qū)過?。? * @note 該函數(shù)將當前傳感器數(shù)據(jù)(如光照強度、人體檢測狀態(tài))和設備狀態(tài)(如LED開關、模式等)
* 格式化為JSON字符串,用于上報到云平臺或其他系統(tǒng)
*/
static int generate_sensor_json(char *json_buf, uint16_t buf_len)
{
// 參數(shù)校驗:緩沖區(qū)為空或長度不足(最小需256字節(jié),確保能容納JSON結(jié)構)
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", // 人體檢測狀態(tài)(全局變量)
g_pwm_DutyCycle ? "true" : "false", // LED狀態(tài)(通過PWM占空比判斷)
g_Modes_witch ? "true" : "false", // 工作模式(全局變量)
g_light_thres_low, // 光感閾值(全局變量)
g_Brightness_set // 亮度設置(全局變量)
);
return 1; // 生成成功
}
6.3 Infraed.c分析
該文件實現(xiàn)紅外傳感器的紅外感應功能,核心如下:
初始化:配置開發(fā)板的PA3引腳為上拉輸入模式。
數(shù)據(jù)讀取:讀取經(jīng)ADC轉(zhuǎn)換濾波之后的數(shù)據(jù)。
功能:實時監(jiān)測是否有人員及車輛經(jīng)過。
#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 獲取紅外傳感器檢測結(jié)果(基于濾波后的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(); // 執(zhí)行AD濾波,獲取穩(wěn)定值
temp = ad_filtered_value[0]; // 紅外傳感器對應ADC通道0的濾波后值
// 根據(jù)閾值判斷是否檢測到物體
if (temp < 1500) {
temp_data = 1; // 檢測到物體
} else {
temp_data = 0; // 未檢測到物體
}
return temp_data;
}
/**
* @brief 讀取紅外傳感器原始AD值(未經(jīng)過濾波)
* @return 原始AD采樣值(直接取自ADC原始緩沖區(qū))
*/
uint16_t infrared_read_raw(void) {
return ad_value[0]; // 紅外傳感器對應ADC通道0的原始值
}
6.4 light.c分析
該文件實現(xiàn)光照傳感器的數(shù)據(jù)采集及燈光處理功能,核心如下:
初始化配置:使能GPIOA,將 PA4配置為模擬輸入模式。
數(shù)據(jù)讀取與轉(zhuǎn)換:函數(shù)讀取經(jīng)ADC轉(zhuǎn)換濾波之后的數(shù)值,通過取倒數(shù)并乘以500000的方式,轉(zhuǎn)換為一個與光照強度成正比的浮點數(shù),能為系統(tǒng)提供實時光照強度數(shù)據(jù)。
功能實現(xiàn):自動模式下當光照強度低于設定的光照閾值時自動開啟LED照明,初始亮度設定為20%(初始亮度可通過網(wǎng)頁端調(diào)節(jié));當紅外傳感器監(jiān)測到行人或車輛經(jīng)過時,LED照明亮度提升至100%,人離開后恢復至20%(10秒后恢復至低亮度),有效實現(xiàn)按需照明并避免資源浪費。在手動控制模式下,網(wǎng)頁可直接設置LED的開關狀態(tài)及亮度。亮度調(diào)節(jié)由網(wǎng)頁端直接下發(fā)亮度值指令,無需在設備端中進行額外處理。
#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 >
// 燈光控制參數(shù)
#define FULL_BRIGHTNESS 100 // 全亮
#define LIGHT_OFF 0 // 關閉燈
/**
* 全局變量(加g_前綴,注明功能和取值范圍)
*/
uint16_t g_light_intensity; // 全局光照強度
bool g_is_person_detected = false; // 紅外傳感器檢測狀態(tài)(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; // 光照閾值下限(用于自動模式判斷)
/**
* 靜態(tài)變量(加s_前綴,注明功能)
*/
static bool s_prev_person_state =
false; // 上一次人體檢測狀態(tài)(用于狀態(tài)變化判斷)
static bool s_delay_active = false; // 延遲狀態(tài)標志(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值轉(zhuǎn)換為物理量)
* @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; // 轉(zhuǎn)換為物理量(公式取決于傳感器特性)
}
/**
* @brief 讀取光照傳感器原始AD值(未濾波)
* @return 原始AD值(通道1的實時采樣值)
*/
uint16_t light_read_raw(void) {
return ad_value[1]; // 直接返回通道1的原始AD值
}
/**
* @brief 智能燈光控制邏輯
* @note 自動模式邏輯:
* 1. 低光照:
* - 有人→全亮;無人→延遲10秒后變?yōu)槲⒐?微光亮度可調(diào))
* 2. 高光照→關燈
* 3. 其他情況→保持當前亮度
* 手動模式:通過外部指令直接控制,本函數(shù)不額外處理
*/
void light_control(void) {
g_light_intensity = (int)read_light_intensity(); // 更新光照強度
g_is_person_detected = infrared_get_data(); // 更新人體檢測狀態(tài)
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; // 延遲結(jié)束→微光
}
} 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; // 更新上一次狀態(tài)
pwm_set_compare1(g_pwm_duty_cycle); // 應用PWM占空比
}
/**
* @brief TIM2中斷服務函數(shù)(處理延遲計時)
* @note 每1ms觸發(fā)一次,減少延遲計時器,為0時結(jié)束延遲
*/
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; // 延遲結(jié)束
}
}
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除中斷標志
}
}
6.5 PWM.C分析
初始化配置完成之后可通過pwm_set_compare1函數(shù)動態(tài)修改占空比 ,當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:向上計數(shù),周期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內(nèi)部時鐘
TIM_InternalClockConfig(TIM5);
// 初始化TIM5時基參數(shù)
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); // 初始化默認參數(shù)
tim_oc_init_structure.TIM_OCMode =
TIM_OCMode_PWM1; // PWM1模式(計數(shù)器< 比較值時輸出有效)
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:占空比數(shù)值(0-100,對應0%-100%)
* @note 直接修改比較寄存器值,實時更新PWM輸出
*/
void pwm_set_compare1(uint16_t compare){
TIM_SetCompare1(TIM5, compare);
}
7 功能驗證
程序燒錄完畢,硬件連接完成如下圖
1.硬件連接完畢,上電通過串口助手打印如下信息:
2.通過串口每5S采集一次數(shù)據(jù)發(fā)送到云平臺,自動模式下當我們遮擋光照傳感器時,光照強度數(shù)值越來越小。當光照強度小于設定閾值時LED燈點亮。移除遮擋光照強度大于設定閾值時LED燈熄滅。手動模式下,我們可通過網(wǎng)頁端手動控制LED燈的開關狀態(tài)及亮度。
3.自動模式下當光照強度低于設定的光照閾值時,LED 燈自動點亮。此時紅外傳感器檢測到遮擋信號后,LED 燈亮度提升至 100%;移除遮擋后,系統(tǒng) 10 秒后恢復亮度至低亮模式,該模式下 LED 燈亮度可通過網(wǎng)頁端調(diào)節(jié)。
完整演示視頻鏈接:[https://www.bilibili.com/video/BV1gJtqzVEtD]
8 總結(jié)
本系統(tǒng)以 W55MH32Q 開發(fā)板為核心控制中樞,集成紅外傳感器、光照傳感器及 LED 照明模塊,通過 MQTT 協(xié)議與 OneNET 云平臺構建完整物聯(lián)網(wǎng)通信鏈路,最終實現(xiàn)了動態(tài)模式切換、遠程控制的智能LED燈控制系統(tǒng)。后續(xù)將會依據(jù)W55MH32Q芯片制作智能路燈系統(tǒng)的PCB板及其公模外殼,制作完成后我會繼續(xù)更新,希望大家捧場,同時感謝大家閱讀,如果有疑問可以在評論區(qū)留言,我會進行解答,為你的開發(fā)提供幫助。
審核編輯 黃宇
-
開源
+關注
關注
3文章
3885瀏覽量
45305 -
智能路燈
+關注
關注
7文章
106瀏覽量
23454 -
OneNET
+關注
關注
1文章
52瀏覽量
13683
發(fā)布評論請先 登錄
單片機軟硬件聯(lián)合仿真解決方案
基于SoPC的狀態(tài)監(jiān)測裝置的嵌入式軟硬件協(xié)同設計
【OneNET麒麟座試用申請】基于OneNET平臺的智慧照明控制系統(tǒng)
機友分享 | 機智云小程序啟蒙:WebSocket網(wǎng)頁控制
基于onenet云平臺MQTT協(xié)議數(shù)據(jù)采集以及遠程控制的個人總結(jié)資料
詳細分析stm32f10x.h
如何對SOA進行軟硬件部署
單片機測控系統(tǒng)的軟硬件平臺技術
智能家居系統(tǒng)的軟硬件設計

機房托管費詳細分析
智能農(nóng)業(yè)監(jiān)控系統(tǒng):MQTT阿里云平臺監(jiān)測+內(nèi)置Web網(wǎng)頁控制+代碼解析

評論