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

long answer:

I want to be able to read and write data from these devices from a remote site on a website.

the simplemodbus Master library - we are talking about in this thread - is perfect for reading data over and over again. It's not the preferred way to write data once. Therefore, if you want to write single values to your slave, you should search for another library.

I don't have the time to develop my own

sure?

It's as simple as that: out of three given parameters

  • time to be invested by you
  • money for the project
  • expectations to the final product

you can either invest more money or you reduce your expectations if you have no time.

and I don't want a product that is not flexible, I want a device that
will be programmable. With such a community, I believe you can help me.

If you have a look at some of the modbus test tools for PCs, you'll see how complex a "flexible" software is. You might be able to imagine what work would be necessary to do something similar on an Arduino. I assume most of us only have implementations for their specific requirements, with limited support of their needed slave devices. I don't say that it wouldn't be possible, but for what use case? Either I need something dedicated for my purpose - or something to test my slaves. And if I want to test, I choose my PC.

So my final advices:

  • Consider to invest LOT OF YOUR TIME.
  • If you need support for your devices, post a CLICKABLE link to the manual, where we can clearly see the modbus registers. Tell us the exact page, where this information starts.
  • tell us, for what hardware platform you are developing,
  • provide a schematic of your wiring and a real picture of your setup
  • State a clear question, clear enough for even for non-native speakers like me :wink:

caddish12:
Hi JPrust,

Maybe you will need this line of code:

modbus_configure(&Serial, 19200, SERIAL_8N2, DEVICE_ID, TxEnablePin, HOLDING_REGS_SIZE, holdingRegs);

// modbus_update_comms(baud, byteFormat, id) is not needed but allows for easy update of the
// port variables and slave id dynamically in any function.
modbus_update_comms(19200, SERIAL_8N2, 1);






As you declared in your code, register of VAL_LED is READ register (address 0) and VAL_POT(address 1) is WRITE register. So, in HMI you can access with address 40001 for VAL_LED (HMI write value into this register such as button input) and 40002 for VAL_POT(HMI will read from this register such as number display?).

Why 40001 and 40002? Because in Delta HMI register address, address 0 will be 40001, so if you need to access register 10, it will be 40011 in Delta HMI. and the data will be WORD.

Hop it will help.

Thanh Nguyen

caddish12:
Hi JPrust,

Maybe you will need this line of code:

modbus_configure(&Serial, 19200, SERIAL_8N2, DEVICE_ID, TxEnablePin, HOLDING_REGS_SIZE, holdingRegs);

// modbus_update_comms(baud, byteFormat, id) is not needed but allows for easy update of the
// port variables and slave id dynamically in any function.
modbus_update_comms(19200, SERIAL_8N2, 1);




As you declared in your code, register of VAL_LED is READ register (address 0) and VAL_POT(address 1) is WRITE register. So, in HMI you can access with address 40001 for VAL_LED (HMI write value into this register such as button input) and 40002 for VAL_POT(HMI will read from this register such as number display?).

Why 40001 and 40002? Because in Delta HMI register address, address 0 will be 40001, so if you need to access register 10, it will be 40011 in Delta HMI. and the data will be WORD.

Hop it will help.

Thanh Nguyen

caddish12:
Hi JPrust,

Maybe you will need this line of code:

modbus_configure(&Serial, 19200, SERIAL_8N2, DEVICE_ID, TxEnablePin, HOLDING_REGS_SIZE, holdingRegs);

// modbus_update_comms(baud, byteFormat, id) is not needed but allows for easy update of the
// port variables and slave id dynamically in any function.
modbus_update_comms(19200, SERIAL_8N2, 1);




As you declared in your code, register of VAL_LED is READ register (address 0) and VAL_POT(address 1) is WRITE register. So, in HMI you can access with address 40001 for VAL_LED (HMI write value into this register such as button input) and 40002 for VAL_POT(HMI will read from this register such as number display?).

Why 40001 and 40002? Because in Delta HMI register address, address 0 will be 40001, so if you need to access register 10, it will be 40011 in Delta HMI. and the data will be WORD.

Hop it will help.

Thanh Nguyen

caddish12:
Hi JPrust,

Maybe you will need this line of code:

modbus_configure(&Serial, 19200, SERIAL_8N2, DEVICE_ID, TxEnablePin, HOLDING_REGS_SIZE, holdingRegs);

// modbus_update_comms(baud, byteFormat, id) is not needed but allows for easy update of the
// port variables and slave id dynamically in any function.
modbus_update_comms(19200, SERIAL_8N2, 1);




As you declared in your code, register of VAL_LED is READ register (address 0) and VAL_POT(address 1) is WRITE register. So, in HMI you can access with address 40001 for VAL_LED (HMI write value into this register such as button input) and 40002 for VAL_POT(HMI will read from this register such as number display?).

Why 40001 and 40002? Because in Delta HMI register address, address 0 will be 40001, so if you need to access register 10, it will be 40011 in Delta HMI. and the data will be WORD.

Hop it will help.

Thanh Nguyen

Hi vietnam friend you made the tube modbus communication dop panel, send me the arduino library
Mail.: ismailsef@gmail.com

Send me the dop panel delta display software + arduino libraries + circuit diagram

Hi my friend you made the tube modbus communication dop panel program send me the arduino library

Hi, I'm beginning to get very frustrated with loading modbus on to arduinos. I've used them for a number of years but now I need to use the 485 protocol.

After various false starts with the old libraries that the internet throws up I have just come across this thread and the 'simple-modbus-master' libraries. So I'm trying to use 'SimpleModbusMasterV2rev2' and 'SimpleModbusSlaveV10'. The examples given seem to be a compatible pair designed to talk to each other, something sadly lacking in the other things that my trawl has thrown up

However, I can't get the thing to compile for a Leonardo.

The Slave code fails with @C:\Applications\Arduino\arduino-1.6.8\libraries\SimpleModbusSlaveV10\examples\SimpleModbusSlaveArduino\SimpleModbusSlaveArduino.ino: In function 'void setup()':

SimpleModbusSlaveArduino:83: error: cannot convert 'Serial_' to 'HardwareSerial' for argument '1' to 'void modbus_configure(HardwareSerial*, long int, unsigned char, unsigned char, unsigned char, unsigned int, unsigned int*)'

modbus_configure(&Serial, 9600, SERIAL_8N2, 1, 2, HOLDING_REGS_SIZE, holdingRegs);

Ive also tried IDE 1.8.9

Now early on in this thread JUGmobile says

'Leonardo as master:
In SimpleModbusMaster.cpp few lines of code needs to be changed. Since Leonardo uses Serial.xxx command for communicating over USB with computer, and Serial1.xxx for TX1/RX1 for communication with other arduinos (including this modbus protocol), the Serial.xxx needs to be changed to Serial1.xxx.'

Leonardo as slave:
In SimpleModbusSlave.cpp few lines of code needs to be changed. Exactly the same solution. Serial.xxx needs to be changed to Serial1.xxx.

What is unclear is does this change have to be made in the sketch or the library code. The only mention of Serial in the slave example is

"modbus_configure(&Serial, 9600, SERIAL_8N2, 1, 2, HOLDING_REGS_SIZE, holdingRegs);"

So does &Serial need to become &Serial1. Or have I got to dismantle the .h and .cpp files?

Dear all,
Could please anyone guide me how can I adapt the arduino modbus library (preferably Modbus-Master-Slave-for-Arduino-master) for the STM32 BluePill board?
Thanks in advance.

HII

I am new to the modbus can u please say i want to use arduino as a master and my pc as a slave and i want to communicate both of them
Thanks in advance.

Hi All,
i was try simplemodbus with power meter, i can read(receive all data) from my power meter, but sometimes i get garbage value in my monitor.

i read 15 address
baud 9600
timeout 1000
polling 400 // the scan rate
retry_count 600
interval millis 10000

please help me and give me solution

thanks All

Hello Juan Sir,

I have read the threads, I really appreciate your patience and help to the people regarding Modbus protocol.

Im also trying to read elmeasure LG1129 energy meter data through Arduino Mega and RS485 to TTL converter. I used your Eastron_SDM320M.ino and modified holding register address value as per elmeasure meter specs.

Trying from past one month still no success. I guess there is a problem in modbus library.

I downloaded two simple modbus libraries from the below links:

https://github.com/angeloc/simplemodbusng- this library produces 'modbus_construct' was not declared in this scope compilation error

https://github.com/jecrespo/simple-modbus/tree/master/Modbus%20RTU%20libraries%20for%20Arduino- this library produces packetpointer was not declared in this scope compilation error

The errors are w.r.t Eastron_SDM320M.ino program. Please let me know which library you used for compiling your program.

The same problem repeats for Elmeasure BM5410 and Schneider EM6400NG meters. I hope both Arduino Mega and RS485 to TTL converter are ok from hardware point of view.

Please help me

JuanB:
Hi sbeghers,

I have attached the sketch that you can test with on the Eastron SDM320M. It will read the line to neutral voltage on Serial and than print the float value on Serial1.

I think you said you were using a mega 2560...

Hello Juan, read your many posts and glad to have a guy like you in open source community. Thanks for your help to many.

I am stuck with reading data from my energy meter for about a month. I have tried many things/programs. But still cannot read data till now. I seek your help. Please reply and I will share details with you.
Thank you.

By the way, I am using Arduino mega 2650. and trying to read ELmeasure meter.
From Modbus tester software I am getting results successfully. https://photos.app.goo.gl/xmgm7CEy7VauBQpX7

But from Arduino, I cannot read the register value. Maybe my code is wrong. I am getting error code 2 as: https://photos.app.goo.gl/dWgKTUT3uuDbSHbq6

My code is: new 20.ino - Google Drive

I am using a max 485 module for communication between Arduino and energy meter.

Many thanks to you in advance.

hello
This is the example code project about Modbus TCP, Modbus RTU

Read coil status.
Read input status.
Read holding registers.
Read input registers.
Write single coil.
Write single register.
Write multiple registers.
Write multiple coils.
...
See full the code here

Hi their,

i'm getting RS-485 Data, using below code.

#include<SimpleModbusMaster.h>
//////////port infromation///////////
#define baud 9600
#define timeout 100
#define polling 100 // the scan rate
#define retry_count 10

// used to toggle the receive/transmit pin on the driver
#define TxEnablePin 2
// the total amount of avaliable memory on the master to store data
#define TOTAL_NO_OF_REGISTERS 10

//this is the esiar way to creat new packet
//add as many as you want . TOTAL_NO_OF_PACKETS
// is automatically updated.

enum
{
PACKET1,
PACKET2,
PACKET3,
PACKET4,
// PACKET 2,
TOTAL_NO_OF_PACKETS //leave this last entry
};

//creat an array of packets to be configured
Packet packets[TOTAL_NO_OF_PACKETS];
//Master Register array
unsigned int regs[TOTAL_NO_OF_REGISTERS];
long temp = (long)regs[0] << 16 | regs[1];

void setup()
{
//Initialize each packets
Serial.begin(9600);

modbus_construct(&packets[PACKET1], 2, READ_INPUT_REGISTERS, 0, 7, 0);

//Initialize the modbus finite state machine
modbus_configure(&Serial, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);

}

void loop()
{
modbus_update();
Serial.println("");
Serial.println("");
Serial.println("");
Serial.print("*ARDUINO AS MODBUS-RTU");
Serial.println("");
Serial.println("");
Serial.print("successful_requests:");
Serial.print(packets[PACKET1].successful_requests );
Serial.println("");
Serial.print("failed_requests: ");
Serial.print(packets[PACKET1].failed_requests );
Serial.println("");
Serial.print("ROOM_TEMP : ");
Serial.print(regs[0]);
Serial.print(" DegC");
delay(1000);
}

here i'm getting Input registers (3x0000) first address value only. (30001 register showing data)

i want to access 30002, 30003, 30004 how i can get these address?

please once check above code and tell me how to get multiple address.

thank you....

you are reading already 7 registers and store them form register 0 onwards.
so they will get stored in regs[0] to regs[6]
you only print regs[0]

if you print to print also regs[1] to regs[4] you might see 30002, 30003, 30004.

P.S.: Please use code-tags when posting code.

Dear sirs,

I try implement modbus slave in ESP32 Wroom. Do you have any examples of how the ESP32 Wroom works?

Hello Guys, I'm having problems with the SimpleModbusSlave V10 library and I'm not able to find out why. I am trying to carry out the communication of a mega arduino with the ScadaBR software, the arduino being the slave and ScadaBR the master. The code I'm using is the library's own example and I use an rs485 shield to make the communication interface. The problem is that the network master sends the request but the slave sends wrong messages, generating an error. I am using software that monitors the serial port and to visualize that the slave's response contains wrong bytes at the beginning. I already looked at the code and the library to find out the reason but I was not successful. I noticed that people here are right inside this library, could they help? I would love to use it for my projects.

I am going to hash up an old dead thread. I am using this library now with some success so wanted to share. I am using this Master library to get information from a slave over RS-232. I am currently able to send messages but am not receiving messages properly yet.

My Arduino MEGA is hooked up to an RS-232 to TTL converter.

I have hooked up an oscilloscope that has an RS-232 decoder. I have confirmed that the transmit messages are correct leaving the TTL to RS-232 converter. I am also getting a response back from the slave that is appropriate. I am not getting a stored response in the Arduino yet though. I haven't had a chance to further troubleshoot the problem yet but I suspect something is going on between the converter and the Arduino MEGA.

I just wanted to report success using this library. I got a different RS232 to TTL converter that uses the SP3232E chip. The previous converter I had used a knockoff MAX3232 and the chip did not work at all.

That chip/adapter along with this library is allowing me to communicate with a Morningstar Tristar MPPT solar charge controller over RS-232.

Hello ... my name is Nelson, I searched a lot on the internet about this ghds100e equipment for programming in the Siemens TIA PORTAL software and I can't find anything ... I need help ... I can't read the equipment ... do you have any manuals ? can you send me please? ... He asked for an access code, do you know what it is? nelson.ncof@gmail.com. thank you

I am new on arduino modbus

I am trying to communicate energy meter's MWH register via arduino SimpleModbusMaster library which is at address 178 [(40179-40001)(address-offset)], meter ID 1, Function code 3.
Meter is not replying.
So I checked Arduino modbus request output in PuTTy which is 01 03 c2 b2 01 24 2d

But as per modbus it should be 01 03 00 B2 00 01 24 2D

Same is cross verified using Simply Modbus Master and found communicating with request 01 03 00 B2 00 01 24 2D

So why c2 in request (register address)
00 are missing after b2 (Total no of registers to be read)
As CRC (24 2D) is identical in both cases background calculation is correct.

Below is my code

#include <SimpleModbusMaster.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 20 chars and 4 line display

//////////////////// Port information ///////////////////
#define baud 9600
#define timeout 1000
#define polling 200 // the scan rate
#define retry_count 10

// used to toggle the receive/transmit pin on the driver
#define TxEnablePin 2 

// The total amount of available memory on the master to store data
#define TOTAL_NO_OF_REGISTERS 1

// This is the easiest way to create new packets
// Add as many as you want. TOTAL_NO_OF_PACKETS
// is automatically updated.
enum
{
PACKET1,
// PACKET2,
TOTAL_NO_OF_PACKETS // leave this last entry
};

// Create an array of Packets to be configured
Packet packets[TOTAL_NO_OF_PACKETS];

// Masters register array
unsigned int regs[TOTAL_NO_OF_REGISTERS];

void setup()
{
lcd.init();
// Initialize each packet
modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 178, 1, 0); //
//  modbus_construct(&packets[PACKET2], 1, PRESET_MULTIPLE_REGISTERS, 1, 1, 0);

// Initialize the Modbus Finite State Machine
modbus_configure(&Serial, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);

// pinMode(LED, OUTPUT);
}

void loop()
{
modbus_update();

regs[0] = analogRead(0); // update data to be written to arduino slave

//analogWrite(LED, regs[0]>>2); // constrain adc value from the arduino slave to 255
lcd.setCursor(1,0); lcd.print(regs[0], HEX);
lcd.setCursor(1,1); lcd.print(regs[1], HEX);
lcd.setCursor(1,3); lcd.print("size of array=");  lcd.print(sizeof(regs));
  
}

(In the futures, please use the Code Tags button, </> on the menu, for posting your code. Thanks - Moderator)

1 Like