Modbus over RS-485 on ESP32

#1

Newbie here, just getting started. My goal is to create an IoT gateway to AWS MQTT for Modbus over RS-485, using the ESP32. Has anyone gone down this road already and have tips?

It seems like Mongoose OS has support for RS-485 the half duplex and transmit enable control since 2.15.0, so at least that seems doable. But does it work well?

Modbus has timing peculiarities I would rather not re-invent. Has anyone used a Modbus library successfully with Mongoose?

Thanks.

1 Like
#2

Mike, I’ve tried RS485 on Mongoose but the serial driver didn’t seem to have the transmit enable feature. What I did find is the esp-idf driver does have this and it works (I’ve just done some simple tests with sending some bytes and scoping the transmit enable pin). That’s where I stopped. Unfortunately the ESP32 does not have native hardware control in its uart, so some software magic needs to be added and it looks like the esp-idf driver does this. I’ve had a quick browse of the esp-idf code and it is not trivial. I’ll try having a look at the Mongoose code again to see if I can get it working and report back.
One work around to generate the transmit enable timing is to count the number of bytes you want to send times the character time (10 / baud rate) and load a timer with this value. when the timer expires, you clear the transmit enable pin.

Anyway, modbus to mqtt sounds like a good project. I’ve had plenty of experience with modbus over the years, so I may be able to assist.

#3

I just went to the link to the driver code you posted - seems I didn’t spot the hd (half_duplex ) option so I’ll give that a try tonight hopefully.

#4

Ok. I can confirm the transmit enable works.

This is my config:

mgos_uart_config_set_defaults(UART_NO, &ucfg);
ucfg.baud_rate = 115200;
ucfg.num_data_bits = 8;
ucfg.parity = MGOS_UART_PARITY_NONE;
ucfg.stop_bits = MGOS_UART_STOP_BITS_1;
ucfg.rx_buf_size = 2048;
ucfg.dev.hd = true;
ucfg.dev.tx_en_gpio = 27;
ucfg.dev.tx_en_gpio_val = 1;

if (!mgos_uart_configure(UART_NO, &ucfg))
{
return MGOS_APP_INIT_ERROR;
}

This configures gpio27 as the transmit enable being ‘1’ when transmitting (which is what you want for a max3485 chip and most other 485 transceivers). Remember to put a 10k pulldown resistor on this pin to keep the transceiver disabled during reset.

Thanks for motivating me to look a little deeper. Not sure if this info is documented as I dug through the code to work it out. Now I can do 485 without a hassle!

1 Like
#5

@Kartman, thanks for the follow-up. That was exactly the confidence I needed to keep going.