如何用Arduino MKR WAN 1310搭配红外读取头获取电表数据
解决方案
1. 硬件接线(关键前提)
Hichi TTL-IR读取头是TTL串口输出设备,并非红外遥控类的调制信号发射器,直接用硬件串口连接即可,接线对应:
- 读取头VCC → Arduino MKR WAN 1310的3.3V引脚(MKR系列为3.3V逻辑,禁止接5V)
- 读取头GND → Arduino GND引脚
- 读取头TX → Arduino MKR WAN 1310的RX1引脚(引脚14)
注:读取头的RX引脚无需连接,我们只需要接收电表的输出数据
2. 替换串口方案(放弃SoftwareSerial)
Arduino MKR WAN 1310自带硬件串口Serial1,完美适配9600波特率的8-N-1格式,直接使用即可,初始化代码示例:
void setup() { Serial.begin(9600); // USB串口用于调试打印 Serial1.begin(9600, SERIAL_8N1); // 连接读取头的硬件串口,匹配电表参数 }
3. 解析SML协议数据
电表输出的是SML 1.04格式的二进制报文,核心逻辑是先捕获帧头0x1B 0x1B 0x1B 0x1B,再读取完整报文后解析:
基础数据读取示例(捕获帧头+完整报文)
const byte SML_HEADER[] = {0x1B, 0x1B, 0x1B, 0x1B}; const int HEADER_LEN = sizeof(SML_HEADER); byte buffer[1024]; int bufferIndex = 0; void loop() { while (Serial1.available()) { byte incoming = Serial1.read(); // 匹配SML帧头 if (bufferIndex < HEADER_LEN) { if (incoming == SML_HEADER[bufferIndex]) { bufferIndex++; } else { bufferIndex = 0; // 匹配失败,重置缓冲区 } } else { // 帧头匹配成功,存储后续数据 if (bufferIndex < sizeof(buffer)) { buffer[bufferIndex++] = incoming; // 遇到SML结束符0x1A时,处理完整报文 if (incoming == 0x1A) { processSMLPacket(buffer, bufferIndex); bufferIndex = 0; // 重置缓冲区,准备下一次捕获 } } else { bufferIndex = 0; // 缓冲区满,强制重置 } } } } void processSMLPacket(byte* packet, int length) { // 此处可调用SML解析库处理报文,或手动提取电表读数 // 调试示例:打印原始报文 Serial.print("捕获到SML报文,长度:"); Serial.println(length); for (int i=0; i<length; i++) { if (packet[i] < 0x10) Serial.print("0"); Serial.print(packet[i], HEX); Serial.print(" "); } Serial.println(); }
进阶:使用SML解析库
可以直接使用适配Arduino的SML解析库,这类库会自动处理SML的结构解析,无需手动拆解二进制,直接提取总用电量、各相电流电压等关键读数。
之前方案无效的原因
IRremote.h是用于处理红外遥控调制信号的库,而你的读取头输出的是TTL电平的串口数据,信号类型完全不匹配,因此无法获取有效数据。SoftwareSerial.h对ARM架构的MKR系列兼容性极差,而MKR自带硬件串口,完全没必要使用软件模拟串口。
内容的提问来源于stack exchange,提问作者EikeJoo
相关产品推荐
相关产品推荐

