飞道的博客

听说隔壁班的程序员给女友做了个智能风扇!

358人阅读  评论(0)

智能风扇是一款常见的智能设备,用户可以使用手机 App 轻松控制,通过远程控制开关、风速、场景联动等来轻松创造出温暖、放松、舒适的室内空间。本教程采用 Keil5 进行编程,基于涂鸦 IoT 平台和三明治 BLDC 功能板,介绍如何快速开发一款安全性强的智能风扇的原型。

方案介绍

MCU 方案与 SoC 方案不同,传感器和联网模组的驱动代码写在 MCU 中,您可以自己开发 MCU 代码,拥有更多的可玩性。

涂鸦三明治开发板 BLDC 套件中,BLDC 板通过 PWM 接口接收 NUCLEO-G071RB 传过来的 PWM,BLDC 板通过接收到的 PWM 的占空比的大小对电机进行驱动。MCU 控制板通过串口 与 Wi-Fi 通信板连接,使用涂鸦智能 App 配网,可以将BLDC板的输出参数状态展现在手机端。MCU 型号为 STM32G071RB。

相关信息

只需简单的外围处理便可实现高效率的 FOC 电机驱动。FU6832 的有感启动无感运行FOC驱动主要应用在各类低压风机上,典型应用如落地扇、空气净化器等。

注意:虽然 BLDC 功能板支持串口,按键和PWM控制,但是 MCU 控制板和 Wi-Fi 通信板通过右下角串口通信,为了减少对 BLDC 控制的影响,该功能板默认是只支持 PWM 控制的。

BLDC 板的采样频率是 12M,通过 PWM 占空比的大小来控制电机转速的,输入 PWM 占空比越大转速越快。PWM 占空比越大转速越快,本教程中预设的输出频率为 1000HZ。

  • 开机 PWM 占空比:0.08,大于该占空比时开机
  • 关机 PWM 占空比:0.06,小于该占空比关机(停机占空比不要设置为改变转向占空比区间内)
  • 改变转向的 PWM 占空比:0.01~0.025,处于该占空比则停机改变方向
  • PWM 输出极性(Polarity)为低(LOW)

PWM配置示例(主频 16M)如下图所示:

 

物料清单

硬件 (4)

涂鸦三明治 Wi-Fi MCU 通信板(WB3S)

数量:1

板载涂鸦 WB3S 模组,负责智能化连接。模组已烧录通用固件,MCU 对接涂鸦串口协议,即可使用涂鸦模组、App、云一站式智能化服务。

涂鸦三明治BLDC电机驱动功能板

数量:1

负责通过判断接收到的 PWM 的占空比大小进行对电机的控制。

涂鸦三明治直流供电电源板

数量:1

用标准的 Arduino 外形尺寸,您可以直接将相应的开发板堆叠在上方进行供电。因对BLDC功能板需要 12V,5V,3.3V 电源,使用电源板可以减少排线。

NUCLEO-G071RB

数量:1

采用 ST 官方 MCU 主控板,负责传感数据接收和模组通讯控制。NUCLEO-G071RB 开发板支持 Arduino 接口。

  • 第 1 步:硬件连接和例程环境

本次使用的涂鸦三明治开发板 BLDC 套件主要包含:

BLDC 功能板

Wi-Fi MCU 通信板

NUCLEO-G071RB

涂鸦直供电源电源板将三明治开发板套件电源板,控制板、通讯板、功能板拼接组装,实物效果如下图。

 

软件开发过程主要基于 Keil5 实现 MCU 与传感器和模组协议对接。首先调通 MCU 和模组的通讯,可以实现App配网,MCU 数据传输到App。

  • 第 2 步:创建产品和工程

您可以根据以下步骤,快速在涂鸦 IoT 平台上开发一个智能风扇。

1、进入 涂鸦智能IoT平台。

2、参考 选品类创建产品 创建一款门磁产品。其中产品属性如下:

开发方式:自定义方案

联网方式:Wi-Fi

功耗类型:标准功耗

 


3、根据页面提示选择产品的标准功能和自定义功能。例如,功能选择为风向、风速、工作模式、开关等。您还可以对某一项功能进行编辑。例如,如果您选择了工作模式功能,可以继续修改模式为自然风和睡眠风两种。

 

4、选择您喜欢的面板,第一次开始调试也可以选择为开发调试面板,便于调试,后面也可以更换面板。

5、面板选择完后,进入 硬件开发 阶段,在页面拉到最下面,下载开发资料。

 

6、硬件测试。下载到 MCU 开发包后,使用开发包中的涂鸦模组调试助手,您可以使用助手模拟 MCU 模式,配合调试模组通讯板,验证模组是否通讯正常,同时也可以熟悉涂鸦串口协议提高对接效率。确定通信板正常可用的,可以跳过此步骤。若调试过程中对协议收发有疑问,也可以使用此助手协助查看正确数据交互格式。 使用步骤可参考 涂鸦模组调试助手使用说明。

  • 第 3 步:移植 MCU SDK

本章节简单介绍了移植过程和功能实现,将 mcu_sdk 中的文件加入工程后,编译根据报错提示,进行修改。如需查看详细的移植调试教程,请参考 MCU SDK 移植。

1、如果编译过程中发生错误 #40: expected an identifier DISABLE = 0 类似的错误提示,可以包含头文件#include "stm32f1xx.h来解决。对应头文件为实际芯片型号,例如,一个 G071RB 的芯片可以添加为 #include "stm32g0xx.h。本教程因为没有介绍 Wi-Fi 功能测试,所以注释了 WIFI_TEST_ENABLE 的宏。

//#define         WIFI_TEST_ENABLE

2、完善uart_transmit_output()函数。

 

3、完善uart_receive_input()函数。

 

4、在MCUWIFI通信板连接的串口的中断服务函数中添加以下代码,注意添加头文件或声明您用到的函数。

 

5、将wifi_uart_service()函数按照#error中的提示信息处理,处理后注释掉。

 

6、将wifi_protocol_init()函数按照#error中的提示信息处理,处理后注释掉。

 

接下来便是all_data_update()函数,该函数会自动上报系统中所有DP信息,您不需要调用该函数。

第4 步:定义结构体

定义一个结构体,用来记录电扇的工作状态。


  
  1. //工作模式
  2. typedef enum {
  3. nature = 0,
  4. sleep
  5. } fan_mode_t;
  6. //正反转
  7. typedef enum {
  8. forward = 0,
  9. reverse
  10. } fan_direction_t;
  11. //电扇工作状态结构体
  12. typedef struct {
  13. _Bool OnOff;
  14. fan_mode_t e_fan_mode;
  15. unsigned long speed;
  16. fan_direction_t e_fan_direction;
  17. } fan_status_t;
  18. //电扇状态结构体,全局变量
  19. fan_status_t gs_fan_status = {
  20. .OnOff = FALSE,
  21. .e_fan_mode = nature,
  22. .speed = 10,
  23. .e_fan_direction = forward
  24. };

在protocol.c文件中,完善dp_download_switch_handle(),dp_download_mode_handle(),dp_download_fan_speed_handle()和dp_download_fan_direction_handle()这四个功能处理函数。
在protocol.c文件的dp_download_switch_handle()函数中:


  
  1. static unsigned char dp_download_switch_handle( const unsigned char value[], unsigned short length)
  2. {
  3. //示例:当前DP类型为BOOL
  4. unsigned char ret;
  5. //0:关/1:开
  6. unsigned char switch_1;
  7. switch_1 = mcu_get_dp_download_bool(value,length);
  8. if(switch_1 == 0) {
  9. //开关关
  10. gs_fan_status.OnOff = FALSE;
  11. } else {
  12. //开关开
  13. gs_fan_status.OnOff = TRUE;
  14. }
  15. //处理完DP数据后应有反馈
  16. ret = mcu_dp_bool_update(DPID_SWITCH,switch_1);
  17. if(ret == SUCCESS)
  18. return SUCCESS;
  19. else
  20. return ERROR;
  21. }

在protocol.c文件的dp_download_mode_handle()函数中:


  
  1. static unsigned char dp_download_mode_handle(const unsigned char value[], unsigned short length)
  2. {
  3. //示例:当前DP类型为ENUM
  4. unsigned char ret;
  5. unsigned char mode;
  6. mode = mcu_get_dp_download_enum(value,length);
  7. switch(mode) {
  8. case 0:
  9. gs_fan_status.e_fan_mode = nature; //自然风模式
  10. break;
  11. case 1:
  12. gs_fan_status.e_fan_mode = sleep; //睡眠风模式
  13. break;
  14. default:
  15. gs_fan_status.e_fan_mode = nature;
  16. break;
  17. }
  18. //处理完DP数据后应有反馈
  19. ret = mcu_dp_enum_update(DPID_MODE, mode);
  20. if(ret == SUCCESS)
  21. return SUCCESS;
  22. else
  23. return ERROR;
  24. }

在protocol.c文件的dp_download_fan_speed_handle()函数中:


  
  1. static unsigned char dp_download_fan_speed_handle(const unsigned char value[], unsigned short length)
  2. {
  3. //示例:当前DP类型为VALUE
  4. unsigned char ret;
  5. unsigned long fan_speed;
  6. fan_speed = mcu_get_dp_download_value(value,length);
  7. /*
  8. //VALUE类型数据处理
  9. */
  10. gs_fan_status.speed = fan_speed; //将下发的速度值给全局变量
  11. //处理完DP数据后应有反馈
  12. ret = mcu_dp_value_update(DPID_FAN_SPEED,fan_speed);
  13. if(ret == SUCCESS)
  14. return SUCCESS;
  15. else
  16. return ERROR;
  17. }

在protocol.c文件的dp_download_fan_direction_handle()函数中:


  
  1. static unsigned char dp_download_fan_direction_handle(const unsigned char value[], unsigned short length)
  2. {
  3. //示例:当前DP类型为ENUM
  4. unsigned char ret;
  5. unsigned char fan_direction;
  6. fan_direction = mcu_get_dp_download_enum(value,length);
  7. switch(fan_direction) {
  8. case 0: //判断当前风向是否为正转,当前风向若不是正转,则改变风向,并将当前状态给全局变量
  9. if(gs_fan_status.e_fan_direction != forward) {
  10. change_fan_direction();
  11. gs_fan_status.e_fan_direction = forward;
  12. }
  13. break;
  14. case 1: //判断当前风向是否为反转,当前风向若不是反转,则改变风向,并将当前状态给全局变量
  15. if(gs_fan_status.e_fan_direction != reverse) {
  16. change_fan_direction();
  17. gs_fan_status.e_fan_direction = reverse;
  18. }
  19. break;
  20. default:
  21. break;
  22. }
  23. //处理完DP数据后应有反馈
  24. ret = mcu_dp_enum_update(DPID_FAN_DIRECTION, fan_direction);
  25. if(ret == SUCCESS)
  26. return SUCCESS;
  27. else
  28. return ERROR;
  29. }

第 5 步:功能实现

在main.c文件中,添加头文件#include "mcu_api.h"和#include “wifi.h”,定义以下宏和变量:


  
  1. //最小速度时,输出的PWM占空比
  2. #define MIN_SPEED 10
  3. //最大速度时,输出的PWM占空比
  4. //最大速度输出的PWM占空比应该为100(建议最大设置为99),我这里因为演示设置较低
  5. #define MAX_SPEED 35
  6. //关机输出占空比
  7. #define OFF_SPEED 5
  8. //改变风扇转向输出的PWM值,在BLDC开发板中输出PWM在1%~2.5%之间改变电机转向
  9. #define DIRECTION_CHANGE_PWM 15
  10. //睡眠模式下,风速改变时间
  11. #define SLEEP_TIME 700
  12. //上一次风扇速度,全局变量
  13. unsigned long last_fan_speed = 0;
  14. //风速sleep模式下,改变风速计数值和风速改变标志,全局变量
  15. unsigned long fen_count = SLEEP_TIME;
  16. _Bool sleep_speed_flag = TRUE;

启动后,进入while(1){}循环前需处理的:


  
  1. void setup(void)
  2. {
  3. //优先输出频率为1000HZ,占空比为5%,使电机处于关机状态
  4. HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
  5. __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (OFF_SPEED * 10));
  6. //打开与涂鸦三明治 Wi-Fi MCU 通信板(E3S)通信的UART1接收中断
  7. __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
  8. //完成wifi协议初始化
  9. wifi_protocol_init();
  10. }

在while(1){}循环内:


  
  1. while ( 1)
  2. {
  3. //wifi串口数据处理服务
  4. wifi_uart_service();
  5. //进入配网模式,并改变LED灯状态进行提示
  6. connect_tuya();
  7. if (gs_fan_status.OnOff == TRUE) { //开机
  8. //判断工作模式
  9. check_mode();
  10. } else {
  11. set_fan_speed( 0);
  12. }
  13. }
  14. ```
  15. connect_tuya()函数中:
  16. ``` objectivec
  17. //该函数主要功能为:当PC3被拉低后,进入配网模式。根据不同联网状态,改变LED灯状态进行提示。
  18. void connect_tuya(void)
  19. {
  20. //判断PC3是否拉低
  21. if (HAL_GPIO_ReadPin(WIFI_KEY_GPIO_Port, WIFI_KEY_Pin) == GPIO_PIN_RESET) {
  22. HAL_Delay( 300);
  23. if (HAL_GPIO_ReadPin(WIFI_KEY_GPIO_Port, WIFI_KEY_Pin) == GPIO_PIN_RESET) {
  24. mcu_set_wifi_mode( 0);
  25. }
  26. }
  27. //获取当前连接状态,显示LED提示
  28. switch(mcu_get_wifi_work_state())
  29. {
  30. case SMART_CONFIG_STATE: //SMART配网模式,快闪
  31. HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin);
  32. HAL_Delay( 250);
  33. break;
  34. case AP_STATE: //AP配网模式,快闪
  35. HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin);
  36. HAL_Delay( 250);
  37. break;
  38. case WIFI_NOT_CONNECTED: //慢闪
  39. HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin);
  40. HAL_Delay( 250);
  41. break;
  42. case WIFI_CONNECTED: //常亮,连接到WIFI
  43. case WIFI_CONN_CLOUD: //常亮,连接到WIFI和云平台
  44. HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET);
  45. break;
  46. default:
  47. HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET);
  48. break;
  49. }
  50. }


在set_fan_speed()函数中:


  
  1. //该函数主要功能为:根据不同转速,输出对应的PWM。PWM频率为1000HZ。
  2. void set_fan_speed( unsigned long speed)
  3. {
  4. //输入为0,关闭电机
  5. if (speed == 0) {
  6. __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (OFF_SPEED * 10));
  7. last_fan_speed = OFF_SPEED; //将当前转速,记录下来
  8. return;
  9. }
  10. //判断输入值是否超出最大,最小值
  11. if (speed < MIN_SPEED) {
  12. __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (MIN_SPEED * 10));
  13. last_fan_speed = MIN_SPEED;
  14. } else if (speed > MAX_SPEED) {
  15. __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (MAX_SPEED * 10));
  16. last_fan_speed = MAX_SPEED;
  17. } else {
  18. __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (speed * 10));
  19. last_fan_speed = speed;
  20. }
  21. return;
  22. }
  23. ​ 在check_mode()函数中:
  24. void check_mode( void)
  25. {
  26. if (gs_fan_status.e_fan_mode == sleep) { //进入睡眠模式
  27. if ((sleep_speed_flag == TRUE) && (fen_count >= SLEEP_TIME)) {
  28. set_fan_speed(gs_fan_status.speed);
  29. //计数清零,改变风速
  30. fen_count = 0;
  31. sleep_speed_flag = FALSE;
  32. } else if((sleep_speed_flag == FALSE) && (fen_count >= SLEEP_TIME)) {
  33. set_fan_speed(MIN_SPEED);
  34. //计数清零,改变风速
  35. fen_count = 0;
  36. sleep_speed_flag = TRUE;
  37. }
  38. fen_count++;
  39. HAL_Delay( 10);
  40. } else {
  41. if (last_fan_speed != gs_fan_status.speed) { //如果上一次转速和目标转速不一致,改变转速
  42. set_fan_speed(gs_fan_status.speed);
  43. }
  44. }
  45. }

小结

基于涂鸦智能平台, 使用三明治开发板,Keil开发环境您可以快速地开发一款智能风扇产品的原型。

还等什么?

更多信息

BLDC 功能板采用 FU6832s 作为主控芯片,FU6832 系列是一款集成电机控制引擎(ME)和 8051 内核的高性能电机驱动专用芯片,ME 集成FOC、MDU、LPF、PI、SVPWM/SPWM 等诸多硬件模组,可硬件自动完成电机 FOC/BLDC运算控制。8051 内核用于参数配置和日常事务处理,双核并行工作实现各种高性能电机控制。其中8051 内核大部分指令周期为 1T 或 2T,芯片内部集成有高速运算放大器、比较器、Pre-driver、高速 ADC、高速乘/除法器、CRC、SPI、I2C、UART、LIN、多种 TIMER、PWM 等功能,内置高压 LDO,适用于 BLDC/PMSM 电机的方波、SVPWM/SPWM、FOC 驱动控制。

FU6832 内部具有全面保护,包括过压保护,欠压保护, 过流保护,FO保护,堵转保护,缺相保护,过温保护,过功率保护,运放偏置电压异常保护。可根据需要选择使能对应的保护,再根据实际情况微调。


转载:https://blog.csdn.net/weixin_50563088/article/details/111933723
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场