LA66 LoRa模块RSSI测量故障:Arduino Uno R3发送正常接收无数据
LA66 LoRa模块通信故障排查与RSSI读取方案
接收端无数据的可能原因及解决方法
1. 串口通信混淆
你的代码直接使用Arduino硬件串口同时连接LA66模块和电脑串口监视器,导致:
- 发送端的调试信息和发给模块的AT指令混在一起,模块可能收到错误指令
- 接收端无法区分模块返回的通信数据和电脑串口的输入
解决:用SoftwareSerial软串口单独连接LA66模块,把硬件串口留给电脑调试(代码示例见下文)。
2. AT指令格式错误
LA66的AT+SEND指令格式要求包含数据长度,正确格式为:AT+SEND=<目标地址>,<数据长度>,<数据>。你的代码里缺少数据长度字段(HelloWorld是10个字符),模块可能拒绝发送数据。
3. 未启动通信状态
配置完P2P参数后,需要发送AT+START指令让模块进入收发状态,你的代码里只执行了AT+SAVE,模块可能未激活通信功能。
4. 模块配置未生效
- 检查模块波特率是否匹配:LA66默认波特率可能是115200而非9600,需确认模块手册,调整代码中的串口波特率
- 配置阶段需确认模块返回
OK响应,否则说明配置失败。可在代码中添加指令响应读取,排查哪一步配置出错 - 确保两块模块的
NETWORKID、PARAMETER、FREQ参数完全一致,任何参数不匹配都会导致无法通信
5. 硬件问题
- 确认模块与Arduino的接线:LA66的TX接Arduino的RX,RX接Arduino的TX,必须交叉连接且共地
- 模块供电需稳定:LoRa模块建议用3.3V/500mA以上电源,Arduino板载3.3V可能功率不足
- 检查天线是否正确安装:无天线时LoRa通信距离极短,甚至无法建立连接
RSSI读取方法
LA66在P2P模式下接收数据后,会返回格式为+RCV=<源地址>,<数据长度>,<RSSI值>,<数据内容>的响应。只需从该字符串中提取倒数第二个逗号前的数值即可得到RSSI(单位:dBm)。
修改后的代码已内置RSSI提取逻辑,同时修复了串口混淆和指令格式问题:
发送端代码
#include <SoftwareSerial.h> SoftwareSerial la66Serial(2, 3); // Arduino引脚2接LA66的TX,引脚3接LA66的RX #define MY_ADDRESS 1 // 发送端模块地址 #define DEST_ADDRESS 2 // 接收端模块地址 unsigned long dernierEnvoi = 0; void setup() { Serial.begin(9600); // 电脑调试串口 la66Serial.begin(9600); // LA66模块串口,需与模块默认波特率匹配 delay(3000); Serial.println("初始化LA66 (TX)"); // 配置P2P模式并检查响应 sendATCommand("AT+STOP"); sendATCommand("AT+RESET"); delay(2000); sendATCommand("AT+MODE=0"); sendATCommand("AT+ADDRESS=" + String(MY_ADDRESS)); sendATCommand("AT+NETWORKID=5"); sendATCommand("AT+PARAMETER=9,7,1,4"); sendATCommand("AT+FREQ=868500000"); sendATCommand("AT+SAVE"); sendATCommand("AT+START"); // 启动通信 Serial.println("TX就绪"); } void loop() { if (millis() - dernierEnvoi > 3000) { dernierEnvoi = millis(); // 正确格式的AT+SEND指令,包含数据长度 String sendCmd = "AT+SEND=" + String(DEST_ADDRESS) + ",10,HelloWorld"; la66Serial.println(sendCmd); Serial.println("已发送指令: " + sendCmd); // 读取模块发送响应 if (la66Serial.available()) { String resp = la66Serial.readStringUntil('\n'); Serial.println("模块响应: " + resp); } } } // 封装AT指令发送与响应读取函数 void sendATCommand(String cmd) { la66Serial.println(cmd); delay(200); if (la66Serial.available()) { String resp = la66Serial.readStringUntil('\n'); Serial.println(cmd + " -> " + resp); } }
接收端代码
#include <SoftwareSerial.h> SoftwareSerial la66Serial(2, 3); // Arduino引脚2接LA66的TX,引脚3接LA66的RX #define MY_ADDRESS 2 // 接收端模块地址 String recu; int rssiCount = 0; long rssiSum = 0; int rssiMin = 999; int rssiMax = -999; void setup() { Serial.begin(9600); // 电脑调试串口 la66Serial.begin(9600); // LA66模块串口,需与模块默认波特率匹配 delay(3000); Serial.println("初始化LA66 (RX)"); // 配置P2P模式并检查响应 sendATCommand("AT+STOP"); sendATCommand("AT+RESET"); delay(2000); sendATCommand("AT+MODE=0"); sendATCommand("AT+ADDRESS=" + String(MY_ADDRESS)); sendATCommand("AT+NETWORKID=5"); sendATCommand("AT+PARAMETER=9,7,1,4"); sendATCommand("AT+FREQ=868500000"); sendATCommand("AT+SAVE"); sendATCommand("AT+START"); // 启动接收 Serial.println("RX就绪"); } void loop() { // 读取LA66模块返回的数据 if (la66Serial.available()) { recu = la66Serial.readStringUntil('\n'); recu.trim(); if (recu.length() > 0) { Serial.println("模块返回: " + recu); // 提取RSSI值 if (recu.startsWith("+RCV")) { int comma1 = recu.indexOf(','); int comma2 = recu.indexOf(',', comma1 + 1); int comma3 = recu.indexOf(',', comma2 + 1); if (comma1 != -1 && comma2 != -1 && comma3 != -1) { String rssiStr = recu.substring(comma2 + 1, comma3); int rssiVal = rssiStr.toInt(); // 更新RSSI统计数据 rssiSum += rssiVal; rssiCount++; if (rssiVal < rssiMin) rssiMin = rssiVal; if (rssiVal > rssiMax) rssiMax = rssiVal; Serial.println("RSSI值: " + String(rssiVal) + " dBm"); Serial.println(" 平均值: " + String((float)rssiSum / rssiCount, 2) + " dBm"); Serial.println(" 最小值: " + String(rssiMin) + " dBm"); Serial.println(" 最大值: " + String(rssiMax) + " dBm"); } } } } } // 封装AT指令发送与响应读取函数 void sendATCommand(String cmd) { la66Serial.println(cmd); delay(200); if (la66Serial.available()) { String resp = la66Serial.readStringUntil('\n'); Serial.println(cmd + " -> " + resp); } }
内容的提问来源于stack exchange,提问作者Ivv-584
相关产品推荐
相关产品推荐

