Arduino通过LoRa发送含字符串的结构体遇到的问题
解决LoRa完整字符串收发问题
问题根源分析
- 你定义的
DATA结构体中char msg是单个字符类型,每次发送仅能传递一个字符,这就是接收端逐字符收到数据的核心原因。 - 串口输入"hello world"并按下回车时,串口会将每个字符(包括换行符
\n,对应ASCII码10)依次传入,因此接收端会收到h、e、l...以及代表换行的10。 - 直接将
char改为String类型无效,因为LoRa传输的是二进制数据,String对象包含额外内部结构,直接序列化发送会导致乱码。
解决方案步骤
1. 重新定义适配字符串传输的结构体
将单个字符改为固定长度的字符数组,同时增加字符串长度字段,用于告知接收端有效字符的数量:
#define MAX_MSG_LEN 64 // 根据需求调整最大字符串长度 struct DATA { char msg[MAX_MSG_LEN]; int valor; uint8_t msg_len; // 存储实际字符串的有效长度 };
2. 发送端:完整读取串口字符串并填充结构体
不再逐字符读取串口,而是一次性获取完整输入(直到换行符),再将内容复制到结构体中:
DATA tx_data; void loop() { if (Serial.available() > 0) { // 读取串口输入直到换行,获取完整字符串 String input_str = Serial.readStringUntil('\n'); // 去除字符串首尾的换行、回车等空白字符 input_str.trim(); // 确保字符串长度不超过数组最大限制 size_t str_len = input_str.length(); if (str_len > MAX_MSG_LEN - 1) { str_len = MAX_MSG_LEN - 1; // 预留一个位置存储字符串结束符'\0' } // 将String转换为char数组,写入结构体 input_str.toCharArray(tx_data.msg, str_len + 1); tx_data.msg_len = str_len; tx_data.valor = 123; // 替换为你的实际valor数值 // 通过LoRa发送结构体二进制数据 LoRa.beginPacket(); LoRa.write((uint8_t*)&tx_data, sizeof(DATA)); LoRa.endPacket(); } }
3. 接收端:正确解析结构体并提取有效字符串
接收时先确认数据包大小与结构体匹配,再根据msg_len提取有效字符串:
DATA rx_data; void loop() { int packetSize = LoRa.parsePacket(); if (packetSize) { // 校验数据包大小与结构体大小一致,避免解析错误 if (packetSize == sizeof(DATA)) { // 读取完整结构体数据 LoRa.read((uint8_t*)&rx_data, sizeof(DATA)); // 手动添加字符串结束符,防止乱码 rx_data.msg[rx_data.msg_len] = '\0'; // 输出接收结果 Serial.print("收到字符串:"); Serial.println(rx_data.msg); Serial.print("收到valor:"); Serial.println(rx_data.valor); } else { Serial.println("数据包大小不匹配,丢弃"); } } }
4. 关键注意事项
- 发送端与接收端的
MAX_MSG_LEN必须完全一致,结构体的成员顺序、类型也要完全相同,否则会出现解析乱码。 - 禁止直接发送
String对象,其内部包含指针和额外结构,不适合二进制传输。 - 确认
sizeof(DATA)不超过你的LoRa库最大数据包限制(常见为255字节,按上述配置仅69字节,完全合规)。
内容的提问来源于stack exchange,提问作者Vinícius
相关产品推荐
相关产品推荐

