前言

在上一期蓝牙控制中,我们实现了手机在几米范围内控制小灯。但如果你想在公司控制家里的设备,或者想用小爱同学/Siri语音控制,蓝牙就无能为力了。
这时我们需要 Wi-Fi模块。本文将以性价比极高的 ESP-01S 为例,带你理解Wi-Fi通信原理,配置AT指令,并接入 巴法云(Bemfa Cloud),最终利用STM32实现远程控制。


第一部分:核心原理深度剖析

1.1 什么是ESP-01S?

ESP-01S 是基于 ESP8266 芯片的微型模组。

  • 不仅仅是模块:与蓝牙HC-05不同,ESP8266本身就是一颗性能强大的32位MCU。它内部集成了完整的 TCP/IP 协议栈
  • 工作方式:我们通常使用“AT指令固件”版本。此时,STM32通过串口告诉ESP-01S:“连上路由器的Wi-Fi”、“连上那个云服务器”,剩下的复杂网络握手都由ESP-01S内部自动完成。

1.2 三种工作模式

  1. Station模式(STA)(本项目使用)
    • 模块像手机一样连接家里的路由器。连接后,模块就有了IP地址,可以访问互联网。
  2. AP模式(Access Point)
    • 模块自己建立一个Wi-Fi热点,手机连上它。类似于“手机开热点”。
  3. STA + AP模式:同时具备以上两种功能。

1.3 什么是“上云”与MQTT协议?

为了实现远程控制,手机和单片机不能直接对话(因为它们在不同的局域网)。它们需要一个中间人——云服务器(MQTT Broker)
我们采用物联网最主流的 MQTT协议,它的核心机制是 发布/订阅(Pub/Sub)

  • Topic(主题):相当于一个“信箱”,比如 Light001
  • 发布者(手机):向 Light001 信箱投递信件(发送指令“开灯”)。
  • 订阅者(ESP-01S):一直关注着 Light001 信箱,一旦有新信件,立马取出来执行。

第二部分:硬件准备与云平台创建

2.1 硬件避坑指南(至关重要!)

ESP-01S 非常“娇气”,新手90%的问题出在电源上:

  • 电压:必须接 3.3V!接5V瞬间烧毁。
  • 电流:Wi-Fi发送瞬间电流可达300mA以上。严禁直接使用USB-TTL的3.3V引脚供电(通常电流不足导致模块无限重启)。建议使用独立的LDO(如AMS1117-3.3)供电。
  • 引脚
    • VCC/GND:3.3V电源。
    • RX/TX:接单片机/TTL。
    • EN (CH_PD):使能引脚,必须接3.3V模块才工作(ESP-01S通常内部已上拉,但ESP-01老版本必须手动接)。

2.2 注册巴法云(Bemfa Cloud)

为了降低入门难度,我们选择 巴法云(无需复杂的鉴权算法,适合单片机AT指令操作)。

巴法科技&巴法云-巴法设备云-巴法物联网云平台

  1. 访问巴法云官网注册登录。
  2. 进入控制台,获取 私钥 (UID)(非常重要,这是你的身份ID)。
  3. 新建主题:
    • 主题名:LED001
    • 类型:MQTT设备

第三部分:AT指令初始化与联网测试

在写代码前,先用 USB-TTL 连接wifi模块,通过串口助手手动发送指令,验证流程。

  • 波特率:默认通常是 115200

3.1 基础配置流程

  1. 测试指令
    • 发送:AT
    • 返回:OK
  2. 设置工作模式为STA
    • 发送:AT+CWMODE=1
    • 返回:OK
  3. 连接家里的Wi-Fi
    • 发送:AT+CWJAP="你的WiFi名称","你的WiFi密码"
    • 返回:WIFI CONNECTED -> WIFI GOT IP (看到这个说明联网成功!)

3.2 连接云服务器(建立TCP连接)

我们要连接巴法云的MQTT服务器:

  • 地址:bemfa.com
  • 端口:8344 (TCP端口)
  1. 建立TCP连接

    • 发送:AT+CIPSTART="TCP","bemfa.com",8344
    • 返回:CONNECT -> OK
  2. 开启透传模式(关键步骤)

    • 发送:AT+CIPMODE=1
    • 返回:OK
    • 解释:开启后,我们发的数据直接给服务器,不需要每次都输指令。
  3. 开始发送数据

    • 发送:AT+CIPSEND
    • 返回:>
    • 此时,串口助手不再解析AT指令,而是把你发的内容全部发给服务器。

3.3 发送MQTT订阅指令

根据巴法云API,我们需要发送一条特定的字符串来订阅主题。
指令格式:cmd=1&uid=你的私钥&topic=LED001

  • 操作:在串口助手发送上述字符串(注意末尾加回车换行)。
  • 现象:如果你去巴法云控制台尝试推送消息,串口助手应该能收到数据!

第四部分:STM32CubeMX 配置

我们将手动操作转化为代码。使用 USART1 连接 ESP-01S,USART2 作为调试打印(连接电脑看日志),PC13 控制LED。

  1. RCC:HSE -> Crystal/Ceramic。
  2. USART1 (连ESP-01S):
    • Baud Rate: 115200 (与模块一致)。
    • 开启 NVIC 中断。
  3. USART2 (连电脑调试):
    • Baud Rate: 115200。
  4. GPIO:PC13 -> Output (LED)。
  5. 生成代码

第五部分:代码编写 (核心逻辑)

由于Wi-Fi连接需要时间,我们不能在中断里写死循环。推荐使用“发送指令 -> 等待响应”的模式。

5.1 简单的发送函数封装 (main.c)

#include <string.h>
#include <stdio.h>

// 发送AT指令并等待(简化版,实际项目建议配合定时器和中断解析)
void ESP_Send_Cmd(char* cmd, int wait_time)
{
    HAL_UART_Transmit(&huart1, (uint8_t*)cmd, strlen(cmd), 0xFFFF);
    HAL_Delay(wait_time); // 简单延时等待模块处理
}

5.2 初始化连接逻辑 (在 main 函数 while(1) 之前)

/* USER CODE BEGIN 2 */
printf("System Init...\r\n");

// 1. 复位模块
ESP_Send_Cmd("AT+RST\r\n", 2000);

// 2. 设置模式
ESP_Send_Cmd("AT+CWMODE=1\r\n", 500);

// 3. 连接WiFi (注意转义字符 \" )
// 请替换为你的实际账号密码
ESP_Send_Cmd("AT+CWJAP=\"HomeWiFi\",\"12345678\"\r\n", 5000); 

// 4. 连接巴法云
ESP_Send_Cmd("AT+CIPSTART=\"TCP\",\"bemfa.com\",8344\r\n", 2000);

// 5. 开启透传
ESP_Send_Cmd("AT+CIPMODE=1\r\n", 500);
ESP_Send_Cmd("AT+CIPSEND\r\n", 500);

// 6. 发送MQTT订阅报文 (登录并订阅)
// 格式: cmd=1&uid=xxx&topic=xxx
char mqtt_sub_msg[100];
sprintf(mqtt_sub_msg, "cmd=1&uid=你的私钥UID&topic=LED001\r\n");
HAL_UART_Transmit(&huart1, (uint8_t*)mqtt_sub_msg, strlen(mqtt_sub_msg), 0xFFFF);

// 开启中断接收
HAL_UART_Receive_IT(&huart1, &rx_byte, 1);
/* USER CODE END 2 */

5.3 接收中断处理 (处理云端发来的指令)

当手机通过云端发送 on 或 off 时,STM32会收到字符串。

uint8_t rx_buffer[128]; // 接收缓冲区
uint8_t rx_index = 0;
uint8_t rx_byte;

// 中断回调
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART1)
    {
        rx_buffer[rx_index++] = rx_byte;
        
        // 简单判断是否接收到换行符(消息结束)
        if(rx_byte == '\n')
        {
            // 在这里处理数据,例如判断字符串里是否包含 "on"
            // 注意:实际接收到的数据可能包含服务器的其他头信息,建议用 strstr 查找
            if(strstr((char*)rx_buffer, "on")) 
            {
                HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); // 开灯
            }
            else if(strstr((char*)rx_buffer, "off")) 
            {
                HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);   // 关灯
            }
            
            // 清空缓冲区准备下一次接收
            memset(rx_buffer, 0, 128);
            rx_index = 0;
        }
        
        HAL_UART_Receive_IT(&huart1, &rx_byte, 1);
    }
}

第六部分:远程控制实战

  1. 烧录代码:将STM32连接好ESP-01S(注意独立供电),上电。
  2. 观察串口:如果通过USB-TTL监控USART1,你会看到连接WiFi和服务器的OK响应。
  3. 手机控制
    • 打开 巴法云 的微信小程序或网页控制台。
    • 找到 LED001 主题。
    • 输入消息 on 并发送 -> 灯亮
    • 输入消息 off 并发送 -> 灯灭
    • 进阶:你甚至可以将巴法云接入米家或天猫精灵,实现“小爱同学,打开书房灯”。
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐