Problem in reading holding register

Hello Everyone!!!
I am trying to read holding register of a magnetic flow-meter via RS485 using Modbus RTU but unable to do. I have read many forum discussions and tried to implement them but didn't succeed.

Actually I am new to Arduino and getting so much confused by different library e.g. ModbusMaster.h and SimpleModbusMaster.h etc.

I am using TTL to RS-485 module and also have 1 arduino mega and 2 UNO.

slave id -1
baudrate -9600
format - 8N1
length - 8

It is easily giving readings using software and USB to RS485.

Please help me out and thanks in advance.

And please let me know if any other information I need to provide.

You need to provide more info ! Data sheet , circuit diagram , code …

Thank you for your response.

Data sheet - http://www.unitechvalves.com/Download/Manual%20Flow%20Meter.pdf

RS485 module - https://www.amazon.in/xcluma-MAX485-Module-Converter-Arduino/dp/B0728BTF5H

Circuit Diagram -

As I told already told that I have tried many examples. One of them is attached below....

#include<ModbusMaster.h>
#include<SoftwareSerial.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, 1);
  digitalWrite(MAX485_DE, 1);

  //My slave uses 9600 baud

  Serial.begin(9600);
  delay(10);
  Serial.println("starting arduino: ");
  Serial.println("setting up Serial ");
  Serial1.begin(9600);
  Serial.println("setting up RS485 port ");
//  slave id
  node.begin(1, Serial1);
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}

void loop() {
  uint8_t result;
//slave address and length
  result = node.readHoldingRegisters(40001, 8);
  
  Serial.println("reading");
  Serial.print("result :");
  Serial.println(result);

  if (result == node.ku8MBSuccess)
  {
    Serial.print("data : ");
    for(int i=1; i<=8; i++){
    Serial.println(node.getResponseBuffer(i));
    }
  }

  Serial.print("\n");
  
}

output:
starting arduino:
setting up RS485 port
reading
result :2

reading
result :226

reading
result :2

reading
result :226
.........

I have few more pictures but as I am new to forum its not allowing me to send them in one post.

Please let me know what is the mistake, I am doing. Thank you!!!

means 0xE2.
Modbus Master Library says:

    Modbus protocol illegal data address exception.
    
    The data address received in the query is not an allowable address for 
    the server (or slave). More specifically, the combination of reference 
    number and transfer length is invalid. For a controller with 100 
    registers, the ADU addresses the first register as 0, and the last one 
    as 99. If a request is submitted with a starting register address of 96 
    and a quantity of registers of 4, then this request will successfully 
    operate (address-wise at least) on registers 96, 97, 98, 99. If a 
    request is submitted with a starting register address of 96 and a 
    quantity of registers of 5, then this request will fail with Exception 
    Code 0x02 "Illegal Data Address" since it attempts to operate on 
    registers 96, 97, 98, 99 and 100, and there is no register with address 
    100. 
    
    @ingroup constant
    */
    static const uint8_t ku8MBIllegalDataAddress         = 0x02;

assumption: you are sending a wrong adress to the server and the server doesn't know that address

try instead:

result = node.readHoldingRegisters(0, 2);  // start with 0 and only two values

further more, print your result codes in HEX - makes debugging easier.
See the file ModbusMaster.h for all response codes.

Thank you for your suggestion.
I have implemented this and printed output in hex but same error again.

result = node.readHoldingRegisters(0, 2);  // start with 0 and only two values
Serial.println(result,HEX);

what should I do now??

you are on a Mega.
you don't need and don't use soft serial - remove that
you use Serial1. --> but you miss a Serial1.begin(xxx)

you are setting your enable lines to 1 in setup()
The halfduplex example uses 0.

  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

double check and tripple check your wiring.
I would connect a RS485 - USB Adapter to the RS485-TTL Adapter and just open a Plain Serial Programm (like Coolterm) to see in HEX what the client is really sending.

As per your advise I have updated my code and reconnect and recheck the wiring.
Please see and correct me If I am wrong.

#include<ModbusMaster.h>
#include<SoftwareSerial.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() {

  Serial1.begin(9600);

  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);

  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

  //My slave uses 9600 baud
  delay(10);
  Serial.println("starting arduino: ");
  Serial.println("setting up Serial ");
  Serial.println("setting up RS485 port ");
//  slave id
  node.begin(1, Serial1);
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}

void loop() {
  uint8_t result;
  
//slave address and length
  result = node.readHoldingRegisters(0,2);
  Serial.print("result :");
  Serial.println(result);
 ;

  if (result == node.ku8MBSuccess)
  {
    Serial.print("data : ");
    for(int i=1; i<=8; i++){
    Serial.println(node.getResponseBuffer(i));
    }
  }

  Serial.print("\n");
  
}

I have used modscan software and the output is given below

and the actual reading should be - "4.337 m^3"

I have used another software to read modbus and attaching it please have a look on it and help me.

Is there anyone who can help me out please.

it will not solve your problem but now you miss a

Serial.begin(9600);

for your debug printing. And you still include Softserial. Remove that.

What I see on your screenshots, it seems you send to register 12292, 12293, (+40001) - but I can't see that in your code.
The Screenshots in #7 and #8 show that you request 8 bytes - but that is not in the Code you posted in #7.

We can only see the information you provide - but that doesn't look consistant.

Can you provide a datasheet of your sensor which points out the real registers?

Have you terminated your bus line with resistor(s)?

Yes I modified the code as per your suggestion now its giving the desired output. Thank you so much @noiasca for giving your precious time.

Good to hear you got it working.
Please post your final "working" prototype also.

Here it is.....

#include<ModbusMaster.h>
#include<SoftwareSerial.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() {
  
  Serial.begin(9600);
  Serial2.begin(9600);

  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);

  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

  //My slave uses 9600 baud
  delay(10);
  Serial.println("starting arduino: ");
  Serial.println("setting up Serial ");
  Serial.println("setting up RS485 port ");
//  slave id
  node.begin(1, Serial2);
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}

void loop() {
  uint16_t result;
  
//slave address and length
  result = node.readHoldingRegisters(400001,8);

  if (result == node.ku8MBSuccess)
  {
      Serial.print("Analyzer : ");
      Serial.println(node.getResponseBuffer(1));
      Serial.print("Flow : ");
      Serial.println(node.getResponseBuffer(2));
  }

  Serial.print("\n");
  
}