I am looking for a general Modbus Master library that provides the plain Modbus messages and can easily be configured to use any Serial for transmission.
I have screened many Modbus libraries, which are either specialized for certain sensors only or hard coded to use only a given RS485 shield.
Who can recommend such a library?
Maybe you want to define this little better:
Thank you. That library begins good:
#include <ModbusMaster.h>
// instantiate ModbusMaster object
ModbusMaster node;
void setup()
{
// use Serial (port 0); initialize Modbus communication baud rate
Serial.begin(19200);
// communicate with Modbus slave ID 2 over Serial (port 0)
node.begin(2, Serial);
}
Exactly like I imagined it. Simple, universal.
You can replace Serial with whatever you need, e.g. SoftwareSerial or RS485.
But then, the "basic" example becomes gibberish.
What is the purpose of:
void loop()
{
static uint32_t i;
uint8_t j, result;
uint16_t data[6];
i++;
// set word 0 of TX buffer to least-significant word of counter (bits 15..0)
node.setTransmitBuffer(0, lowWord(i));
// set word 1 of TX buffer to most-significant word of counter (bits 31..16)
node.setTransmitBuffer(1, highWord(i));
// slave: write TX buffer to (2) 16-bit registers starting at register 0
result = node.writeMultipleRegisters(0, 2);
// slave: read (6) 16-bit registers starting at register 2 to RX buffer
result = node.readHoldingRegisters(2, 6);
// do something with data if read is successful
if (result == node.ku8MBSuccess)
{
for (j = 0; j < 6; j++)
{
data[j] = node.getResponseBuffer(j);
}
}
}
Do we need that?
Can't we just have something like:
data = node.readHoldingRegisters(start address, number of words);
?
or
node.writeCoil(start address) = true;
?
Yes, It's just an example...
It's quicker if you just describe what you need.
Rs485 is not a replacement of hardwareserial or softwareserial, it's addition to control separate hardware
I just don't understand the purpose of the indices i, j and the
node.setTransmitBuffer(0, lowWord(i));
node.setTransmitBuffer(1, highWord(i));
...
data[j] = node.getResponseBuffer(j);
Why do we need to manipulate buffers?
What is that code doing?
I just want to get some registers from sensors, eventually also set a sensor address or write to registers or coils.
For most of cases you can just ignore those. But there are many kind of ways how modbus registers are used. They can have a purpose bit by bit or have a purpose combined multiple registers. All depends on your slave modbus protocol.
I have found the half duplex example being more explicit.
I just can omit the DE/RE handling that I don't (yet) need.
The "basic" example appears being somewhat confusing.
So you want to use softwareserial without flow control(DE/RE)?
Something like this?
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
// Define software serial RX and TX pins
#define RX_PIN 2
#define TX_PIN 3
// Create a SoftwareSerial instance
SoftwareSerial mySerial(RX_PIN, TX_PIN);
ModbusMaster node;
void setup()
{
Serial.begin(9600);
mySerial.begin(9600); // Initialize software serial port
node.begin(1, mySerial); // Use software serial for Modbus communication
}
void loop()
{
uint8_t result;
uint8_t j;
result = node.readHoldingRegisters(0x0000, 10);
if (result == node.ku8MBSuccess)
{
for (j = 0; j < 10; j++)
{
Serial.println(node.getResponseBuffer(j));
}
}
else
{
Serial.print("Modbus Error: ");
Serial.println(result);
}
Serial.println("\n ------------ \n ");
delay(1000);
}
I will use SoftwareSerial on Arduinos with TTL devices using the Modbus protocol.
I will use Serial after Serial.swap() on ESP8266 with TTL devices using the Modbus protocol. (with the user communication running wirelessly using Telnetstream, since I only have one UART available)
I will use Serial1 on ESP32, which has two UARTS.
For sensors with RS485, I have smart interfaces that don't need DE/RE.
You are good to go with this library.
Esp32 has 3 uarts, I usually use Serial2
You can still use sofwareserial. If not, why to use esp8266 in the fist place?
Be aware, that softwareseril works reliably only at lower baudrates.
On an ESP8266, I have Telnetstream for the user communication and the hardware UART can be used for Modbus after Serial.swap().
(Once you have tasted the wireless user interface over Telnet, you never want to return to serial for the user communication )
Of course, I have repurposed many Esp8266 boards that doesn't need usb-serial. . I just don't understand why to choose esp8266 instead of esp32. To save 1$?
I have many PCBs ready for the WemosD1, and it has a decent ADC.
Ok, I agree for ADC.
But be aware, D1 mini is a wild west board. Some might have different voltage dividers for adc, some might have resistors on rx/tx pins making them unusable for serial etc....
either read very carefully the functions of the modbus master or define very precise what register you want to read with what function.
The more details you provide, the better we can answer your questions.
"some might have resistors on rx/tx pins making them unusable for serial"
I know what I am doing.
After Serial.swap() the UART is on D7/D8, which are plain regular input/outputs that you define as you want them.
In fact, I am frequently using the Witty board, which has the huge advantage to have the CH340 USB-serial on a separate board. You save a lot of battery power to run them without that (initial) programming board.
Which functions of the Modbus master will be used, will be defined later. I am not fixed on a given slave.