alejoseb / Modbus-STM32-HAL-FreeRTOS

Modbus TCP and RTU, Master and Slave for STM32 using Cube HAL and FreeRTOS
GNU Lesser General Public License v2.1
519 stars 182 forks source link

Incorrect/varying length of start bit in first modbus response byte #98

Closed anders-vanneback closed 4 months ago

anders-vanneback commented 5 months ago

Hi Generally the lib works great but recently I noticed that sometimes when the slaves send the response to the master then the ID byte gets misinterpreted and the master complains about the response comming from an incorrect modbus ID.

I'm using this lib on the slave devices only, the master is running a modbus python script on a ubuntu machine.

My slaves are using USART 2 on an STM32FF103 device with 38400bps, no parity, 1 stop bit, asynchronous settings.

The slave and PC communicates over 2-wire RS485 (i.e. half duplex mode) and the slave device has an external RS485 driver with a read/write enable pin.

Using an oscilloscope I could see that the start bit in every response from the slave varies in length. With 38400bps speed each bit should be ~26us but it varies quite a bit and is never longer than 20us in my case.

Have you seen this issue as well?

I found out that I can work around this issue by adding a small delay in the code before and after the tranmit occurs, like this (from line 1548):

if (modH->EN_Port != NULL)
{
            //enable transmitter, disable receiver to avoid echo on RS485 transceivers
            HAL_HalfDuplex_EnableTransmitter(modH->port);
            HAL_Delay(1);
            HAL_GPIO_WritePin(modH->EN_Port, modH->EN_Pin, GPIO_PIN_SET);
}

Then the start bit length is correct and constant as intended.

In my specific application the external RS485 driver will handle the halfduplex setting so I can keep the USART block configured for full duplex at all times and I ended up just commenting out the call to: HAL_HalfDuplex_EnableTransmitter(modH->port); Both before and after the transmission (instead of using the delay mentioned above) and this also works as intended in my application.

It seems like there needs to be a short delay after reconfiguring the USART registers before the actual transmit can occur to to give the USART block enough time to reconfigure asynchronously?

I'm not certain what the proper generic solution for this would be that would also support UART-to-UART communication (which is what I assume the intention behind using half duplex is intended for in this context) that does not have external drivers to handle the half duplex mode?

alejoseb commented 5 months ago

Hi, I am not sure what your intention or use case is here. This Modbus library is always half duplex. I have also tested with automatic transceivers that do not need the CE signal without any issue, or connecting directly USARTs without any issues.

So your problem is specific to what you are doing, or your electrical connections, it is not related to the library. Also this is a master-slave protocol, not sure if that is what you are looking for.