在 Arduino Mega 中使用 Modbus RTU 从电表读取数据
Read Data from energy meter using Modbus RTU in Arduino Mega
正在尝试从电表读取数据。该代码假设读取电压数据和 return 但它显示了一些随机数。我在代码中哪里出错了?仪表是 conzerv EM6436 能量计。
尝试过:- 1) 转换 uint16_t 中的数据失败
2)读不同的其他寄存器失败
3) 能量计在 modscan 上显示正确的数据。
Energy Meter register Link
#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(19200,SERIAL_8E1);
//slave ID 1
node.begin(1, Serial);
Serial.println("Starting Modbus Transaction:");
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
uint16_t newData = 0;
float floatData;
double dataOne;
void loop() { // loop starts from here.
static uint32_t i;
uint8_t j, result;
uint16_t data[10];
i++;
result = node.readHoldingRegisters(3036,1);
Serial.println(" ");
if (result == node.ku8MBSuccess) {
Serial.print("\nSuccess, Received data 0: ");
for (j = 0; j < 1; j++) {
data[j] = node.getResponseBuffer(j);
floatData, dataOne= node.getResponseBuffer(j);
Serial.print("\nHex data:");
Serial.print(data[j], HEX);
Serial.print(" ");
Serial.print("\nDec data:");
Serial.print(data[j], DEC);
Serial.print("\nfloat data:");
Serial.print(floatData);
}
} else {
Serial.print("Failed, Response Code: ");
Serial.print(result, HEX);
Serial.println(" ");
delay(5000);
}
delay(1000);
}
结果:-
Success, Received data 0:
-> Hex data:648F
-> Dec data:25743
-> float data:25743.00⸮
正如 Bosz 在上面的评论中所建议的,您需要做的第一件事是读取两个 Modbus 寄存器而不是一个。因此更改:
result = node.readHoldingRegisters(3036,1);
至:
result = node.readHoldingRegisters(3036,2);
然后你需要使用两个寄存器并将它们组合起来以获得你正在寻找的浮点数:
if (result == node.ku8MBSuccess) {
Serial.print("\nSuccess, Received data 0: ");
for (j = 0; j < 2; j++) {
data[j] = node.getResponseBuffer(j);
}
unsigned long temp = (unsigned long)data[0] + (unsigned long)data[1]*65536;
floatData = *((float*)&temp);
Serial.print(floatData);
}
此转换适用于设备寄存器列表中的任何 FLOAT32
值。
这个问题已经在好几个地方讨论过,例如here。
正在尝试从电表读取数据。该代码假设读取电压数据和 return 但它显示了一些随机数。我在代码中哪里出错了?仪表是 conzerv EM6436 能量计。 尝试过:- 1) 转换 uint16_t 中的数据失败 2)读不同的其他寄存器失败 3) 能量计在 modscan 上显示正确的数据。 Energy Meter register Link
#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(19200,SERIAL_8E1);
//slave ID 1
node.begin(1, Serial);
Serial.println("Starting Modbus Transaction:");
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
uint16_t newData = 0;
float floatData;
double dataOne;
void loop() { // loop starts from here.
static uint32_t i;
uint8_t j, result;
uint16_t data[10];
i++;
result = node.readHoldingRegisters(3036,1);
Serial.println(" ");
if (result == node.ku8MBSuccess) {
Serial.print("\nSuccess, Received data 0: ");
for (j = 0; j < 1; j++) {
data[j] = node.getResponseBuffer(j);
floatData, dataOne= node.getResponseBuffer(j);
Serial.print("\nHex data:");
Serial.print(data[j], HEX);
Serial.print(" ");
Serial.print("\nDec data:");
Serial.print(data[j], DEC);
Serial.print("\nfloat data:");
Serial.print(floatData);
}
} else {
Serial.print("Failed, Response Code: ");
Serial.print(result, HEX);
Serial.println(" ");
delay(5000);
}
delay(1000);
}
结果:-
Success, Received data 0:
-> Hex data:648F
-> Dec data:25743
-> float data:25743.00⸮
正如 Bosz 在上面的评论中所建议的,您需要做的第一件事是读取两个 Modbus 寄存器而不是一个。因此更改:
result = node.readHoldingRegisters(3036,1);
至:
result = node.readHoldingRegisters(3036,2);
然后你需要使用两个寄存器并将它们组合起来以获得你正在寻找的浮点数:
if (result == node.ku8MBSuccess) {
Serial.print("\nSuccess, Received data 0: ");
for (j = 0; j < 2; j++) {
data[j] = node.getResponseBuffer(j);
}
unsigned long temp = (unsigned long)data[0] + (unsigned long)data[1]*65536;
floatData = *((float*)&temp);
Serial.print(floatData);
}
此转换适用于设备寄存器列表中的任何 FLOAT32
值。
这个问题已经在好几个地方讨论过,例如here。