前言
包括简单的AT命令使用和发出 GET / POST 请求和连接 webscoket 服务。
注意,下文中的AT指令如果使用代码操作时,每个指令后面都需要增加 \r
基本使用
简单测试模块是否可用,发送 AT 显示 OK 说明模块没问题
信号质量查询
[2025-11-18 18:19:25.874 T] AT+CSQ
[2025-11-18 18:19:25.933 R]
+CSQ: 31,99
OK
GET 请求
需要注意,每次请求都需要删除掉旧的请求后重新来,不然参数什么的肯定不对。
[2025-10-09 18:41:37.491 T] AT+MHTTPTERM=0
[2025-10-09 18:41:37.551 R]
OK
[2025-10-09 18:41:38.416 T] AT+MHTTPDEL=0
[2025-10-09 18:41:38.471 R]
OK
[2025-10-09 18:41:39.592 T] AT+MHTTPCREATE="http://120.237.117.213:9997/"
[2025-10-09 18:41:39.658 R]
+MHTTPCREATE: 0
OK
[2025-10-09 18:41:43.983 T] AT+MHTTPREQUEST=0,1,0,"/sdk/use_once_api_by_api_key?api_key=xxx"
[2025-10-09 18:41:44.066 R]
OK
[2025-10-09 18:41:44.816 R]
+MHTTPURC: "header",0,200,364,HTTP/1.1 200 OK
Vary: Origin
Access-Control-Allow-Origin:
Access-Control-Allow-Credentials: true
content-type: application/json; charset=utf-8
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-download-options: noopen
x-readtime: 379
content-length: 41
Date: Thu, 09 Oct 2025 10:41:44 GMT
Connection: keep-alive
Keep-Alive: timeout=5
+MHTTPURC: "content",0,41,41,41,{"data":{"api_limit":702},"success":true}
POST 请求
需要注意,每次请求都需要删除掉旧的请求后重新来,不然参数什么的肯定不对。
[2025-10-09 18:31:48.207 T] AT+MHTTPTERM=0
[2025-10-09 18:31:48.277 R]
OK
[2025-10-09 18:31:48.696 T] AT+MHTTPDEL=0
[2025-10-09 18:31:48.757 R]
OK
[2025-10-09 18:31:49.599 T] AT+MHTTPCREATE="http://120.237.117.213:9997/"
[2025-10-09 18:31:49.661 R]
+MHTTPCREATE: 0
OK
[2025-10-09 18:31:51.193 T] AT+MHTTPHEADER=0,0,0,"Content-Type: application/json"
[2025-10-09 18:31:51.257 R]
OK
[2025-10-09 18:31:53.164 T] AT+MHTTPCONTENT=0,0,0,"{"api_key":"xxx","device_id":"xxx","bin_id":"111","wifi_ssid":"xxx", "version": "0.1"}"
[2025-10-09 18:31:53.236 R]
OK
[2025-10-09 18:31:54.551 T] AT+MHTTPREQUEST=0,2,0,"/devices/add"
[2025-10-09 18:31:54.620 R]
OK
[2025-10-09 18:31:55.226 R]
+MHTTPURC: "header",0,200,365,HTTP/1.1 200 OK
Vary: Origin
Access-Control-Allow-Origin:
Access-Control-Allow-Credentials: true
content-type: application/json; charset=utf-8
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-download-options: noopen
x-readtime: 336
content-length: 383
Date: Thu, 09 Oct 2025 10:31:55 GMT
Connection: keep-alive
Keep-Alive: timeout=5
+MHTTPURC: "content",0,383,383,383,{"success":true,"message":"绑定成功","data":{"id":"xxx","create_time":1760005914970,"user_id":"xxx","equipment_id":"xxx","api_key":"xxx","device_id":"xxx","name":"新设备-未命名","wifi_ssid":"xxx","version":"0.1","bin_id":"111","is_online":"1","enable":"1"}}
TCP 请求
服务端代码
/**
* =========================
* TCP 服务
*/
const net = require("net");
const moment = require("moment");
const TCP_PORT = 8088; // TCP 服务端口
/**
* 启动 TCP 服务(给 ESP 模组用)
*/
const tcpServer = net.createServer((socket) => {
console.log("[TCP] 模组已连接:", socket.remoteAddress, socket.remotePort);
// tcpClients.push(socket);
socket.on("data", (data) => {
console.log("[TCP] 收到模组数据:", moment().format(" HH:mm:ss SSS"));
const dataStr = data.toString();
let dataJson = null;
// JSON 数据解析
try {
const obj = JSON.parse(dataStr);
if (typeof obj === 'object' && obj !== null) {
dataJson = { ...obj };
}
} catch (e) { }
if (dataJson) {
console.log("[TCP] 收到模组数据 JSON:", dataJson);
socket.write(JSON.stringify({ success: true, message: "数据已收到" }));
} else {
console.log("[TCP] 收到模组数据 String:", dataStr);
}
});
socket.on("close", () => {
console.log("[TCP] 模组断开连接");
});
socket.on("error", (err) => {
console.error("[TCP] 错误:", err.message);
});
});
tcpServer.listen(TCP_PORT, () => {
console.log(`[TCP] 服务器已启动: 端口 ${TCP_PORT}`);
});
AT 测试指令
[2025-10-10 20:42:19.458 T] AT+MIPCLOSE=0
[2025-10-10 20:42:19.533 R]
OK
+MIPCLOSE: 0
[2025-10-10 20:42:23.704 T] AT+MIPOPEN=0,"TCP","120.237.117.213",9700
[2025-10-10 20:42:23.773 R]
OK
[2025-10-10 20:42:23.833 R]
+MIPOPEN: 0,0
[2025-10-10 20:42:27.144 T] AT+MIPSEND=0,,"12345678900"
[2025-10-10 20:42:27.209 R]
+MIPSEND: 0,11
OK
[2025-10-10 20:42:28.528 T] AT+MIPSEND=0,,"{"name":"小明同学", "age": 20}"
[2025-10-10 20:42:28.656 R]
+MIPSEND: 0,34
OK
+MIPURC: "rtcp",0,44,{"success":true,"message":"数据已收到"}
// 退出透传模式,后面不要加 \r
+++
服务日志
webScoket 请求
WS 服务连接
// 1. 连接 TCP 服务
AT+MIPOPEN=0,"TCP","120.237.117.213",9700
// 2. 进入透传模式
AT+MIPMODE=0,1
// 3. 升级为webscoket
// 发送这个时候,最后面有两个回车,不能忽略
// 如果在代码中执行这个指令是,每一行后面都需要增加 \r\n ,最后是 \r\n\r\n 。
GET /connect_espai_node?param=xxx HTTP/1.1
Host: 120.237.117.213:9700
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: ZYvFZbM7K1XzDp8n6SYnNQ==
Sec-WebSocket-Version: 13
Sec-WebSocket-Protocol:arduino
// 代码中执行下面语句即可
GET /connect_espai_node?param=xxx HTTP/1.1\r\nHost: 120.237.117.213:9700\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: ZYvFZbM7K1XzDp8n6SYnNQ==\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Protocol:arduino\r\n\r\n
数据发送
WebSocket 文本帧必须 mask 数据。以发送 hi 为例:
注意:串口助手下要用 16进制 发送,而后后面不能加换行。
81 82 12 34 56 78 7A 5D
客户端发送的每一帧数据都必须带掩码(mask),格式如下:
| 字段 | 长度 | 说明 |
|---|---|---|
| FIN + RSV + opcode | 1 字节 | 文本消息 opcode = 0x1,FIN=1 表示消息结束(常用 0x81) |
| Mask + Payload len | 1 字节 | 最低7位表示数据长度(若 ≤125),最高位=1 表示有 mask |
| Masking-key | 4 字节 | 掩码随机数(任意) |
| Payload data | N 字节 | 实际数据,每字节都要与 mask 异或 |
帧构造步骤如下:
我们要发送字符串 "hi"(ASCII: 0x68 0x69,长度2)
| 字段 | 含义 | 示例值 |
|---|---|---|
| 0x81 | FIN=1, Text帧 | 81 |
| 0x82 | 掩码标志+长度2 | 82 (0x80 + 0x02) |
| 掩码 | 随机4字节 | 12 34 56 78 |
| Payload原文 | "h"=68, "i"=69 | |
| 掩码后payload | (68⊕12)=7A, (69⊕34)=5D |
🔹所以最终发送字节序列为:
81 82 12 34 56 78 7A 5D