Help with ModBus RTU Master-Slave: SimpleModbus [SOLVED]

On the Leo you can only use the Serial1 object. Although you have done this you cannot access the Serial1 object methods as this will conflict with the library. The information should be stored in the array you initialized the packet to, in this case readRegs[4]. This array contains the unsigned int values read from the slave. Since modbus only specifies unit16 values you will have to read 2 registers per float value. You will need to shift the two consecutive unsigned integers together to form the float32 value. You can then use Serial (USB) to transmit the two registers to the PC.

So the readRegs[4] contains the 4 words read from the slave.
readRegs[0] 1st word
readRegs[1] 2nd word
readRegs[2] 3rd word
readRegs[3] 4th word

Actually i want to read the registers and store the data on SD Card.
Arduino will read the data periodically and update the file by over writing the entries in the file.
The file will act as a sort of database.
As of now just for debugging i am printing the output to Serial1.

Yes, readRegs[] contains the requested registers information.

According to the arduino product page you must use Serial for USB transmission and Serial1 for UART (modbus) on the Leo.

Hello,

I tried with the schematics from simple modbus. Didn't Work.

Tried a breakout board for RS-485. Didn't work.

Serial port hangs never enters the if condition where it checks if hardware serial is available using breakout board.

Reading output of hardware serial. Giving junk values without even connecting wires.

Please help. Thanks

Hi meetjeremy,

Again, you can not access the Serial1's objects methods directly. You must transmit the contents of readRegs[] using Serial.

If you see the third attachment in my previous post. I have done that.

Still no output :frowning:

The third attachment still uses Serail1.available() and the other one uses Serial1.read(). This wont work.

Use Serial.println(readRegs[]) or something similar like you already did to transmit the received values from Serial1 (the modbus connection). Again you cannot use Serial1.available() since it will most of the time be empty depending when you read it. The library reads the received information and stores it in the assigned register array, in this case readRegs[]. This is the only way of interfacing with the information received.

If you want to know if the request packet is successful than access the packets following information counters like this:
packet1->requests;
packet1->successful_requests;
packet1->failed_requests;
packet1->exception_errors;

Also try not to use delay() with values larger than 100ms. It will affect the polling and timeout values.

If you want to periodically send the received information from readRegs[] to Serial (USB) than rather use millis() in a timely manner or check if the value linked to the regdRegs[] index has changed.

Hello JuanB,

Thanks for the reply.

I printed this

void loop()
{
  modbus_update();
  //if (Serial1.available()){
    /// Write the received data from Serial 1 to Serial
    //Serial.println(Serial1.read());
    //Serial.println(readRegs[]);
    Serial.println(packet1->requests);
    Serial.println(packet1->successful_requests);
    Serial.println(packet1->failed_requests);
    Serial.println(packet1->exception_errors);
    //Serial.println(readRegs[1]);
  //}
  analogWrite(LED, readRegs[0]>>2);
}

but i'm getting

50
0
50
0

that is requests made 50 but all failed requests.

Even the comm. light on the meter is not blinking.

Hi meetjeremy, since the information is scattered could you please mail me your complete sketch to bester.juan@gmail.com.

Maybe I have asked this but did you connect the driver ic (or break out board) according to the RS485 connection schematic on the SimpleModbus site?

What arduino are you using?

Hello JaunB,

Thanks for the reply.

I'm using Leonardo for this project.

Yes i have connected the circuit according to the schematics.

I have sent you the code in your mail.

Hi Jeremy,

Assuming that you are referring to the ElMeasure meter LG119:

Try using the address 159 directly as some master implementations include an offset automatically.

Hello JuanB,

i tried reading for register 40159 and tried 159 also. It didn't read. I read it via rs485 usb converter also it didn't send anything. So now i'm not reading from Elmeasure.


I tried the same with Fineco (China) meter also and the readReg[] gives different values. The communication led on the meter is blinking. And when addressed on a Daisy chain only that particular meter is read. But the values are not proper.

    //Serial.println(readRegs[0]);  0
    //Serial.println(readRegs[1]);  0
    //Serial.println(readRegs[2]);  12801
    //Serial.println(readRegs[3]);  2
    //Serial.println(readRegs[4]);  259
    //Serial.println(readRegs[5]);  29
    //Serial.println(readRegs[5]);  21762
    //Serial.println(readRegs[6]);  241
    //Serial.println(readRegs[7]);  0
    //Serial.println(readRegs[8]);  0
    //Serial.println(readRegs[9]);  0
    //Serial.println(readRegs[10]);0
    //Serial.println(readRegs[11]);0

Another thing.. If i remove the 10k resistor then the communication light blinks for every 1 second properly. Else if i have the 10k resistor then the light blinks very fast continuously with very less gap.

Best thing i'm now able to see the communication light blinking, but now i don't know how to get the proper data.

Hi jeremy,

This is strange indeed, although if the code is so short and depending on the response of the slave than the led flash rate should theoretically be very quick not 1 second intervals as you have described. If I connect an led (with 220ohm resistor)on the TxRxEnable output the led will flash according to the polling rate of 200ms which is editable in the code. So rather leave the 10k in place as the 1 second interval you are perceiving is most likely the timeout of 1000ms expiring due to false reception.

Your statement: "I read it via rs485 usb converter also it didn't send anything." Are you referring that you have used another modbus implementation via an USB-RS485 converter?

Maybe the ElMeasure meter LG119 is dead?

Anyway...

Mail me the code for the Fineco (China) meter and the complete data sheet so I can have a look at the address space.

Hello JuanB,

Ya i think Elmeasure is dead. Let me check with other modbus readers.

Let me try to connect a 220ohm resistor wit led at txrxenable pin.

Ok i'll mail you the data sheet.

Thanks

Hello JaunB,

I tried the LED. Yes its flashing for every 200 ms.

Hi meetjeremy,

Have you connected GND from master to slave (from one RS485 device to other)? This is one more possibility why it's not working.
Hf, Jakob

also..

You can use hex values in the ide. Change the id, baud and parity if necessary.

#include <SimpleModbusMaster.h>

// Fineco

#define baud 9600
#define timeout 1000
#define polling 200 
#define retry_count 10

#define TxEnablePin 2 
#define LED 13

enum
{
  PACKET1,
  TOTAL_NO_OF_PACKETS,
};

Packet packets[TOTAL_NO_OF_PACKETS];
packetPointer packet1 = &packets[PACKET1];
unsigned int readRegs[1];
void setup()
{
  modbus_construct(packet1, 1, READ_HOLDING_REGISTERS, 0x011E, 1, readRegs); 
  ///// Starting serial for Leonardo
  Serial.begin(9600);
  while (!Serial) { ; }
  
  modbus_configure(&Serial1, baud, SERIAL_8E1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS);
  pinMode(LED, OUTPUT);
}

void loop()
{
  modbus_update();
  Serial.print("requests: ");    
  Serial.println(packet1->requests);
  Serial.print("successful_requests: ");  
  Serial.println(packet1->successful_requests);
  Serial.print("failed_requests: ");  
  Serial.println(packet1->failed_requests);  
  Serial.print("exception_errors: ");  
  Serial.println(packet1->exception_errors); 
  Serial.print("Active energy: ");  
  Serial.println(readRegs[0]);                          
}

Of course, missed that one, thanks Jakob. Definitely need a common reference.

No luck..

i connected with the ground of arduino to the slave.

this is the result..

requests: 10
successful_requests: 0
failed_requests: 10
exception_errors: 0
Active energy: 0

Do you think 100 ohm might be the problem.. because when i removed it, the comm. led stopped blinking.
i'll try with 120 ohm and let you know.

Thanks.

Jeremy,

If it still does not work after connecting the 120ohm resistor please measure the voltage across the 120 ohm resistor while the master driver ic (MAX485) is in receive mode. The differential voltage must be more than 200mV or less than -200mV.

Hi,

Still No output,

I have connected 120 ohm resistor.

The voltage across 120 ohm resistor is 84 mV When i measured.