back to index

Serial communication over TCP - TasmoCOM


Why
How
      ESP8266 serial ports
            diode and switched pullup
            circuit
      Tasmota configuration
            console responses, good and bad
            commands

Why

Because very often the serial comm goes over UART, and attaching a device over wifi is the minimalistic way to avoid wiring.

Because standard modules with well-established firmware are the easiest way.

The method provides just the raw UART over socket. No virtual COM ports. No RFC2217 support for in-band control lines and port setting. If these are needed, either use another approach (eg. sw_SerialOverIP_RFC2217) or implement out-of-band control of the lines over GPIOs available.

The surplus GPIOs on the module can be used for attaching additional sensors and ADCs, for eg. monitoring temperature of the device under control, or switching it on/off, via standard Tasmota's HTTP or MQTT API.

The solution is tested with MODBUS protocol. Full binary communication is possible.

When wired communication is needed, another approach can be used, via eg. serial-over-Ethernet modules.


How

Use a module with ESP8266 or compatible. One of most comfortable firmwares to use is Tasmota. For the sake of example, the Wemos D1 Mini is chosen as it is used in the prototype tested.

ESP8266 serial ports

The ESP8266 has two serial ports, primary (Tx0/Rx0) and secondary (Tx1/Rx1), on these pins:

The primary port is used as Tasmota's serial console. On some modules it is attached to USB-UART converter. The chip's bootloader also outputs data there during boot, typically at 74880 bps, which looks like binary garbage at other speeds and can confuse attached hardware. Disabling the serial console also disposes of the ability to easily reconfigure the device, eg. when changing networks.

The secondary port is therefore a better choice. Not the straightest, though.

diode and switched pullup

The GPIO15 comes with a gotcha that can bite the unwary. At boot time, it serves as a selector between booting from internal flash (pulled L) vs running in SDIO mode (sdcard) (pulled H). To run properly, it has to be pulled L. On Wemos module, this is via a 10k resistor.

The UART is H when inactive. This precludes having the Rx1/GPIO15 connected directly. A diode, preferably Schottky, is a solution; anode to GPIO15, cathode to device's UART.

During tests, with the diode between the device's UART and chip's GPIO15, the chip booted properly. The data sent through the pin were however relayed as binary garbage. Scope check shown nice rectangular serial data on diode's anode, and narrow peaks on the cathode; the pulldown is holding the signal L, and the H spikes are all that gets through the diode's capacitance. Oops.

The internal pullup on the pin is grossly insufficient against the fixed 10k pulldown. It has to be aided with a resistor. But a fixed resistor from Vcc will go against the pulldown necessary on power-on time.

Switched pullup to the rescue.

Sacrifice one of the plentiful GPIOs. Let's choose GPIO12 for being nearby on the module used. Configure it to fixed H state. On power-on moment, it is in high-impedance state. Only after the firmware boots and initializes the pins, it goes high. This provides more than enough time for the chip to start in the proper mode.

The suitable values for the resistor are 2k2 and 3k3, assuming the 10k pulldown. Lower value gives higher current load, higher gives lower voltage at H. Chip datasheet promises H level on input to be guaranteed at 75% of Vcc. 3k3 narrowly reaches over this limit, 2k2 is comfortably within. 1k may be pushing the load of the device's UART.

The Tx line on GPIO13 requires no additional hardware. A pullup resistor of 10-100k can be used if the slave UART on the other side gets random garbage during when the chip is booting and the pin is at high impedance.

circuit

                   2k2
GPIO12/D6  o-----/\/\/\---
                          |     small schottky
GPIO15/D8  o--------------*-----|>|-----o
                          |
      GND  o-----/\/\/\---
                 10k, built-in

Tasmota configuration

The precompiled firmware flavor used is zbbridge - we are using the same trick as used with bridging Zigbee coordinator modules.

The pins are configured as such:

The port server has to be enabled (and the TCP port specified) after boot. A rule is a convenient way to automate this, for port 8888 as example.

(set up a rule, then set rule as active)

The port speed can be set via command, and is remembered: tcpbaudrate 115200 (max rate)

The port is accessible from the entire local network (security!). Access can be limited to a single individual IP, eg.:

console responses, good and bad

correct:

[160][0.005][100.242]02:41:25.473 SRC: Rule
[161][0.000][100.243]02:41:25.474 CMD: Grp 0, Cmd 'TCPSTART', Idx 1, Len 4, Pld 8888, Data '8888'
[162][0.007][100.250]02:41:25.477 TCP: Starting TCP server on port 8888
[163][0.002][100.253]02:41:25.484 MQT: stat/SerBridge2/RESULT = {"TCPStart":"Done"}

TCP-serial bridge fails to start:

[105][0.005][20.047]02:40:05.114 SRC: Rule
[106][0.000][20.047]02:40:05.115 CMD: Grp 0, Cmd 'TCPSTART', Idx 1, Len 4, Pld 8888, Data '8888'
[107][0.009][20.056]02:40:05.120 MQT: stat/SerBridge2/RESULT = {"Command":"Unknown"}
common causes:

commands

Detailed description of the TCPserial subsystem at https://tasmota.github.io/docs/Serial-to-TCP-Bridge/.


If you have any comments or questions about the topic, please let me know here:
Your name:
Your email:
Spambait
Leave this empty!
Only spambots enter stuff here.
Feedback: