ModbusMaster icon indicating copy to clipboard operation
ModbusMaster copied to clipboard

Unable to read input register values via RS485

Open eliuker opened this issue 7 years ago • 5 comments

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.

screen shot 2018-10-11 at 11 22 40 screen shot 2018-10-11 at 11 28 21

eliuker avatar Oct 11 '18 14:10 eliuker

I observed following 2 points

  1. your reading required 2 REGISTERS for evaluation of a one parameter(from SHORT column)
  2. 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));

apanasara avatar Jan 02 '19 00:01 apanasara

refer this link for details RS-485 & Modbusmaster.h

apanasara avatar Jan 09 '19 00:01 apanasara

I observed following 2 points

  1. your reading required 2 REGISTERS for evaluation of a one parameter(from SHORT column)
  2. 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. sdm120 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?

Sergio-tix avatar Feb 13 '20 07:02 Sergio-tix

store 0,6,70,342 into array & run loop

apanasara avatar Feb 20 '20 17:02 apanasara

refer getReading() function of crypt_Mqtt_Modbus_wifiManager

apanasara avatar Feb 20 '20 18:02 apanasara