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

0次阅读

共计 8169 个字符,预计需要花费 21 分钟才能阅读完成。

智能风扇是一款常见的智能设施,用户能够应用手机 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 爱护,堵转爱护,缺相爱护,过温爱护,过功率爱护,运放偏置电压异样爱护。可依据须要抉择使能对应的爱护,再依据理论状况微调。

正文完
 0