Unable to read input register values via RS485
Hello, I'm new to the Modbus protocol and I would like some help in my project. I'm basically trying to get the voltage data from a power meter using the ESP-12E, RS-485 transceiver, and the Modbus RTU protocol. The problem is: I'm not able to get any result. Here's the code I'm using:
#include<ModbusMaster.h> //include Modbus library #include<SoftwareSerial.h> #define MAX485_DE 3 //high to enable #define MAX485_RE_NEG 2 //low to enable
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); digitalWrite(MAX485_RE_NEG, 0); digitalWrite(MAX485_DE, 0);
Serial.begin(115200);
node.begin(1, Serial); node.preTransmission(preTransmission); node.postTransmission(postTransmission); }
void loop() { uint8_t resultMain;
resultMain = node.readInputRegisters (0x04,2); if (resultMain == node.ku8MBSuccess) { Serial.println("--------------"); Serial.print("PV Voltage: "); Serial.println(node.getResponseBuffer(0x01) / 1.0f); } delay(1000);
}
I'm attaching the results I'm getting as well as the data sheet from the developer of the power meter. I would appreciate the help.
I observed following 2 points
- your reading required 2 REGISTERS for evaluation of a one parameter(from SHORT column)
- your readings will be required to get converted into data_type (here FLOAT - from FORMTO column)
//for float conversation
union
{
uint32_t i;
float f;
}u;
uint8_t result = node.readInputRegisters(address, 2); // for 3000xx registers
Serial.println("Result : " + String(result));// to get error type
if (result == node.ku8MBSuccess)
{
u.i=(((unsigned long)node.getResponseBuffer(0x01)<<16) | (node.getResponseBuffer(0x00)));// shifting 2nd register to left & stiching with 1st register
}
Serial.println("Reading is "+String(u.f));
refer this link for details RS-485 & Modbusmaster.h
I observed following 2 points
- your reading required 2 REGISTERS for evaluation of a one parameter(from SHORT column)
- your readings will be required to get converted into data_type (here FLOAT - from FORMTO column)
//for float conversation union { uint32_t i; float f; }u; uint8_t result = node.readInputRegisters(address, 2); // for 3000xx registers Serial.println("Result : " + String(result));// to get error type if (result == node.ku8MBSuccess) { u.i=(((unsigned long)node.getResponseBuffer(0x01)<<16) | (node.getResponseBuffer(0x00)));// shifting 2nd register to left & stiching with 1st register } Serial.println("Reading is "+String(u.f));
Hello!
This code worked for my hardware which works with data type FLOAT, bit sequence AB CD.
But I'm not very literate in programming (I'm dunce). How can I make a request (and how to get an answer) for several registers? Registers do not follow sequentially.
I only need registers:
30000-30001
30006-30007
30070-30071
30342-30343
How to redo the code? Need to repeat your example every time for a new address with new variable names? Or is there a more rational way?
store 0,6,70,342 into array & run loop
refer getReading() function of crypt_Mqtt_Modbus_wifiManager