MODBUS over rs-485

im tryig to communicate with my power meter over modbus via rs485, im able to send successful modbus frame from my arduino even my meter is responding with data(im checking this using an usb rs485 connected parallely(tapped on th a and b lines of arduino and meter) but im always getting a time out error no matter what. my data is being sent by the meter immediately and the default time out is 2s , its not even taking that long, tried switching re and de pins high and low out of library but still no success.i tried for days without sleep, finally fed up and posting here any help would save me. thank you.

#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);

  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

  Serial.begin(9600);
  delay(500);
  Serial1.begin(9600);
  delay(500);
  node.begin(1, Serial1);
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}


void loop()
{
  uint8_t result;
  uint16_t data[6];
  
  result = node.readInputRegisters(0x05, 4);
  Serial.print(result);//always returning 226 even when the meter is replying with valid modbus frame
  if (result == node.ku8MBSuccess)
  {
   Serial.print("success");
   for (j = 0; j < 6; j++)
    {
      data[j] = node.getResponseBuffer(j);
    }
  }

  delay(1000);
}

Hi Dharani123,
As far as I understand (If I didn't miss understand) you have no MODBUS implementation in your Arduino code.
MODBUS is a second layer protocol which works over the first layer (RS485). To able to communicate, you have to implement the MODBUS protocol, in Arduino side as well. You have to set a MODBUS address for Arduino, and power meter should communicate with that defined MODBUS address. I am sure there will be MODBUS implementation for Arduino somewhere in internet. It will be helpful also if you read about MODBUS protocol. It is a simple protocol.

You did a good job with the code, it looks like it should work but we just don’t know enough about the remainder of your installation to help. A few questions:

  1. Which Arduino board?
  2. A schematic of the connections of the Arduino to rs-485 module
  3. A link to the manual of your power meter which describes its Modbus interface

thank you for your reply ismail, isnt

node.begin(1, Serial1);

the modbus inititalization. i think i dont have any issues with the modbus initialization because im able to verify that the modbus frame is correct fom the sender and my meter is also responding (please correct me if im wrong)

sender modbus frame:

01 04 00 05 00 04 E1 C8

received modbus frame

01 04 08 00 00 01 3A D5 92 26 FF 3E 18

My problem is that its giving me a timeout response without capturing result even when the meter is giving response

Thank you for replying, the code i posted is written for atmega2560

this is how i connected my devices, i'm monitoring request and response frames via an usb rs485 module tapped on a and b lines of arduino and meter.

unfortunately its a local made meter which doesnt have any documentaion
these are the general properties of the meter

Serial parameters : 9600 baud rate,no parity eight bits

Where is the data you show as the response coming from? From the Arduino?

The 226 (0xE2) code is a timeout which implies the ModbusMaster code did not receive a response to its message.

1 Like

Arduino is sending this frame:

01 04 00 05 00 04 E1 C8

meter is sending this frame in response:

01 04 08 00 00 01 3A D5 92 26 FF 3E 18

and yes my arduino on serial port 0 is giving 226 timeout error i dont know why its not taking response from the meter, the default time out is 2 seconds in the library and the reply is immediate. so i dont know why its giving me time out even when the meter is responding.

Hi Dharani,
I have checked the answer from your power-meter. It seems that your power meter answers the request.

Part of Data Package Description Value
01 Slave address 0x01 (1)
04 Function code 0x04 (4) - Read Input Registers
08 Byte count 0x08 (8)
00 00 01 3A D5 92 26 FF Register value 0x0000 (0), 0x013A (314), 0xD592 (54674), 0x26FF (9983)
3E 18 CRC 0x3E18 (15896)

You can check it on the following parsing tool link:
https://rapidscada.net/modbus/ModbusParser.aspx

Best regards.

1 Like

Thank you so much ismail thats a really useful link.
If thats a valid response then why am i not able to parse it, why is the library throwing timeout error?

The response from Power meter seems to be valid. Your requested first word is zero, second 0x013A (314), third 0xD592 (54674) and forth 0x26FF (9983).
You need to know what do those values mean in your power meter.

i can process them to their data type(64 bit integers) once i can parse the data, my poblem is that the library is not pushing this data to getresponsebuffer ,instead its giving me a time out error

Be sure that you have defined the right MODBUS address in your Arduino. Hier it seems to be 1.

yes ismail, its right address . i can manually change the address in meter and tried with different addresses

Can you change it in Arduino side?

yes i can use this code

node.begin(1(Slave address), Serial1);

Hi Dharani,
As far as I understand, you are able to send the data via modbus from Arduino, but in your Arduino code, you can not catch the data which is answered by power meter. Have you investigated the application examples of your Modbus library? Normally an interrupt driven trigger starts the reading process. I am not sure whether your problem related to interrupt triggering, but you can investigate the issue. If reading data comes to Arduino serial bus, an interrupt must be started and the data should be taken into your input array. I think all this mechanism is defined in your Modbus library. Be sure that that the related interrupt configured rightly. For example if you change the default data ports in library, you must change the interrupt sources accordingly as well. (This is just a suggestion, I am not sure whether this is the reason of your problem)

Thats really a valid point ismail,that library is hard to read. I used this code snippet to verify the data over serial port1

If (Serial1.available()>0){
Serial.println(Serial1.read());
}

but its not printing anything i think the library is holding it up.

any help anyone

I still haven't seen a wiring diagram. It looks like a hardware problem. Either a problem with DE/RE or the wire going to the RX pin on your Arduino. Check the wires!

We need links to the used hardware (RS-485 board)!

That cannot work. Either your above code is consuming the serial traffic or the Modbus library but no both.

If the meter is indeed responding to the command, the likely problem is the RE pin is not being pulled low to enable the max485 receiver.

If the above does not help, please post photos of the board and the wiring to the Mega. We did ask earlier for a schematic which was not provided, only a block diagram which did not provide the required detail.