(六)RT-Thread网络通信--AT组件与ESP8266

RT-Thread网络通信 --- AT组件与ESP8266联网实战

前言

嵌入式设备要实现联网通信,AT命令是最常用的方式之一。RT-Thread提供了完善的AT组件,配合ESP8266 AT设备库,可以快速实现WiFi连接和网络通信。本文将介绍AT命令基础、AT组件架构、ESP8266设备库的使用,以及传感器框架的基本用法。


一、AT 命令基础

1.1 什么是AT命令?

AT命令是一种标准化的指令集,最早用于控制调制解调器,后来广泛应用于GSM、WiFi、蓝牙等通信模块的控制。AT命令通过串口传输,格式简单:

复制代码
发送: AT+CWJAP="SSID","PASSWORD"\r\n
响应: OK

1.2 RT-Thread AT 组件

AT组件包含两个核心部分:

组件 角色 功能
AT Server 接收端 接收并解析来自客户端的命令,返回响应
AT Client 发送端 向外部模块发送命令,接收和解析响应

在典型的物联网场景中,MCU作为AT Client,通过串口向ESP8266等WiFi模块(AT Server)发送AT命令。


二、AT Server

2.1 配置

rtconfig.h 中启用:

c 复制代码
#define RT_USING_AT
#define AT_USING_SERVER
#define AT_SERVER_DEVICE "uart3"

2.2 初始化

c 复制代码
int at_server_init(void);

系统会创建 at_server 线程处理命令接收和解析。

2.3 自定义AT命令

c 复制代码
static at_result_t at_test_exec(void)
{
    at_server_printfln("AT test command executed!");
    return 0;
}

AT_CMD_EXPORT("AT+TEST", =<value1>[,<value2>], NULL, NULL, NULL, at_test_exec);

参数说明:

  • 第1参数:命令名称
  • 第2参数:参数格式(<>必选,[]可选)
  • 第3-6参数:测试/查询/设置/执行 对应的处理函数

三、AT Client

3.1 配置与初始化

c 复制代码
#define RT_USING_AT
#define AT_USING_CLIENT
#define AT_CLIENT_NUM_MAX 1
c 复制代码
int at_client_init(const char *dev_name, rt_size_t recv_bufsz);

3.2 响应结构体

c 复制代码
struct at_response
{
    char *buf;           // 接收数据缓冲区
    rt_size_t buf_size;  // 缓冲区大小
    rt_size_t line_num;  // 接收行数限制
    rt_int32_t timeout;  // 响应超时时间
};

3.3 核心API

API 说明
at_create_resp(buf_size, line_num, timeout) 创建响应对象
at_delete_resp(resp) 删除响应对象
at_exec_cmd(resp, cmd_expr, ...) 发送命令并接收响应
at_resp_get_line(resp, line) 获取指定行数据
at_resp_parse_line_args(resp, line, expr, ...) 解析指定行数据

3.4 URC(非请求信息)处理

URC是指外部模块主动推送的数据(如WiFi连接状态变化、收到网络数据等),通过注册回调表来处理:

c 复制代码
static struct at_urc urc_table[] = {
    {"WIFI CONNECTED", "\r\n", urc_conn_func},
    {"+RECV",          ":",    urc_recv_func},
};

at_set_urc_table(urc_table, sizeof(urc_table) / sizeof(urc_table[0]));

3.5 多客户端支持

AT组件支持同时连接多个外部模块:

c 复制代码
/* 初始化两个客户端 */
at_client_init("uart2", 512);
at_client_init("uart3", 512);

/* 获取指定客户端 */
at_client_t client = at_client_get("uart3");
at_obj_exec_cmd(client, resp, "AT+CIFSR");

3.6 实战:通过AT命令扫描WiFi并连接

c 复制代码
#include <at.h>

#define AT_CLIENT_UART_NAME "uart2"
#define AT_RESP_BUFF_SIZE   2048
#define WIFI_SSID           "rtthread"
#define WIFI_PASSWORD       "12345678"

int scan_wifi_esp8266(void)
{
    at_client_t client = RT_NULL;
    at_response_t resp = RT_NULL;

    /* 初始化AT Client */
    at_client_init(AT_CLIENT_UART_NAME, AT_RESP_BUFF_SIZE);
    client = at_client_get(AT_CLIENT_UART_NAME);

    /* 创建响应对象(10秒超时) */
    resp = at_create_resp(AT_RESP_BUFF_SIZE, 0, rt_tick_from_millisecond(10000));

    /* 扫描周围WiFi */
    if (at_obj_exec_cmd(client, resp, "AT+CWLAP") == RT_EOK)
    {
        for (int i = 1; i <= 15; i++)
        {
            const char *line = at_resp_get_line(resp, i);
            if (line) rt_kprintf("WiFi: %s\n", line);
            else break;
        }
    }

    /* 连接到指定WiFi */
    if (at_obj_exec_cmd(client, resp, "AT+CWJAP=\"%s\",\"%s\"",
                        WIFI_SSID, WIFI_PASSWORD) == RT_EOK)
    {
        rt_kprintf("WiFi connected!\n");
    }

    at_delete_resp(resp);
    return 0;
}

四、ESP8266 AT 设备库

4.1 为什么用ESP8266库而不直接写AT命令?

对比项 直接AT命令 ESP8266库
开发效率 需手动拼接命令和解析响应 高层API,一行调用
错误处理 需手动处理超时/重试 内置自动重试
URC处理 需手动注册回调 已内置WiFi/Socket事件处理
Socket接口 对接标准BSD Socket
版本兼容 需自行适配 内置版本检测

4.2 主要模块

模块 文件 功能
设备初始化 at_device_esp8266.c WiFi连接、设备复位、版本管理
网络配置 at_device_esp8266.c IP/DNS/DHCP配置
Socket管理 at_socket_esp8266.c TCP/UDP连接、数据收发

4.3 配置与初始化

1. 启用配置(rtconfig.h):

c 复制代码
#define AT_DEVICE_USING_ESP8266
#define AT_USING_SOCKET

2. 注册设备并连接WiFi:

c 复制代码
esp8266_device_class_register();
esp8266_wifi_info_set(device, &info);

4.4 核心API

设备初始化与控制
API 说明
esp8266_init(device) 初始化设备(配置WiFi模式、连接等)
esp8266_reset(device) 复位设备(发送AT+RST)
esp8266_wifi_info_set(device, info) 设置WiFi信息并连接
esp8266_get_at_version() 获取AT固件版本
网络配置
API 说明
esp8266_netdev_set_addr_info(...) 设置IP/网关/子网掩码
esp8266_netdev_set_dns_server(...) 设置DNS服务器
esp8266_netdev_set_dhcp(...) 开启/关闭DHCP
esp8266_netdev_ping(...) Ping测试
Socket操作
API 说明
esp8266_socket_connect(socket, ip, port, type, is_client) 建立TCP/UDP连接
esp8266_socket_send(socket, buff, size, type) 发送数据
esp8266_socket_close(socket) 关闭连接
esp8266_domain_resolve(name, ip) 域名解析
esp8266_socket_set_event_cb(event, cb) 注册Socket事件回调

4.5 事件与回调

ESP8266库内置了URC事件处理:

事件 触发条件
WIFI CONNECTED WiFi连接成功
WIFI DISCONNECT WiFi断开
SEND OK 数据发送完成
+IPD 收到网络数据
CLOSED Socket连接关闭

五、传感器框架

传感器框架为物联网数据采集提供了统一接口,是将传感器数据上传到云平台的基础。

5.1 设计目标

通过标准化接口访问不同厂商的传感器,提高代码复用性。传感器作为I/O设备,遵循 rt_device_* 接口规范。

5.2 工作模式

模式 打开标志 适用场景
轮询模式 RT_DEVICE_FLAG_RDONLY 低频数据采集
中断模式 RT_DEVICE_FLAG_INT_RX 数据变化频繁
FIFO模式 RT_DEVICE_FLAG_FIFO_RX 低功耗批量采集

5.3 电源管理

c 复制代码
rt_device_control(dev, RT_SENSOR_CTRL_SET_POWER, (void *)RT_SEN_POWER_HIGH);

支持掉电、普通、低功耗、高性能四种模式。

5.4 传感器数据结构

c 复制代码
struct rt_sensor_data
{
    union {
        struct { rt_int32_t x, y, z; } acce;  /* 加速度 */
        struct { rt_int32_t x, y, z; } gyro;  /* 陀螺仪 */
        struct { rt_int32_t x, y, z; } mag;   /* 磁力计 */
        rt_int32_t temp;                      /* 温度 */
        rt_int32_t humi;                      /* 湿度 */
        rt_int32_t baro;                      /* 气压 */
    } data;
    rt_uint32_t timestamp;                    /* 时间戳 */
};

5.5 控制命令

命令 功能
RT_SENSOR_CTRL_GET_ID 获取设备ID
RT_SENSOR_CTRL_GET_INFO 获取设备信息
RT_SENSOR_CTRL_SET_RANGE 设置测量范围
RT_SENSOR_CTRL_SET_ODR 设置数据输出速率
RT_SENSOR_CTRL_SET_POWER 设置电源模式

5.6 DHT11 温湿度传感器示例

c 复制代码
#include <rtthread.h>
#include <rtdevice.h>
#include "sensor.h"
#include "sensor_dallas_dht11.h"

#define DHT11_DATA_PIN GET_PIN(A, 7)

static void read_temp_entry(void *parameter)
{
    rt_device_t dev = rt_device_find("temp_micu");
    if (dev == RT_NULL) return;

    rt_device_open(dev, RT_DEVICE_FLAG_RDWR);

    rt_uint8_t freq = 1;
    rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)&freq);

    while (1)
    {
        struct rt_sensor_data data;
        if (rt_device_read(dev, 0, &data, 1) == 1)
        {
            uint8_t temp = data.data.temp & 0xFFFF;
            uint8_t humi = (data.data.temp >> 16) & 0xFF;
            rt_kprintf("温度: %d°C, 湿度: %d%%\n", temp, humi);
        }
        rt_thread_delay(1000);
    }
}

static int dht11_sample(void)
{
    rt_thread_t thread = rt_thread_create("dht_tem", read_temp_entry,
                                          RT_NULL, 1024,
                                          RT_THREAD_PRIORITY_MAX / 2, 20);
    if (thread) rt_thread_startup(thread);
    return RT_EOK;
}
INIT_APP_EXPORT(dht11_sample);

总结

要点 内容
AT命令 标准化串口指令集,控制通信模块
AT组件 Server(接收端)+ Client(发送端)
URC处理 自动处理模块主动推送的事件
ESP8266库 封装AT命令,提供WiFi连接和Socket通信
传感器框架 统一接口访问不同传感器

到这里,设备已经能够联网并采集数据。

相关推荐
北京耐用通信2 小时前
协议融合的工业钥匙:耐达讯自动化网关如何打通CC-Link IE转DeviceNet的通信壁垒
人工智能·物联网·网络协议·自动化·信息与通信
qq_411262423 小时前
把esp32-c2当单片机用,不用wifi,如何配置,节省更多内存
单片机·嵌入式硬件
爱编码的小八嘎4 小时前
C语言完美演绎3—8
c语言
kaikaile19955 小时前
农业物联网基于STM32的LoRa无线通信系统设计与实现
stm32·嵌入式硬件·物联网
Irissgwe6 小时前
C&C++内存管理
c语言·开发语言·c++·c++内存管理
雾岛听蓝6 小时前
C文件操作与系统IO
linux·c语言·开发语言·经验分享·笔记·算法
Yupureki7 小时前
《C++实战项目-高并发内存池》3.ThreadCache构造
服务器·c语言·c++·算法·哈希算法
wsoz7 小时前
MCU中部署TinyMaix
单片机·mcu·神经网络·嵌入式·tinymaix
香水5只用六神7 小时前
【RTOS快速入门】07_同步互斥与通信概述
单片机·嵌入式硬件·学习·操作系统·freertos·rtos·嵌入式软件