WiFi模块相关代码说明
板载模组的AT指令
关于WIFI模块,需要注意的是AT指令的运用,模组的通用指令文件在安信可官网可查到:指令链接
发送AT指令以及处理回复的消息
主控芯片使用串口2向模块发送AT指令,基础的硬件初始化已经在库中写好了。使用WIFI模块中只需要学会使用下面三个函数便可以完成发送AT指令的操作。
成员函数 | 功能描述 |
Wifi() | 构造函数 |
void init(u32 baudrate) | 初始化WiFi模块(默认设置波特率为115200) |
u8 sendATCmd(u8 *cmd, u8 *resp, u32 timeout) | 发送AT指令 |
u8 sendATCmd(u8 *cmd, u8 *resp, u32 timeout, u8 *recvData, u16 recvBufSize) | 发送AT指令(支持接收数据存储) |
下面为相关函数用法
#include <stdio.h> // 引入标准输入输出库,用于 printf、sprintf 等函数
#include "wifi.h" // 引入自定义的 WiFi 模块驱动头文件
#define WIFI_SSID "" // WiFi 名称,需替换为你自己的 SSID
#define WIFI_PASSWORD "" // WiFi 密码,需替换为你自己的密码
Wifi wifi; // 创建一个 Wifi 类的实例,用于控制 WiFi 模块
u8 recvBuf[1024]; // 定义一个 1024 字节的缓冲区,用于存放从 WiFi 模块接收到的数据
u16 result = 1024; // 定义接收缓冲区大小变量(这里直接等于 1024)
void setup() { // Arduino 初始化函数,只在启动时执行一次
Serial.begin(115200); // 初始化串口通信,波特率 115200,用于调试打印
wifi.init(115200); // 初始化 WiFi 模块,设置串口波特率 115200
// 发送 AT 指令,等待返回 "OK",超时时间 2000ms,用来检测模块是否正常工作
wifi.sendATCmd((u8 *)"AT", (u8 *)"OK", 2000);
// 查询当前 WiFi 模式,期望返回 "+WMODE:1"(Station 模式),超时 2000ms
wifi.sendATCmd((u8 *)"AT+WMODE?", (u8 *)"+WMODE:1", 2000);
u8 connectCmd[128]; // 定义一个 128 字节的数组,用于存放连接 WiFi 的 AT 指令
// 格式化生成连接 WiFi 的 AT 命令,例如:AT+WJAP=SSID,PASSWORD
sprintf((char *)connectCmd, "AT+WJAP=%s,%s", WIFI_SSID, WIFI_PASSWORD);
// 发送连接 WiFi 的 AT 指令,等待获取 IP 地址事件 "+EVENT:WIFI_GOT_IP",超时 10000ms
wifi.sendATCmd(connectCmd, (u8 *)"+EVENT:WIFI_GOT_IP", 10000);
// 发送 HTTP 请求获取天气数据
// 注意:这里原代码换行写法会导致编译错误,建议合并成一行或使用续行符
wifi.sendATCmd(
(u8 *)"AT+HTTPCLIENTLINE=1,3,application/json,api.seniverse.com,80,https://api.seniverse.com/v3/weather/now.json?key=SyrYSW2nxI29Gqr4S&location=nanjing&language=zh-Hans",
(u8 *)"OK", // 期望返回 "OK"
10000, // 超时时间 10000ms
recvBuf, // 接收数据缓冲区
result // 缓冲区大小
);
// 通过串口打印接收到的原始天气数据
Serial.printf("原始数据:%s\r\n", recvBuf);
}
void loop() { // Arduino 主循环函数,会不断重复执行
}
1. 代码解析
这段 Arduino 代码的作用是:
- 初始化串口(用于调试输出);
- 初始化 WiFi 模块(通过串口和它通信);
- 用 AT 指令控制 WiFi 模块:
- 检测模块是否在线;
- 设置/查询 WiFi 模式;
- 连接到指定 WiFi 网络;
- 发送 HTTP 请求获取天气数据;
- 把收到的数据打印到电脑串口监视器。
2. 串口和 AT 指令在这个例子里的角色
串口(UART)
AT 指令
3. 代码执行流程(串口 + AT 指令)
启动 & 初始化
Serial.begin(115200);
wifi.init(115200);
- 打开 Arduino 与电脑之间的串口(调试用);
- 打开 Arduino 与 WiFi 模块之间的串口(波特率 115200)。
检测模块是否在线
wifi.sendATCmd((u8 *)"AT", (u8 *)"OK", 2000);
- Arduino 通过串口发
"AT"
给 WiFi 模块;
- 如果模块正常,会回
"OK"
;
- 如果没回,说明串口没接好或模块坏了。
查询 WiFi 模式
wifi.sendATCmd((u8 *)"AT+WMODE?", (u8 *)"+WMODE:1", 2000);
- 问模块当前的 WiFi 模式;
- 期望返回
+WMODE:1
(Station 模式)。
连接 WiFi
sprintf((char *)connectCmd, "AT+WJAP=%s,%s", WIFI_SSID, WIFI_PASSWORD);
wifi.sendATCmd(connectCmd, (u8 *)"+EVENT:WIFI_GOT_IP", 10000);
- 生成连接指令,例如:
AT+WJAP=MyWiFi,12345678
- 发过去后,等待模块连上 WiFi 并获取 IP(返回
+EVENT:WIFI_GOT_IP
)。
HTTP 请求天气数据
wifi.sendATCmd(
(u8 *)"AT+HTTPCLIENTLINE=1,3,application/json,api.seniverse.com,80,https://api.seniverse.com/v3/weather/now.json?key=your&location=nanjing&language=zh-Hans",
(u8 *)"OK",
10000,
recvBuf,
result
);
- 发 HTTP GET 请求给天气 API;
- 模块会把服务器返回的 JSON 数据通过串口传回 Arduino,存到
recvBuf
。
打印结果
Serial.printf("原始数据:%s\r\n", recvBuf);
- 把收到的天气 JSON 数据通过 电脑串口监视器 显示出来。
4. 串口 ↔ AT 指令的关系图
电脑(串口监视器) <--USB串口--> Arduino <--硬件串口(UART)--> WiFi模块
↑ ↑
调试打印 发AT指令/收回复
- Arduino ↔ WiFi 模块:用串口线连接,传递 AT 指令和数据;
- Arduino ↔ 电脑:用 USB 串口,方便你看到调试信息。
总结:
- 串口是 Arduino 和 WiFi 模块之间的“对话通道”;
- AT 指令是 Arduino 对 WiFi 模块说的“命令语言”;
- 代码就是通过串口发 AT 指令,让 WiFi 模块去连接网络、请求数据,然后把结果显示给你看。
案例使用AT指令连接WIFI
心知天气API的使用方法
- 注册并获取API密钥
在心知天气官网注册账号后,登录并创建应用,系统会分配一个唯一的API密钥,用于所有API请求的身份验证。请妥善保管该密钥。
- 构造HTTP请求
选择合适的API接口后,通过HTTP请求获取数据。例如,获取实时天气信息的请求格式如下:
https://api.seniverse.com/v3/weather/now.json?key=YOUR_API_KEY&location=beijing&language=zh-Hans&unit=c
- 解析返回数据
API返回的数据为JSON格式,包含天气信息。以下是示例返回数据:
{"results":[{"location":{"id":"WTSQQYHVQ973","name":"南京","country":"CN","path":"南京,南京,江苏,中国",
"timezone":"Asia/Shanghai","timezone_offset":"+08:00"},
"now":{"text":"阴","code":"9","temperature":"22"},"last_update":"2025-09-24T10:07:29+08:00"}]}
- 实现代码示例
#include <stdio.h>
#include "wifi.h"
#include <ArduinoJson.h> // 需安装ArduinoJson库(版本6以上)
#define WIFI_SSID "" // 替换为你的WiFi名称
#define WIFI_PASSWORD "" // 替换为你的WiFi密码
Wifi wifi;
// 初始化WiFi
u8 AI_WB2_InitWiFi(void)
{
printf("Initialize AI-WB2-12S...\r\n");
if (wifi.sendATCmd((u8 *)"AT", (u8 *)"OK", 2000) != 0)
return 1;
if (wifi.sendATCmd((u8 *)"AT+WMODE?", (u8 *)"+WMODE:1", 2000) != 0)
return 1;
delay(1000);
u8 connectCmd[128];
sprintf((char *)connectCmd, "AT+WJAP=%s,%s", WIFI_SSID, WIFI_PASSWORD);
if (wifi.sendATCmd(connectCmd, (u8 *)"+EVENT:WIFI_GOT_IP", 10000) != 0)
return 1;
return 0;
}
// 从接收数据中提取JSON字符串
char* extractJsonString(char* data) {
char* start = strstr(data, "{"); // 查找JSON起始符
char* end = strrchr(data, '}'); // 查找最后一个JSON结束符
if (start && end) {
end[1] = '\0'; // 截断多余内容(包括后面的OK)
return start;
}
return NULL;
}
// 解析天气数据
void parseWeatherData(char* jsonStr) {
if (!jsonStr) {
Serial.println("未找到有效的JSON数据");
return;
}
// 分配足够的缓冲区(根据实际JSON大小调整)
const size_t capacity = 512;
DynamicJsonDocument doc(capacity);
DeserializationError error = deserializeJson(doc, jsonStr);
if (error) {
Serial.print("JSON解析错误: ");
Serial.println(error.c_str());
return;
}
// 提取数据
const char* location = doc["results"][0]["location"]["name"];
const char* time = doc["results"][0]["last_update"];
const char* weather = doc["results"][0]["now"]["text"];
const char* temp = doc["results"][0]["now"]["temperature"];
// 打印结果
Serial.println("\n===== 天气信息 =====");
Serial.print("地点: ");
Serial.println(location);
Serial.print("时间: ");
Serial.println(time);
Serial.print("天气: ");
Serial.println(weather);
Serial.print("温度: ");
Serial.print(temp);
Serial.println("°C");
Serial.println("====================");
}
u8 recvBuf[1024];
u16 result = 1024;
void setup()
{
Serial.begin(115200);
wifi.init(115200);
if (AI_WB2_InitWiFi() == 0)
{
Serial.println("WiFi连接成功,正在获取天气数据...");
// 发送HTTP请求
wifi.sendATCmd(
(u8 *)"AT+HTTPCLIENTLINE=1,3,application/json,api.seniverse.com,80,
https://api.seniverse.com/v3/weather/now.json?key=SyrYSW2nxI29Gqr4S&location=nanjing&language=zh-Hans",
(u8 *)"OK",
10000,
recvBuf,
result
);
Serial.printf("接收数据长度:%d\r\n", result);
Serial.printf("原始数据:%s\r\n", recvBuf);
// 提取并解析JSON
char* jsonStr = extractJsonString((char*)recvBuf);
parseWeatherData(jsonStr);
}
else
{
Serial.println("WiFi连接失败");
}
}
void loop()
{
delay(300000); // 每5分钟刷新一次
setup();
}