/esp8266-modbus-gateway

ESP8266 Modbus TCP to RTU gateway

Primary LanguagePythonMIT LicenseMIT

ESP8266 Modbus TCP/RTU gateway

This is a Modbus TCP to RTU gateway for ESP8266 microcontroller written in MicroPython. Multiple persistent TCP connections are supported. There is watchdog timer that should reboot the controller in case anything goes wrong.

Installation

First, you need ESP8266 with MicroPython onboard. Refer to official MicroPython ESP8266 tutorial for more details. Setup WiFi connection and WebREPL. This is the most convenient way to transfer files into board flash. What's more important, this will be the only access to REPL console since hardware UART is used for Modbus communication.

Next review serial port settings (the default is 9600, 8N1) in main.py and change according to your needs. Transfer modbus.py and main.py into the board. For this you need webrepl_cli.py available from MicroPython WebREPL repository:

# webrepl_cli.py modbus.py 192.168.4.1:/
# webrepl_cli.py main.py 192.168.4.1:/

Hardware connection

A TTL-RS485 converter is necessary for RS485 connection. Connect ESP TX pin to DI pin and ESP RX pin to RO pin. By default D1 (GPIO5, you can change this in main.py) is used for driver enable control and needs to be connected to converter's DE (active high) and RE (active low) pins.

Software part

The code is purposely not using uasyncio library to avoid frequent memory allocation and possible fragmentation issues. Request handler uses readinto() functions to read data in-place into a single static buffer of 128 bytes for TCP and RTU frames. This is the maximum supported TCP frame length. Maximum RTU frame length is 122 bytes. You can increase that if you want by raising buffer size.

Watchdog timer

There is a watchdog timer with timeout between 1.6 and 3.2 seconds (see this MicroPython issue), reset on every Modbus TCP request and every 1000ms. If Modbus TCP master fails to send request and acknowledge response in watchdog timeout, it will reboot the board.

Logging

By default logging is disabled. To enable logging, use set_log() function in modbus.py:

set_log(10) # Debug level

Logging requires micropython-logging package installed. Refer to official MicroPython package documentation for details.

Troubleshooting

When something goes wrong causing the code to hang or raise an unexpected exception, watchdog timer will promptly reboot the device. This is desired in normal use but makes debugging virtually impossible. To disable watchdog timer pass None as wdt_feed to ModbusGateway. It's important not to instantiate WDT class because this starts watchdog which can't be stopped afterwards.

So in order to disable watchdog timer you need to edit main.py and replace

wdt_feed = WDT().feed

with

wdt_feed = None

Another point to consider is that debugging is tough without log messages so do yourself a favour installing micropython-logging package and enable logging as described in the previous part.