Please fill the info fields, it helps to get you faster support ;)
If you have a Guru Meditation Error, please decode it:
https://github.com/me-no-dev/EspExceptionDecoder
----------------------------- Remove above -----------------------------
Board: ?DOIT V1 ESP32 Dev Module?
Core Installation/update date: ?11/jul/2017?
IDE name: ?Arduino IDE? ?Platform.io? ?IDF component?
Flash Frequency: ?40Mhz?
Upload Speed: ?115200?
I'm using modbusmaster library to communicate with some Modbus slave. I initially used hardwareserial(2) because I thought serial1 was for communicating to Arduino IDE. With serial2 I only got response from the Modbus slave the first time after reboot. When I use Serial1 UART it works fine.
this has been reported earlier: [https://github.com/espressif/arduino-esp32/issues/650]
//Change the code below by your sketch
#include <Arduino.h>
void setup() {
}
void loop() {
}
Enable Core debug level: Debug on tools menu of Arduino IDE, then put the serial output here
I tried using the default UART2 pins 16 and 17, no improvement.
Wich modbusmaster library are you using?
You should include the important parts of your code.
Hi,
I'm using the https://github.com/4-20ma/ModbusMaster)
these are parts of my code:
global:
`#include <HardwareSerial.h>
#include <ModbusMaster.h>
HardwareSerial Serial2(1);
#define Serial2TxControl 4 //RS485 Direction control
#define RS485Transmit HIGH
#define RS485Receive LOW
ModbusMaster node;
```setup:
Serial.begin(115200);
pinMode(Serial2TxControl, OUTPUT);
//delay(10);
Serial2.setDebugOutput(HIGH);
Serial2.begin(19200,SERIAL_8N1,16,17);
node.begin(4,Serial2);
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
loop:
`node.readHoldingRegisters(20100,64)
node.getResponseBuffer(i)
Now when I change
HardwareSerial Serial2(1); to HardwareSerial Serial2(2); The code runs once after reboot, it sends out data, but I think it's corrupt because Modbus slave doesn't respond. The hardwareserial (1) runs fine for several days now. Important: you need to add a delay in the 'posttransmission' routine so the driver stays on a few ms longer, depending on your baudrate speed.
And although the common MAX485 Arduino board is specified for TTL use, it runs fine at CMOS levels (and powered by 3.3V).
same issue for me
only the first message is sent correctly throught UART2, followings packet are garbled with other data
I dont't what this data is
using UART1 works forever
Most likely it's related to hardware issue of UART2.
https://github.com/espressif/esp-idf/issues/1202#issuecomment-342691402
RS485 communication using ESP32's UART2 hits this problem as it needs to flush send buffer to exit RTS state.
In esp-idf, workaround has been applied but not in Arduino-ESP32.
In my case, I abandoned using Arduino-ESP32's HardwareSerial and used esp-idf's uart library instead by including driver/uart.h. (Implementing modbus by my own was a bit pain in the ass, though)
@shimarin maybe you are right about the hardware bug.. could you extend and apply the workaround on the Arduino HardwareSerial library too?
@baggior Well, I wish I was someone who could do it. Rewriting my code to use esp-idf's uart library was the best I could do.
who could correct the HardwareSerial library and include the uart fix, then?
@me-no-dev ?
yes, having only UART1, (most of us use UART0 for IDE communication) feels like a limitation on ESP32. Hopefully someone with the right skillset can fix this.
I think there have been some changes lately, does this problem still persist?
this problem still persist
JacoFourie got all three UARTS working, you need to add a serial.flush() in the pretransmission routine. I haven't tested it.
https://github.com/4-20ma/ModbusMaster/issues/96#issuecomment-368253172
@TLS1000 thank you for your reply.
below works well.
HardwareSerial uart(2);
...
loop(){
uint8_t data[11] = {0x01, 0x10, 0x01, 0x02, 0x00, 0x01, 0x02, 0x00, 0x09, 0x77, 0x74};
uart.write(data, 11);
}
output
01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41 01 10 01 01 00 01 02 00 00 B7 41
but let me add a line of code., it output garbled data.
HardwareSerial uart(2);
...
loop(){
uint8_t data[11] = {0x01, 0x10, 0x01, 0x02, 0x00, 0x01, 0x02, 0x00, 0x09, 0x77, 0x74};
uart.write(data, 11);
uart.flush(); // next loop output garbled data.
}
output
01 10 01 01 00 01 02 00 00 B7 41 46 27 1A 9D E6 ED 1D AE 01 25 B1 7D 4B 83 CE A1 5A A8 54 67 30 92 38 6F DA 33 C1 A5 B5 6B BA 6A AD A3 BC 04 D6 33 F9 56 C7 CB C3 A6 97 FE 65 56 AB AF 77 6B 5C 56 CA 4A 57 85 65 AB FF 80 A4 95 2A 06 EB BF CB 84 34 17 2E 76 E1 B1 62 D0 21 3B 83 3E F9 61 20 BF B0 DD 56 63 B8 C4 DA 46 40 79 18 25 B6 AF 50 6B E8 F7 39 A1 D6 F9 61 4C 31 DE E5 69 D0 41 F9 01 10 01 01 00 01 02 00 00 B7 41 46 27 1A 9D E6 ED 1D AE 01 25 B1 7D 4B 83 CE A1 5A A8 54 67 30 92 38 6F DA 33 C1 A5 B5 6B BA 6A AD A3 BC 04 D6 33 F9 56 C7 CB C3 A6 97 FE 65 56
but HardwareSerial uart(1) that's not going to happen
Another clue for finding this issue. I am using Arduino ide with a Wrover module, the uart2.available() function will only respond every 10 seconds if I am initialising uart2 non-inverted. When I enable invert the uart2.available() responds normally.
------UPDATE -----
Apologies, I think it must have been an electrical issue. Seems to be working with a different chip.
I have been working with ESP32, connected to a SP3485 RS485 driver chip (but should work with others) using a simple circuit to drive the DE/RE pins automatically from the TX line. I have been struggling for some time now to get the Simple Modbus Slave Arduino library to correctly send a response to a Modbus Master. The library was correctly generating the response but on the RS485 side the data was corrupted.

As you can see from the above the first message which is a request for data always gives a good response but alll the following message, which just happen to be write messages, are corrupted. This device is oone of a number on the Modbus link so after this set of messages the master moves on to other devices before looping round and repating a set of requests.
I have been scanning the various forums looking for a solution and eventually found one that works,
thanks to antonyc on the ESP32 forum in topic 'ESP32 RS485driver hardware serial ModbusMaster' for the solution which was to simply add a 13uS delay in between each character.
Code for transmit function
// ************************
//
// Send the modbus message
//
// ************************
void sendPacket(uint16_t bufferSize) {
// not required, using auto detect Tx
//digitalWrite(TxEnablePin, HIGH);
// transmit the characters in buffer singly with delay
for (uint16_t i = 0; i < bufferSize; i++) {
(ModbusPort).write(frame[i]);
delayMicroseconds(13);
}
// rather than as a block
//(ModbusPort).write(frame, bufferSize);
// found flush caused problems
//(*ModbusPort).flush();
// allow a frame delay to indicate end of transmission
delayMicroseconds(T3_5);
// not required, using auto detect Tx
//digitalWrite(TxEnablePin, LOW);
}
In the sendPacket function I added the 13uS delay after each character and now the software correctly responds to all the messages.

My hardware is a purpose designed PCB using an ESP32 WROOM-U, programmed using the Arduino IDE and latest development code for Arduino EPS32 the SDK is Versionv3.2-dev-1055-g3276a1316, the library is heavily modified version of Simple Modbus Slave. The RS485 is provided by a SP3485 RS485 chip using Serial2 ( pins 16 and 17) and no hardware pin for the direction select as this works automatically via a simple circuit that detects when transmission starts
With reference to using an ESP WROVER chi with serial2, it cannot be done as pins 16 and 17 are not connected, they are used to handle the PSRAM.
One other point of interest that caught me out is that the ESP32 WROVER uses 1.8V Flash and not 3V3 as used by the ESP32 WROOM, this means that the GPIO pin 12 must have different biasing for the WROVER chip, so they are not interchangeable as I first thought.
With my new project I need all three UARTS, problem still persists...
I can use Serial(1) with no problem, when I change to Serial(2) the code only runs once after startup...
please help
I managed to get Serial(2) working with the ESP32Serial.h library
https://github.com/9a4gl/ESP32Serial