Modbus Master: Home Assistant OS (running on Intel NUC)
Goal
Make the ESP32 act as a Modbus RTU slave, and toggle a relay on GPIO19 when the master writes to a holding register (e.g. register 4 = 1 → turn on relay).
Problem
ESPHome does not natively support reacting to Modbus coil or holding register writes when in server mode.
What I’ve tried
modbus_controller + coil_states → only works in client mode
Hello Rudi,
Thanks for coming here and asking a question.
Would you be so kind as to adjusting the format of your code so that we can read it properly & check the YAML spacing, etc. Editing your original is the preferred way. It is very hard for us to tell what is what when the text formatter jumbles everything like that.
Use the </> button or this:
Here is an example of how to fix it from the site FAQ Page. How to help us help you - or How to ask a good question.
the code is from me, i tried maybe 10 different ways i read every google page to page 20 in Google results in 4 different languages.
Watched every Youtube video an read the whole article about modbus in ESPhome Homepage.
The code in my post where only the last attempt.
I tried so many things in the slave config.
in the server_register tried UART switch, holding, coil registers. digital switches.
I am new to the topic, and there is no problem to read data from switches or motionsensors etc.
works fine. Therefor i know my wiring, soldering, and network stat are ok. i even can use it in HOA als entities, but the switch to put a Relay on pin 19 (tried other to) on high/low don’t work.
i played with baudrate, timeout of the master or my last attempt where to try a few possible lambda variations in the slave config (that’s the reason why the value x is x==1.
Its so a simple task but i miss this little detail how i get it to work.
it will be a simple setup:
Intel Nuk with HOA OS as master and a ESP32 with ESPhome as slave.
The Slave/s are daisychined with a KNX cable 120R on the end.
And then there are switches and motion sensors and on other boards relays.
The modbus_controller part in the slave config where left behind from the last attempt.
@Karosm and @RudlDudl I have been looking into this myself. It doesn’t seem like this is currently supported in the modbus_controller built into esphome.
I would love to be proven wrong, but my current investigation had led me to these conclusions:
The server / slave support is limited to READ_HOLDING_REGISTERS = 0x03 and READ_INPUT_REGISTERS = 0x04
The relevant sections of the code are in parse_modbus_byte_ function in modbus.cpp
the on_modbus_data function in modbus_controller.cpp
It seems that to add support for 0x05 Write Coil command there are two options:
Add a new function to the modbus_controller API and insert it before the else clause that defaults to the handling the incoming MODBUS command with the on_modbus_data function in the parse_modbus_byte_ function in modbus.cpp
Inherit from modbus_controller and override the on_modbus_data function which has not been marked final.
I have zero experience with the esphome code base besides investigating this issue. I have no idea how to properly integrate any changes to API into the yaml parsing front end.
You may be better off using some sort of external component. I have seen one more possibility beside the link posted by @rudldudl, but have not tested it.
It may be worth opening an feature request issue for write coil support. It seems like a useful feature and I don’t believe that there is any currently exposed method to do this in the current esphome code base.
@Karosm and @RudlDudl there is a current PR#8577 which adds 0x5 Write Coil Support. Write coils may be added to the existing modbus_controller component with the option server_coil_register.
See esphome-doc PR#4825 for an example showing how to use the write_lambda to control a relay. A link to the deploy preview of the updated docs are provided below.