This post is a part of a series about the TouchBerry ModbusRTU autoflow issue and how have I resolved it. Other posts of the series can be found under the touchberry tag. Note that newer posts might contain more recent information.
With the access to the TouchBerry 10" model including RS485, I set to start controlling some ModbusRTU devices with it. It has the M8, 3-pin connector. The center pin is connected to supply voltage ground, so I assumed the remaining two are A and B for RS485. As it turned out, there is absolutely no documentation on the topic publicly available.
RS485 pinout
Fortunately, I was able to receive the email from the support quite promptly. The email confirmed the pinout.
# | M8 position | RS485 |
---|---|---|
1 | right | B- |
2 | left | A+ |
3 | top | GND |
But with the GND sorted out, getting to A and B is not a problem. If not working, just swap them and try again. With everything else correct, this is sufficient procedure.
The UPS shield pinout
Subsequently, the email contained information about the UPS shield pinout which hosts the RS-485 chip. The chip is Unisonic Technologies UTRS485G, but I have never heard about them before. The UPS shield also hosts uninterrupted power supply electronics (hence the name) and the timekeeping chip DS3231 for the RTC capabilities.
The shield makes use of the full 40 pin header for the Raspberry Pi 4 being the core of the TouchBerry 10", the details from the email are following:
Fn | Descr. | # | # | Descr. | Fn |
---|---|---|---|---|---|
NC | 1 | 2 | Vin | ||
SDA | GPIO2 | 3 | 4 | Vin | |
SCL | GPIO3 | 5 | 6 | GND | |
NC | 7 | 8 | GPIO14 | TXD | |
NC | 9 | 10 | GPIO15 | RXD | |
RE | GPIO17 | 11 | 12 | NC | |
DE | GPIO27 | 13 | 14 | GND | |
NC | 15 | 16 | GPIO23 | UPS IN | |
NC | 17 | 18 | GPIO24 | UPS OUT | |
NC | 19 | 20 | GND | ||
NC | 21 | 22 | NC | ||
NC | 23 | 24 | NC | ||
GND | 25 | 26 | NC | ||
NC | 27 | 28 | NC | ||
NC | 29 | 30 | GND | ||
NC | 31 | 32 | NC | ||
NC | 33 | 34 | GND | ||
NC | 35 | 36 | NC | ||
NC | 37 | 38 | NC | ||
GND | 39 | 40 | NC |
This was quite helpful, as the chip responsible for the RS485 communication has to know which direction the data is flowing. It is an advanced feature to design the overall system such that the user has this responsibility abstracted away - so called autoflow or automatic flow control.
Using RS485 interface on TouchBerry 10
The importance for the autoflow can be apparent from the python script provided as the third part of the email from the IndustrialShields support:
#!/usr/bin/env python3
# IMPORTANT: remember to add "enable_uart=1" line to /boot/config.txt
from gpiozero import OutputDevice
from time import sleep
from serial import Serial
# RO <-> GPIO15/RXD
# RE <-> GPIO17
# DE <-> GPIO27
# DI <-> GPIO14/TXD
#
# VCC <-> 3.3V
# B <-> RS-485 B
# A <-> RS-485 A
# GND <-> GND
# enable reception mode
re = OutputDevice(17)
de = OutputDevice(27)
de.off()
re.off()
with Serial('/dev/ttyS0', 19200) as s:
while True:
# waits for a single character
rx = s.read(1)
# print the received character
print("RX: {0}".format(rx))
# wait some time before echoing
sleep(0.1)
# enable transmission mode
de.on()
re.on()
# echo the received character
s.write(rx)
s.flush()
# disable transmission mode
de.off()
re.off()
To send the data over the RS485 interface, the RE and DE pins of the chip has to be pulled HIGH, the data should be transmitted, and then both RE and DE pins should be pulled LOW immediately to receive the response. This is very unfortunate as most Modbus implementations assume the autoflow, as is also the case when using mbpoll.
Missing autoflow?
It is basically a lot of hassle to not have the autoflow functionality rendering most standard Modbus implementations unusable. I have searched quite hard for the way how to do this in some nice automated way on the RPi software on some application or kernel level, visiting search term results like alternative GPIO functions, dtoverlay, RTS0, uart-ctsrts and serial sniffers but could not find the solution yet. Some of the most promising are referenced below among other relevant links.
The GPIO17 has the alternative function of RTS0 at ALT3, which is connected
to the RE pin - this is hopefully done by design. There is however no such
function available for the GPIO27 connected to the RE pin. In reality, both
DE and RE should be tied together, controlled by the single RTS0 pin, that
is in turn driven by GPIO14 being TXD0. I have no idea why the RE pin is
separate. I have to hook it up to the oscilloscope to learn more. Before
touching the soldering iron, I also have to wait for another support email
response - maybe they provide some nice information. In the end, their
RPi based PLC has /dev/ttySC0
and /dev/ttySC1
for both RS485 channels.
This is a 92th post of #100daystooffload.
Links
- http://www.unisonic.com.tw/datasheet/UTRS485.pdf
- https://www.industrialshields.com/web/content?model=ir.attachment&field=datas&id=137792&
- https://ethertubes.com/raspberry-pi-rts-cts-flow-control/
- https://raspberrypi.stackexchange.com/a/32504/59436
- https://widgetlords.com/pages/rs485
- https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/rpi_DATA_2711_1p0_preliminary.pdf