ArduinoModbus for other shields and with different Serial port

Hi everybody,
If anyone gonna use "ArduinoModbus" library with simple RS485 modules or any shield other than "MKR 485 SHIELD", here is some simple modification to "RS485.cpp" and "RS485.h" files in "ArduinoRS485" library.
Normally you can find these files in this path:
C:\Users\YOUR_USERNAME\Documents\Arduino\libraries\ArduinoRS485\src
For this, you will need to add some functions to these files,
first, you will need to add function bodies to the CPP file. Here is what you need to add:

void RS485Class::setSerial(HardwareSerial* serial)
{
  _serial = serial;
}

Also, add the function prototype to the class in the .h file:

void setSerial(HardwareSerial* serial);

Now save these files and go to one of the examples from "ArduinoModbus" library. apply these definitions to your code:

#define SERIAL_PORT_HARDWARE Serial1
#define RS485_DEFAULT_TX_PIN  18
#define RS485_DEFAULT_DE_PIN  22
#define RS485_DEFAULT_RE_PIN  23

you can change these values to other pins to match your project.
Now apply these codes before the "begin" method for "ModbusRTUClient" or "ModbusRTUServer".

RS485.setPins(RS485_DEFAULT_TX_PIN, RS485_DEFAULT_DE_PIN, RS485_DEFAULT_RE_PIN);
RS485.setSerial(&SERIAL_PORT_HARDWARE);

Upload your code to Arduino and Enjoy.

Doesn't work with esp8266 weimos d1 mini:


#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
#include <ArduinoModbus.h>

#define SERIAL_PORT_HARDWARE Serial1
#define RS485_DEFAULT_TX_PIN  1
#define RS485_DEFAULT_DE_PIN  5
#define RS485_DEFAULT_RE_PIN  4

int counter = 0;
int id = 2; // pozowoli na szybką zmiane adresu urządzeń więc tam gedzie widzisz "id"  przypisana bedzie własnie ta liczba

void setup() {
  RS485.setPins(RS485_DEFAULT_TX_PIN, RS485_DEFAULT_DE_PIN, RS485_DEFAULT_RE_PIN);
  RS485.setSerial(&SERIAL_PORT_HARDWARE);
  Serial.begin(9600);
  while (!Serial);

  Serial.println("Modbus RTU Client Kitchen Sink");

  // start the Modbus RTU client
  if (!ModbusRTUClient.begin(9600)) {
    Serial.println("Failed to start Modbus RTU Client!");
    while (1);
  }
}

void loop() {



// składnia ramki modbus 
//ModbusRTUClient.holdingRegisterWrite(1,0x0001,0x0100);
//to polecenie odpowiada polecnenu modbus 6 tzn. zapis do pojedyńczego rejestru ModbusRTUClient.holdingRegisterWrite(to adres urządenia 1, to nr rejestru 0x0001, to wartośc jaka ma być przypisana w rejestrze 0x0100);
// innymi słowy wysyłamy polecenie 01 06 0001 0100 (suma kontrolna jest obliczana automatycznie)  

ModbusRTUClient.holdingRegisterWrite(2,0x0001,0x0100);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(2,0x0002,0x0100);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(2,0x0003,0x0100);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0004,0x0100);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0005,0x0100);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0006,0x0100);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0007,0x0100);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0008,0x0100);
delay(1000);

ModbusRTUClient.holdingRegisterWrite(id,0x0001,0x0200);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0002,0x0200);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0003,0x0200);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0004,0x0200);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0005,0x0200);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0006,0x0200);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0007,0x0200);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0008,0x0200);
delay(1000);

ModbusRTUClient.holdingRegisterWrite(2,0x0001,0x0100);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(2,0x0002,0x0100);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(2,0x0003,0x0100);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0004,0x0100);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0005,0x0100);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0006,0x0100);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0007,0x0100);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0008,0x0100);
delay(1000);

delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0001,0x0100);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0002,0x0100);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0003,0x0100);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0004,0x0100);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0005,0x0100);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0006,0x0100);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0007,0x0100);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0008,0x0100);
delay(1000);

ModbusRTUClient.holdingRegisterWrite(id,0x0001,0x0200);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0002,0x0200);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0003,0x0200);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0004,0x0200);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0005,0x0200);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0006,0x0200);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0007,0x0200);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0008,0x0200);
delay(1000);


delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0001,0x0100);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0002,0x0100);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0003,0x0100);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0004,0x0100);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0005,0x0100);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0006,0x0100);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0007,0x0100);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0008,0x0100);
delay(1000);

ModbusRTUClient.holdingRegisterWrite(id,0x0007,0x0400);


ModbusRTUClient.holdingRegisterWrite(id,0x0002,0x0100);
delay(1);

ModbusRTUClient.holdingRegisterWrite(id,0x0004,0x0100);
delay(1);

ModbusRTUClient.holdingRegisterWrite(id,0x0006,0x0100);
delay(1);

ModbusRTUClient.holdingRegisterWrite(id,0x0008,0x0100);
delay(1000);

ModbusRTUClient.holdingRegisterWrite(id,0x0001,0x0300);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0002,0x0300);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0003,0x0300);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0004,0x0300);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0005,0x0300);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0006,0x0300);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0007,0x0300);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0008,0x0300);
delay(1000);


ModbusRTUClient.holdingRegisterWrite(id,0x0001,0x0300);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0002,0x0300);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0003,0x0300);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0004,0x0300);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0005,0x0300);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0006,0x0300);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0007,0x0300);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0008,0x0300);
delay(1000);

ModbusRTUClient.holdingRegisterWrite(id,0x0001,0x0300);
delay(500);
ModbusRTUClient.holdingRegisterWrite(id,0x0002,0x0300);
delay(20);
ModbusRTUClient.holdingRegisterWrite(id,0x0003,0x0300);
delay(1000);
ModbusRTUClient.holdingRegisterWrite(id,0x0004,0x0300);
delay(100);
ModbusRTUClient.holdingRegisterWrite(id,0x0005,0x0300);
delay(80);
ModbusRTUClient.holdingRegisterWrite(id,0x0006,0x0300);
delay(300);
ModbusRTUClient.holdingRegisterWrite(id,0x0007,0x0300);
delay(800);
ModbusRTUClient.holdingRegisterWrite(id,0x0008,0x0300);
delay(1000);

ModbusRTUClient.holdingRegisterWrite(id,0x0001,0x0200);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0002,0x0200);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0003,0x0200);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0004,0x0200);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0005,0x0200);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0006,0x0200);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0007,0x0200);
delay(1);
ModbusRTUClient.holdingRegisterWrite(id,0x0008,0x0200);
delay(1);

int zmienna = 0;

while (zmienna < 10)
{
ModbusRTUClient.holdingRegisterWrite(2,0x0001,0x0100);
delay(100);
ModbusRTUClient.holdingRegisterWrite(2,0x0002,0x0100);
delay(100);
ModbusRTUClient.holdingRegisterWrite(2,0x0003,0x0100);
delay(100);
ModbusRTUClient.holdingRegisterWrite(id,0x0004,0x0100);
delay(100);
ModbusRTUClient.holdingRegisterWrite(id,0x0005,0x0100);
delay(100);
ModbusRTUClient.holdingRegisterWrite(id,0x0006,0x0100);
delay(100);
ModbusRTUClient.holdingRegisterWrite(id,0x0007,0x0100);
delay(100);
ModbusRTUClient.holdingRegisterWrite(id,0x0008,0x0100);
delay(100);

ModbusRTUClient.holdingRegisterWrite(id,0x0008,0x0200);
delay(100);
ModbusRTUClient.holdingRegisterWrite(id,0x0007,0x0200);
delay(100);
ModbusRTUClient.holdingRegisterWrite(id,0x0006,0x0200);
delay(100);
ModbusRTUClient.holdingRegisterWrite(id,0x0005,0x0200);
delay(100);
ModbusRTUClient.holdingRegisterWrite(id,0x0004,0x0200);
delay(100);
ModbusRTUClient.holdingRegisterWrite(id,0x0003,0x0200);
delay(100);
ModbusRTUClient.holdingRegisterWrite(id,0x0002,0x0200);
delay(100);
ModbusRTUClient.holdingRegisterWrite(id,0x0001,0x0200);
delay(100);

  zmienna++;
}

}

error:

C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.cpp: In member function 'virtual void RS485Class::begin(long unsigned int, uint16_t, int, int)':
C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.cpp:72:28: error: invalid conversion from 'uint16_t' {aka 'short unsigned int'} to 'SerialConfig' [-fpermissive]
   72 |   _serial->begin(baudrate, config);
      |                            ^~~~~~
      |                            |
      |                            uint16_t {aka short unsigned int}
In file included from C:\Users\bubuq3\Documents\ArduinoData\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/Arduino.h:288,
                 from C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.h:23,
                 from C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.cpp:20:
C:\Users\bubuq3\Documents\ArduinoData\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/HardwareSerial.h:78:49: note:   initializing argument 2 of 'void HardwareSerial::begin(long unsigned int, SerialConfig)'
   78 |     void begin(unsigned long baud, SerialConfig config)
      |                                    ~~~~~~~~~~~~~^~~~~~
C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.cpp: In member function 'void RS485Class::sendBreak(unsigned int)':
C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.cpp:168:29: error: invalid conversion from 'uint16_t' {aka 'short unsigned int'} to 'SerialConfig' [-fpermissive]
  168 |   _serial->begin(_baudrate, _config);
      |                             ^~~~~~~
      |                             |
      |                             uint16_t {aka short unsigned int}
In file included from C:\Users\bubuq3\Documents\ArduinoData\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/Arduino.h:288,
                 from C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.h:23,
                 from C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.cpp:20:
C:\Users\bubuq3\Documents\ArduinoData\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/HardwareSerial.h:78:49: note:   initializing argument 2 of 'void HardwareSerial::begin(long unsigned int, SerialConfig)'
   78 |     void begin(unsigned long baud, SerialConfig config)
      |                                    ~~~~~~~~~~~~~^~~~~~
C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.cpp: In member function 'void RS485Class::sendBreakMicroseconds(unsigned int)':
C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.cpp:178:29: error: invalid conversion from 'uint16_t' {aka 'short unsigned int'} to 'SerialConfig' [-fpermissive]
  178 |   _serial->begin(_baudrate, _config);
      |                             ^~~~~~~
      |                             |
      |                             uint16_t {aka short unsigned int}
In file included from C:\Users\bubuq3\Documents\ArduinoData\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/Arduino.h:288,
                 from C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.h:23,
                 from C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.cpp:20:
C:\Users\bubuq3\Documents\ArduinoData\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266/HardwareSerial.h:78:49: note:   initializing argument 2 of 'void HardwareSerial::begin(long unsigned int, SerialConfig)'
   78 |     void begin(unsigned long baud, SerialConfig config)
      |                                    ~~~~~~~~~~~~~^~~~~~
In file included from C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.cpp:20:
C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.cpp: At global scope:
C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.h:35:30: error: 'A6' was not declared in this scope; did you mean 'A0'?
   35 | #define RS485_DEFAULT_DE_PIN A6
      |                              ^~
C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.cpp:194:62: note: in expansion of macro 'RS485_DEFAULT_DE_PIN'
  194 | RS485Class RS485(SERIAL_PORT_HARDWARE, RS485_DEFAULT_TX_PIN, RS485_DEFAULT_DE_PIN, RS485_DEFAULT_RE_PIN);
      |                                                              ^~~~~~~~~~~~~~~~~~~~
C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.h:36:30: error: 'A5' was not declared in this scope; did you mean 'A0'?
   36 | #define RS485_DEFAULT_RE_PIN A5
      |                              ^~
C:\Users\bubuq3\Documents\Arduino\libraries\ArduinoRS485\src\RS485.cpp:194:84: note: in expansion of macro 'RS485_DEFAULT_RE_PIN'
  194 | RS485Class RS485(SERIAL_PORT_HARDWARE, RS485_DEFAULT_TX_PIN, RS485_DEFAULT_DE_PIN, RS485_DEFAULT_RE_PIN);
      |                                                                                    ^~~~~~~~~~~~~~~~~~~~
exit status 1
Błąd kompilacji dla płytki NodeMCU 0.9 (ESP-12 Module).

Hi,
Yes, you have to do these modifications:
first: you have used the "Serial" device for debugging and Modbus at the same time! It is not possible, because ESP8266 has only one HARDWARE_UART and you have to use it for Modbus communications. So if you need a debug console, you can create a "SoftwareSerial" for that. Note that you can't use "SoftwareSerial" for Modbus. Also, there is no Serial1 in ESP8266 modules. Change the code:

#define SERIAL_PORT_HARDWARE Serial1

to this:

#define SERIAL_PORT_HARDWARE Serial

Also, you need to make some changes to the library. Go to RS485.cpp file and find these functions:

void RS485Class::begin(unsigned long baudrate, uint16_t config, int predelay, int postdelay);
void RS485Class::sendBreak(unsigned int duration);
void RS485Class::sendBreakMicroseconds(unsigned int duration);

Change the last line of these functions like this:

_serial->begin(_baudrate);

Build the files and you are good to go. In case of any other problems, post it here and update the ESP8266 board package in Tools>>Board>>Boards manager.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.