聽(tīng)說(shuō)隔壁班的程序員給女友做了個(gè)智能風(fēng)扇
智能風(fēng)扇是一款常見(jiàn)的智能設(shè)備,用戶可以使用手機(jī) App 輕松控制,通過(guò)遠(yuǎn)程控制開(kāi)關(guān)、風(fēng)速、場(chǎng)景聯(lián)動(dòng)等來(lái)輕松創(chuàng)造出溫暖、放松、舒適的室內(nèi)空間。本教程采用 Keil5 進(jìn)行編程,基于涂鴉 IoT 平臺(tái)和三明治 BLDC 功能板,介紹如何快速開(kāi)發(fā)一款安全性強(qiáng)的智能風(fēng)扇的原型。
方案介紹
MCU 方案與 SoC 方案不同,傳感器和聯(lián)網(wǎng)模組的驅(qū)動(dòng)代碼寫(xiě)在 MCU 中,您可以自己開(kāi)發(fā) MCU 代碼,擁有更多的可玩性。
涂鴉三明治開(kāi)發(fā)板 BLDC 套件中,BLDC 板通過(guò) PWM 接口接收 NUCLEO-G071RB 傳過(guò)來(lái)的 PWM,BLDC 板通過(guò)接收到的 PWM 的占空比的大小對(duì)電機(jī)進(jìn)行驅(qū)動(dòng)。MCU 控制板通過(guò)串口 與 Wi-Fi 通信板連接,使用涂鴉智能 App 配網(wǎng),可以將BLDC板的輸出參數(shù)狀態(tài)展現(xiàn)在手機(jī)端。MCU 型號(hào)為 STM32G071RB。
相關(guān)信息
只需簡(jiǎn)單的外圍處理便可實(shí)現(xiàn)高效率的 FOC 電機(jī)驅(qū)動(dòng)。FU6832 的有感啟動(dòng)無(wú)感運(yùn)行FOC驅(qū)動(dòng)主要應(yīng)用在各類低壓風(fēng)機(jī)上,典型應(yīng)用如落地扇、空氣凈化器等。
注意:雖然 BLDC 功能板支持串口,按鍵和PWM控制,但是 MCU 控制板和 Wi-Fi 通信板通過(guò)右下角串口通信,為了減少對(duì) BLDC 控制的影響,該功能板默認(rèn)是只支持 PWM 控制的。
BLDC 板的采樣頻率是 12M,通過(guò) PWM 占空比的大小來(lái)控制電機(jī)轉(zhuǎn)速的,輸入 PWM 占空比越大轉(zhuǎn)速越快。PWM 占空比越大轉(zhuǎn)速越快,本教程中預(yù)設(shè)的輸出頻率為 1000HZ。
開(kāi)機(jī) PWM 占空比:0.08,大于該占空比時(shí)開(kāi)機(jī)
關(guān)機(jī) PWM 占空比:0.06,小于該占空比關(guān)機(jī)(停機(jī)占空比不要設(shè)置為改變轉(zhuǎn)向占空比區(qū)間內(nèi))
改變轉(zhuǎn)向的 PWM 占空比:0.01~0.025,處于該占空比則停機(jī)改變方向
PWM 輸出極性(Polarity)為低(LOW)
PWM配置示例(主頻 16M)如下圖所示:
物料清單
硬件 (4)
涂鴉三明治 Wi-Fi MCU 通信板(WB3S)
數(shù)量:1
板載涂鴉 WB3S 模組,負(fù)責(zé)智能化連接。模組已燒錄通用固件,MCU 對(duì)接涂鴉串口協(xié)議,即可使用涂鴉模組、App、云一站式智能化服務(wù)。
涂鴉三明治BLDC電機(jī)驅(qū)動(dòng)功能板
數(shù)量:1
負(fù)責(zé)通過(guò)判斷接收到的 PWM 的占空比大小進(jìn)行對(duì)電機(jī)的控制。
涂鴉三明治直流供電電源板
數(shù)量:1
用標(biāo)準(zhǔn)的 Arduino 外形尺寸,您可以直接將相應(yīng)的開(kāi)發(fā)板堆疊在上方進(jìn)行供電。因?qū)LDC功能板需要 12V,5V,3.3V 電源,使用電源板可以減少排線。
NUCLEO-G071RB
數(shù)量:1
采用 ST 官方 MCU 主控板,負(fù)責(zé)傳感數(shù)據(jù)接收和模組通訊控制。NUCLEO-G071RB 開(kāi)發(fā)板支持 Arduino 接口。
第 1 步:硬件連接和例程環(huán)境
本次使用的涂鴉三明治開(kāi)發(fā)板 BLDC 套件主要包含:
BLDC 功能板
Wi-Fi MCU 通信板
NUCLEO-G071RB
涂鴉直供電源電源板將三明治開(kāi)發(fā)板套件電源板,控制板、通訊板、功能板拼接組裝,實(shí)物效果如下圖。
軟件開(kāi)發(fā)過(guò)程主要基于 Keil5 實(shí)現(xiàn) MCU 與傳感器和模組協(xié)議對(duì)接。首先調(diào)通 MCU 和模組的通訊,可以實(shí)現(xiàn)App配網(wǎng),MCU 數(shù)據(jù)傳輸?shù)紸pp。
第 2 步:創(chuàng)建產(chǎn)品和工程
您可以根據(jù)以下步驟,快速在涂鴉 IoT 平臺(tái)上開(kāi)發(fā)一個(gè)智能風(fēng)扇。
1、進(jìn)入 涂鴉智能IoT平臺(tái)。
2、參考 選品類創(chuàng)建產(chǎn)品 創(chuàng)建一款門磁產(chǎn)品。其中產(chǎn)品屬性如下:
開(kāi)發(fā)方式:自定義方案
聯(lián)網(wǎng)方式:Wi-Fi
功耗類型:標(biāo)準(zhǔn)功耗
3、根據(jù)頁(yè)面提示選擇產(chǎn)品的標(biāo)準(zhǔn)功能和自定義功能。例如,功能選擇為風(fēng)向、風(fēng)速、工作模式、開(kāi)關(guān)等。您還可以對(duì)某一項(xiàng)功能進(jìn)行編輯。例如,如果您選擇了工作模式功能,可以繼續(xù)修改模式為自然風(fēng)和睡眠風(fēng)兩種。
4、選擇您喜歡的面板,第一次開(kāi)始調(diào)試也可以選擇為開(kāi)發(fā)調(diào)試面板,便于調(diào)試,后面也可以更換面板。
5、面板選擇完后,進(jìn)入 硬件開(kāi)發(fā) 階段,在頁(yè)面拉到最下面,下載開(kāi)發(fā)資料。
6、硬件測(cè)試。下載到 MCU 開(kāi)發(fā)包后,使用開(kāi)發(fā)包中的涂鴉模組調(diào)試助手,您可以使用助手模擬 MCU 模式,配合調(diào)試模組通訊板,驗(yàn)證模組是否通訊正常,同時(shí)也可以熟悉涂鴉串口協(xié)議提高對(duì)接效率。確定通信板正常可用的,可以跳過(guò)此步驟。若調(diào)試過(guò)程中對(duì)協(xié)議收發(fā)有疑問(wèn),也可以使用此助手協(xié)助查看正確數(shù)據(jù)交互格式。 使用步驟可參考 涂鴉模組調(diào)試助手使用說(shuō)明。
第 3 步:移植 MCU SDK
本章節(jié)簡(jiǎn)單介紹了移植過(guò)程和功能實(shí)現(xiàn),將 mcu_sdk 中的文件加入工程后,編譯根據(jù)報(bào)錯(cuò)提示,進(jìn)行修改。如需查看詳細(xì)的移植調(diào)試教程,請(qǐng)參考 MCU SDK 移植。
1、如果編譯過(guò)程中發(fā)生錯(cuò)誤 #40: expected an identifier DISABLE = 0 類似的錯(cuò)誤提示,可以包含頭文件#include "stm32f1xx.h來(lái)解決。對(duì)應(yīng)頭文件為實(shí)際芯片型號(hào),例如,一個(gè) G071RB 的芯片可以添加為 #include "stm32g0xx.h。本教程因?yàn)闆](méi)有介紹 Wi-Fi 功能測(cè)試,所以注釋了 WIFI_TEST_ENABLE 的宏。
//#define WIFI_TEST_ENABLE
2、完善uart_transmit_output()函數(shù)。
3、完善uart_receive_input()函數(shù)。
4、在MCUWIFI通信板連接的串口的中斷服務(wù)函數(shù)中添加以下代碼,注意添加頭文件或聲明您用到的函數(shù)。
5、將wifi_uart_service()函數(shù)按照#error中的提示信息處理,處理后注釋掉。
6、將wifi_protocol_init()函數(shù)按照#error中的提示信息處理,處理后注釋掉。
接下來(lái)便是all_data_update()函數(shù),該函數(shù)會(huì)自動(dòng)上報(bào)系統(tǒng)中所有DP信息,您不需要調(diào)用該函數(shù)。
第4 步:定義結(jié)構(gòu)體
定義一個(gè)結(jié)構(gòu)體,用來(lái)記錄電扇的工作狀態(tài)。
//工作模式typedef enum { nature = 0, sleep }fan_mode_t;//正反轉(zhuǎn)typedef enum { forward = 0, reverse }fan_direction_t;//電扇工作狀態(tài)結(jié)構(gòu)體typedef struct { _Bool OnOff; fan_mode_t e_fan_mode; unsigned long speed; fan_direction_t e_fan_direction; }fan_status_t;//電扇狀態(tài)結(jié)構(gòu)體,全局變量fan_status_t gs_fan_status = { .OnOff = FALSE, .e_fan_mode = nature, .speed = 10, .e_fan_direction = forward };
在protocol.c文件中,完善dp_download_switch_handle(),dp_download_mode_handle(),dp_download_fan_speed_handle()和dp_download_fan_direction_handle()這四個(gè)功能處理函數(shù)。
在protocol.c文件的dp_download_switch_handle()函數(shù)中:
static unsigned char dp_download_switch_handle(const unsigned char value[], unsigned short length) { //示例:當(dāng)前DP類型為BOOL unsigned char ret; //0:關(guān)/1:開(kāi) unsigned char switch_1; switch_1 = mcu_get_dp_download_bool(value,length); if(switch_1 == 0) { //開(kāi)關(guān)關(guān) gs_fan_status.OnOff = FALSE; }else { //開(kāi)關(guān)開(kāi) gs_fan_status.OnOff = TRUE; } //處理完DP數(shù)據(jù)后應(yīng)有反饋 ret = mcu_dp_bool_update(DPID_SWITCH,switch_1); if(ret == SUCCESS) return SUCCESS; else return ERROR; }
在protocol.c文件的dp_download_mode_handle()函數(shù)中:
static unsigned char dp_download_mode_handle(const unsigned char value[], unsigned short length){ //示例:當(dāng)前DP類型為ENUM unsigned char ret; unsigned char mode; mode = mcu_get_dp_download_enum(value,length); switch(mode) { case 0: gs_fan_status.e_fan_mode = nature; //自然風(fēng)模式 break; case 1: gs_fan_status.e_fan_mode = sleep; //睡眠風(fēng)模式 break; default: gs_fan_status.e_fan_mode = nature; break; } //處理完DP數(shù)據(jù)后應(yīng)有反饋 ret = mcu_dp_enum_update(DPID_MODE, mode); if(ret == SUCCESS) return SUCCESS; else return ERROR; }
在protocol.c文件的dp_download_fan_speed_handle()函數(shù)中:
static unsigned char dp_download_fan_speed_handle(const unsigned char value[], unsigned short length){ //示例:當(dāng)前DP類型為VALUE unsigned char ret; unsigned long fan_speed; fan_speed = mcu_get_dp_download_value(value,length); /* //VALUE類型數(shù)據(jù)處理 */ gs_fan_status.speed = fan_speed; //將下發(fā)的速度值給全局變量 //處理完DP數(shù)據(jù)后應(yīng)有反饋 ret = mcu_dp_value_update(DPID_FAN_SPEED,fan_speed); if(ret == SUCCESS) return SUCCESS; else return ERROR; }
在protocol.c文件的dp_download_fan_direction_handle()函數(shù)中:
static unsigned char dp_download_fan_direction_handle(const unsigned char value[], unsigned short length){ //示例:當(dāng)前DP類型為ENUM unsigned char ret; unsigned char fan_direction; fan_direction = mcu_get_dp_download_enum(value,length); switch(fan_direction) { case 0: //判斷當(dāng)前風(fēng)向是否為正轉(zhuǎn),當(dāng)前風(fēng)向若不是正轉(zhuǎn),則改變風(fēng)向,并將當(dāng)前狀態(tài)給全局變量 if(gs_fan_status.e_fan_direction != forward) { change_fan_direction(); gs_fan_status.e_fan_direction = forward; } break; case 1: //判斷當(dāng)前風(fēng)向是否為反轉(zhuǎn),當(dāng)前風(fēng)向若不是反轉(zhuǎn),則改變風(fēng)向,并將當(dāng)前狀態(tài)給全局變量 if(gs_fan_status.e_fan_direction != reverse) { change_fan_direction(); gs_fan_status.e_fan_direction = reverse; } break; default: break; } //處理完DP數(shù)據(jù)后應(yīng)有反饋 ret = mcu_dp_enum_update(DPID_FAN_DIRECTION, fan_direction); if(ret == SUCCESS) return SUCCESS; else return ERROR; }
第 5 步:功能實(shí)現(xiàn)
在main.c文件中,添加頭文件#include "mcu_api.h"和#include “wifi.h”,定義以下宏和變量:
//最小速度時(shí),輸出的PWM占空比#define MIN_SPEED 10//最大速度時(shí),輸出的PWM占空比//最大速度輸出的PWM占空比應(yīng)該為100(建議最大設(shè)置為99),我這里因?yàn)檠菔驹O(shè)置較低#define MAX_SPEED 35//關(guān)機(jī)輸出占空比#define OFF_SPEED 5//改變風(fēng)扇轉(zhuǎn)向輸出的PWM值,在BLDC開(kāi)發(fā)板中輸出PWM在1%~2.5%之間改變電機(jī)轉(zhuǎn)向#define DIRECTION_CHANGE_PWM 15//睡眠模式下,風(fēng)速改變時(shí)間#define SLEEP_TIME 700//上一次風(fēng)扇速度,全局變量unsigned long last_fan_speed = 0;//風(fēng)速sleep模式下,改變風(fēng)速計(jì)數(shù)值和風(fēng)速改變標(biāo)志,全局變量unsigned long fen_count = SLEEP_TIME;_Bool sleep_speed_flag = TRUE;
啟動(dòng)后,進(jìn)入while(1){}循環(huán)前需處理的:
void setup(void) { //優(yōu)先輸出頻率為1000HZ,占空比為5%,使電機(jī)處于關(guān)機(jī)狀態(tài) HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2); __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (OFF_SPEED * 10)); //打開(kāi)與涂鴉三明治 Wi-Fi MCU 通信板(E3S)通信的UART1接收中斷 __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); //完成wifi協(xié)議初始化 wifi_protocol_init(); }
在while(1){}循環(huán)內(nèi):
while (1) { //wifi串口數(shù)據(jù)處理服務(wù) wifi_uart_service(); //進(jìn)入配網(wǎng)模式,并改變LED燈狀態(tài)進(jìn)行提示 connect_tuya(); if (gs_fan_status.OnOff == TRUE) { //開(kāi)機(jī) //判斷工作模式 check_mode(); } else { set_fan_speed(0); } } ``` 在connect_tuya()函數(shù)中: ```objectivec//該函數(shù)主要功能為:當(dāng)PC3被拉低后,進(jìn)入配網(wǎng)模式。根據(jù)不同聯(lián)網(wǎng)狀態(tài),改變LED燈狀態(tài)進(jìn)行提示。void connect_tuya(void) { //判斷PC3是否拉低 if (HAL_GPIO_ReadPin(WIFI_KEY_GPIO_Port, WIFI_KEY_Pin) == GPIO_PIN_RESET) { HAL_Delay(300); if (HAL_GPIO_ReadPin(WIFI_KEY_GPIO_Port, WIFI_KEY_Pin) == GPIO_PIN_RESET) { mcu_set_wifi_mode(0); } } //獲取當(dāng)前連接狀態(tài),顯示LED提示 switch(mcu_get_wifi_work_state()) { case SMART_CONFIG_STATE: //SMART配網(wǎng)模式,快閃 HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin); HAL_Delay(250); break; case AP_STATE: //AP配網(wǎng)模式,快閃 HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin); HAL_Delay(250); break; case WIFI_NOT_CONNECTED: //慢閃 HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin); HAL_Delay(250); break; case WIFI_CONNECTED://常亮,連接到WIFI case WIFI_CONN_CLOUD://常亮,連接到WIFI和云平臺(tái) HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET); break; default: HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET); break; } }
在set_fan_speed()函數(shù)中:
//該函數(shù)主要功能為:根據(jù)不同轉(zhuǎn)速,輸出對(duì)應(yīng)的PWM。PWM頻率為1000HZ。void set_fan_speed(unsigned long speed) { //輸入為0,關(guān)閉電機(jī) if (speed == 0) { __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (OFF_SPEED * 10)); last_fan_speed = OFF_SPEED; //將當(dāng)前轉(zhuǎn)速,記錄下來(lái) return; } //判斷輸入值是否超出最大,最小值 if (speed < MIN_SPEED) { __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (MIN_SPEED * 10)); last_fan_speed = MIN_SPEED; } else if (speed > MAX_SPEED) { __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (MAX_SPEED * 10)); last_fan_speed = MAX_SPEED; } else { __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (speed * 10)); last_fan_speed = speed; } return; } 在check_mode()函數(shù)中:void check_mode(void) { if (gs_fan_status.e_fan_mode == sleep) { //進(jìn)入睡眠模式 if ((sleep_speed_flag == TRUE) && (fen_count >= SLEEP_TIME)) { set_fan_speed(gs_fan_status.speed); //計(jì)數(shù)清零,改變風(fēng)速 fen_count = 0; sleep_speed_flag = FALSE; } else if((sleep_speed_flag == FALSE) && (fen_count >= SLEEP_TIME)) { set_fan_speed(MIN_SPEED); //計(jì)數(shù)清零,改變風(fēng)速 fen_count = 0; sleep_speed_flag = TRUE; } fen_count++; HAL_Delay(10); } else { if (last_fan_speed != gs_fan_status.speed) { //如果上一次轉(zhuǎn)速和目標(biāo)轉(zhuǎn)速不一致,改變轉(zhuǎn)速 set_fan_speed(gs_fan_status.speed); } } }
小結(jié)
基于涂鴉智能平臺(tái), 使用三明治開(kāi)發(fā)板,Keil開(kāi)發(fā)環(huán)境您可以快速地開(kāi)發(fā)一款智能風(fēng)扇產(chǎn)品的原型。
還等什么?
auth.tuya.com/?from=https%3A%2F%2Fiot.tuya.com%2F&_source=5da300e50745947aec50c44f209c5367 |
更多信息
BLDC 功能板采用 FU6832s 作為主控芯片,F(xiàn)U6832 系列是一款集成電機(jī)控制引擎(ME)和 8051 內(nèi)核的高性能電機(jī)驅(qū)動(dòng)專用芯片,ME 集成FOC、MDU、LPF、PI、SVPWM/SPWM 等諸多硬件模組,可硬件自動(dòng)完成電機(jī) FOC/BLDC運(yùn)算控制。8051 內(nèi)核用于參數(shù)配置和日常事務(wù)處理,雙核并行工作實(shí)現(xiàn)各種高性能電機(jī)控制。其中8051 內(nèi)核大部分指令周期為 1T 或 2T,芯片內(nèi)部集成有高速運(yùn)算放大器、比較器、Pre-driver、高速 ADC、高速乘/除法器、CRC、SPI、I2C、UART、LIN、多種 TIMER、PWM 等功能,內(nèi)置高壓 LDO,適用于 BLDC/PMSM 電機(jī)的方波、SVPWM/SPWM、FOC 驅(qū)動(dòng)控制。
FU6832 內(nèi)部具有全面保護(hù),包括過(guò)壓保護(hù),欠壓保護(hù), 過(guò)流保護(hù),F(xiàn)O保護(hù),堵轉(zhuǎn)保護(hù),缺相保護(hù),過(guò)溫保護(hù),過(guò)功率保護(hù),運(yùn)放偏置電壓異常保護(hù)。可根據(jù)需要選擇使能對(duì)應(yīng)的保護(hù),再根據(jù)實(shí)際情況微調(diào)。
快來(lái)做出你的創(chuàng)意叭,推薦平臺(tái)如下,親測(cè)有效:
https://auth.tuya.com/?_source=7c8653b7bd61bf9239a1a6c12e52124d
*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。