中国移动 ML307R 模组 AT 命令学习

0 阅读5分钟

前言

包括简单的AT命令使用和发出 GET / POST 请求和连接 webscoket 服务。

注意,下文中的AT指令如果使用代码操作时,每个指令后面都需要增加 \r

基本使用

简单测试模块是否可用,发送 AT 显示 OK 说明模块没问题

image.png

信号质量查询


[2025-11-18 18:19:25.874 T] AT+CSQ

[2025-11-18 18:19:25.933 R] 
+CSQ: 31,99

OK

image.png

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
+++ 

服务日志

image.png

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 + opcode1 字节文本消息 opcode = 0x1,FIN=1 表示消息结束(常用 0x81
Mask + Payload len1 字节最低7位表示数据长度(若 ≤125),最高位=1 表示有 mask
Masking-key4 字节掩码随机数(任意)
Payload dataN 字节实际数据,每字节都要与 mask 异或

帧构造步骤如下: 我们要发送字符串 "hi"(ASCII: 0x68 0x69,长度2)

字段含义示例值
0x81FIN=1, Text帧81
0x82掩码标志+长度2820x80 + 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