Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serial(2) only works first loop after reboot, Serial(1) works fine, with modbusmaster #991

Closed
TLS1000 opened this issue Jan 11, 2018 · 17 comments

Comments

@TLS1000
Copy link

TLS1000 commented Jan 11, 2018

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 -----------------------------

Hardware:

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?

Description:

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//issues/650]

Sketch:

//Change the code below by your sketch
#include <Arduino.h>

void setup() {
}

void loop() {
}

Debug Messages:

Enable Core debug level: Debug on tools menu of Arduino IDE, then put the serial output here 
@TLS1000
Copy link
Author

TLS1000 commented Jan 11, 2018

I tried using the default UART2 pins 16 and 17, no improvement.

@TLS1000 TLS1000 changed the title Serial(2) only works first loop after reboot, Serial(1) works fine Serial(2) only works first loop after reboot, Serial(1) works fine, with modbusmaster Jan 11, 2018
@bertvaneyken
Copy link

Wich modbusmaster library are you using?
You should include the important parts of your code.

@TLS1000
Copy link
Author

TLS1000 commented Jan 15, 2018

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).

@baggior
Copy link
Contributor

baggior commented Feb 4, 2018

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

@shimarin
Copy link

shimarin commented Feb 6, 2018

Most likely it's related to hardware issue of UART2.
espressif/esp-idf#1202 (comment)

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)

@baggior
Copy link
Contributor

baggior commented Feb 6, 2018

@shimarin maybe you are right about the hardware bug.. could you extend and apply the workaround on the Arduino HardwareSerial library too?

@shimarin
Copy link

shimarin commented Feb 6, 2018

@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.

@baggior
Copy link
Contributor

baggior commented Feb 6, 2018

who could correct the HardwareSerial library and include the uart fix, then?
@me-no-dev ?

@TLS1000
Copy link
Author

TLS1000 commented Feb 6, 2018

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.

@everslick
Copy link
Contributor

I think there have been some changes lately, does this problem still persist?

@dtboy1995
Copy link

this problem still persist

@TLS1000
Copy link
Author

TLS1000 commented May 31, 2018

JacoFourie got all three UARTS working, you need to add a serial.flush() in the pretransmission routine. I haven't tested it.

4-20ma/ModbusMaster#96 (comment)

@dtboy1995
Copy link

dtboy1995 commented May 31, 2018

@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

@Kirk-1
Copy link

Kirk-1 commented Jun 11, 2018

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.

@malbrook
Copy link

malbrook commented Oct 19, 2018

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.

prior to mod

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.

after mod

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.

@TLS1000
Copy link
Author

TLS1000 commented Nov 30, 2018

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

@TLS1000
Copy link
Author

TLS1000 commented Nov 30, 2018

I managed to get Serial(2) working with the ESP32Serial.h library
https://github.com/9a4gl/ESP32Serial

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants