问题描述
我一直在尝试使用 Arduino 通过 Modbus 通信从我的电能表获取电气参数。但是我的代码无法从仪表中获取数据。在这段代码中,我试图从寄存器地址为 12 的电能表中获取相电压值。
#include<ModbusMaster.h>
#define MAX485_DE 3
#define MAX485_RE_NEG 2
ModbusMaster node;
void preTransmission()
{
digitalWrite(MAX485_RE_NEG,1);
digitalWrite(MAX485_DE,1);
}
void postTransmission()
{
digitalWrite(MAX485_RE_NEG,0);
digitalWrite(MAX485_DE,0);
}
void setup() {
pinMode(MAX485_RE_NEG,OUTPUT);
pinMode(MAX485_DE,OUTPUT);
// Init in receive mode
digitalWrite(MAX485_RE_NEG,0);
digitalWrite(MAX485_DE,0);
Serial.begin(9600);
//slave ID 1
node.begin(1,Serial);
Serial.println("Starting Modbus Transaction:");
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
void loop() {
static uint32_t i;
uint8_t j,result;
uint16_t data[10];
i++;
result = node.readInputRegisters(0x30012,2);
Serial.println("");
if (result == node.ku8MBSuccess) {
Serial.print("Success,Received data: ");
for (j = 0; j < 2; j++) {
data[j] = node.getResponseBuffer(j);
Serial.print(data[j],HEX);
Serial.print(" ");
}
Serial.println("");
} else {
Serial.print("Failed,Response Code: ");
Serial.print(result,HEX);
Serial.println("");
delay(5000);
}
delay(1000);
}
解决方法
您使用了错误的 Modbus 功能。您应该使用函数 0x03 readHoldingRegisters
(注意页面底部框架开头的 0x03)。
只需更改这一行:
result = node.readInputRegisters(0x30012,2);
到:
result = node.readHoldingRegisters(12,2);
顺便说一句,您的设置肯定有其他问题,因为您得到的错误代码是 0xE2
而您应该得到 0x02
的意思是 Ilegal Data Address
或者 {{1 }} (0x01
) 取决于仪表的固件。也许你应该仔细检查一下波特率。
您可能还需要在设置循环中将节点的 ID 设置为 Illegal Function
:
0xAA
正如上面有人评论的那样。文档不是很好...
如果您查看底部的示例数据命令:
node.begin(170,Serial);
看起来 aa 03 0001 003C 0DC0
是从地址,aa
是上面讨论的功能代码,03
是要读取的寄存器数量(60 从仪表读取所有数据一气呵成)。最后两个字节 003C
应该是 CRC。
如果这是正确的,那么如果您想获得相电压,您应该考虑读取寄存器 11 和 12 而不是 12-13:
0DC0
再说一次,这只是我填补文档空白的最佳猜测。