乐趣区

关于开发者:听说隔壁班的程序员给女友做了个智能风扇

智能风扇是一款常见的智能设施,用户能够应用手机 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 步:定义构造体

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

// 工作模式
typedef enum {
    nature = 0,
    sleep
}fan_mode_t;

// 正反转
typedef enum {
    forward = 0,
    reverse
}fan_direction_t;

// 电扇工作状态构造体
typedef struct {
    _Bool OnOff;
    fan_mode_t e_fan_mode;
    unsigned long speed;
    fan_direction_t e_fan_direction;
}fan_status_t;

// 电扇状态构造体,全局变量
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() 这四个性能处理函数。
在 protocol.c 文件的 dp_download_switch_handle() 函数中:

static unsigned char dp_download_switch_handle(const unsigned char value[], unsigned short length)
{
    // 示例: 以后 DP 类型为 BOOL
    unsigned char ret;
    //0: 关 /1: 开
    unsigned char switch_1;
    
    switch_1 = mcu_get_dp_download_bool(value,length);
    if(switch_1 == 0) {
        // 开关关
        gs_fan_status.OnOff = FALSE;
    }else {
        // 开关开
        gs_fan_status.OnOff = TRUE;
    }
  
    // 解决完 DP 数据后应有反馈
    ret = mcu_dp_bool_update(DPID_SWITCH,switch_1);
    if(ret == SUCCESS)
        return SUCCESS;
    else
        return ERROR;
} 

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

static unsigned char dp_download_mode_handle(const unsigned char value[], unsigned short length) {
    // 示例: 以后 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;    // 自然风模式
        break;
        
        case 1:
                    gs_fan_status.e_fan_mode = sleep;    // 睡眠风模式
        break;
        
        default:
                    gs_fan_status.e_fan_mode = nature;
        break;
    }
    
    // 解决完 DP 数据后应有反馈
    ret = mcu_dp_enum_update(DPID_MODE, mode);
    if(ret == SUCCESS)
        return SUCCESS;
    else
        return ERROR;
} 

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

static unsigned char dp_download_fan_speed_handle(const unsigned char value[], unsigned short length) {
    // 示例: 以后 DP 类型为 VALUE
    unsigned char ret;
    unsigned long fan_speed;
    
    fan_speed = mcu_get_dp_download_value(value,length);
    /*
    //VALUE 类型数据处理
    
    */
    gs_fan_status.speed = fan_speed;    // 将下发的速度值给全局变量
    // 解决完 DP 数据后应有反馈
    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() 函数中:

static unsigned char dp_download_fan_direction_handle(const unsigned char value[], unsigned short length) {
    // 示例: 以后 DP 类型为 ENUM
    unsigned char ret;
    unsigned char fan_direction;
    
    fan_direction = mcu_get_dp_download_enum(value,length);
    switch(fan_direction) {
        case 0:        // 判断以后风向是否为正转,以后风向若不是正转,则扭转风向,并将以后状态给全局变量
                    if(gs_fan_status.e_fan_direction != forward) {change_fan_direction();
                        gs_fan_status.e_fan_direction = forward;
                    }
        break;
        
        case 1:        // 判断以后风向是否为反转,以后风向若不是反转,则扭转风向,并将以后状态给全局变量
                    if(gs_fan_status.e_fan_direction != reverse) {change_fan_direction();
                        gs_fan_status.e_fan_direction = reverse;
                    }
        break;
        
        default:
        break;
    }
    
    // 解决完 DP 数据后应有反馈
    ret = mcu_dp_enum_update(DPID_FAN_DIRECTION, fan_direction);
    if(ret == SUCCESS)
        return SUCCESS;
    else
        return ERROR;
}

第 5 步:性能实现

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

// 最小速度时,输入的 PWM 占空比
#define MIN_SPEED    10

// 最大速度时,输入的 PWM 占空比
// 最大速度输入的 PWM 占空比应该为 100(倡议最大设置为 99),我这里因为演示设置较低
#define MAX_SPEED    35

// 关机输入占空比
#define    OFF_SPEED    5

// 扭转风扇转向输入的 PWM 值,在 BLDC 开发板中输入 PWM 在 1%~2.5% 之间扭转电机转向
#define DIRECTION_CHANGE_PWM 15

// 睡眠模式下,风速扭转工夫
#define SLEEP_TIME 700

// 上一次风扇速度,全局变量
unsigned long last_fan_speed = 0;

// 风速 sleep 模式下,扭转风速计数值和风速扭转标记,全局变量
unsigned long fen_count = SLEEP_TIME;
_Bool sleep_speed_flag = TRUE; 

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

void setup(void)
{
    // 优先输入频率为 1000HZ,占空比为 5%,使电机处于关机状态
    HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (OFF_SPEED * 10));
    
    // 关上与涂鸦三明治 Wi-Fi MCU 通信板(E3S)通信的 UART1 接管中断
    __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
    
    // 实现 wifi 协定初始化
    wifi_protocol_init();}

在 while(1){} 循环内:

while (1)
  {
        //wifi 串口数据处理服务
        wifi_uart_service();
        
        // 进入配网模式,并扭转 LED 灯状态进行提醒
        connect_tuya();
        
        if (gs_fan_status.OnOff == TRUE) { // 开机
            // 判断工作模式
            check_mode();} else {set_fan_speed(0);
        }
  }

在 connect_tuya() 函数中:

// 该函数次要性能为:当 PC3 被拉低后,进入配网模式。依据不同联网状态,扭转 LED 灯状态进行提醒。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);
        }
    }
    
    // 获取以后连贯状态,显示 LED 提醒
    switch(mcu_get_wifi_work_state())
    {
                case SMART_CONFIG_STATE:    //SMART 配网模式,快闪
                        HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin);
                        HAL_Delay(250);
                break;
                case AP_STATE:    //AP 配网模式,快闪
                        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 和云平台
                        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() 函数中:

// 该函数次要性能为:依据不同转速,输入对应的 PWM。PWM 频率为 1000HZ。void set_fan_speed(unsigned long speed)
{
    // 输出为 0,敞开电机
    if (speed == 0) {__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (OFF_SPEED * 10));
        last_fan_speed = OFF_SPEED; // 将以后转速,记录下来
        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() 函数中:void check_mode(void) 
{if (gs_fan_status.e_fan_mode == sleep) { // 进入睡眠模式
        if ((sleep_speed_flag == TRUE) && (fen_count >= SLEEP_TIME)) {set_fan_speed(gs_fan_status.speed);
            // 计数清零,扭转风速
            fen_count = 0;
            sleep_speed_flag = FALSE;
        } else if((sleep_speed_flag == FALSE) && (fen_count >= SLEEP_TIME)) {set_fan_speed(MIN_SPEED);

            // 计数清零,扭转风速
            fen_count = 0;
            sleep_speed_flag = TRUE;
        }
        
        fen_count++;
        HAL_Delay(10);
    } else {if (last_fan_speed != gs_fan_status.speed) { // 如果上一次转速和指标转速不统一,扭转转速
                set_fan_speed(gs_fan_status.speed);
        }
    }
}

小结

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

还等什么?

auth.tuya.com/register?from=http%3A%2F%2Fiot.tuya.com%2F&_source=e74d60a1928993e1892f7e5efbaa5467

更多信息

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 爱护,堵转爱护,缺相爱护,过温爱护,过功率爱护,运放偏置电压异样爱护。可依据须要抉择使能对应的爱护,再依据理论状况微调。

退出移动版