Using TTY2MQTT to bridge between serial communication and MQTT

The TTY2MQTT command line tool is a bridge between TTY (COM) serial communication and an MQTT message broker and provides a CLI for publishing and subscribing data from and to a serial port from and to an MQTT message broker. You can download TTY2MQTT from this site’s downloads section.

You may operate TTY2MQTT on a Raspberry Pi to which Arduino boards are attached to by USB. The USB connections by default act as serial TTY (COM) connections over USB, so that the Raspberry Pi directly can communicate with the Arduino boards via serial communication. The TTY2MQTT tool now bridges this serial communication to an MQTT message broker.

IoT Serial Edge Computing Internet Cloud
Local Area USB-Cable TTY2MQTT Internet Connection Cloud

Quick start

First go to the downloads section of this site and download a TTY2MQTT flavor most appropriate for you.

Depending on the executable’s flavor the command might also be named tty2mqtt-x.y.z.jar, tty2mqtt-bundle-x86_64-x.y.z.elf, tty2mqtt-bundle-x86_64-x.y.z.exe, tty2mqtt-installer-x86_64-x.y.z.msi, tty2mqtt-launcher-x.y.z.sh, tty2mqtt-launcher-x86_64-x.y.z.elf, tty2mqtt-launcher-x86_64-x.y.z.exe, tty2mqtt-native-x86_64-x.y.z.elf where x.y.z stands for the version of the tty2mqtt command. The according executable’s name will be referenced to in this manual as tty2mqtt.

Once downloaded and placed into a folder of your choice, TTY2MQTT can be instructed to create an initial configuration for you:

  • ./tty2mqtt --init: Create an initial tty2mqtt.ini configuration file

To get an impression of all the functionality, just go for ./tty2mqtt --help, which shows the tool’s help.

  • ./tty2mqtt --list: List available TTY (COM) ports

Once configured, you can fire up TTY2MQTT as follows (make sure a configured MQTT message broker is up and running):

  • ./tty2mqtt: Start the tool

Using the default configuration, sending a message from your serial TTY (COM) port to the TTY2MQTT bridge using an Arduino can look as follows:

1
2
Serial.println("@button1:Button 1 pressed") // Use topic "button1" when TTY2MQTT publishes the message 
Serial.println("# The button one on the Arduino has been pressed!") // This is a comment, TTY2MQTT just logs this text

The MQTT topic to publish to is button1 and the payload is “Button 1 pressed”. Before this example works, you must configure your TTY (COM) port to attach to on the one side and the MQTT broker to attach to on the other side. Next we will go through the various configuration properties to, amongst others, do so.

You may prepare multiple configurations and launch TTY2MQTT multiple times with the according configuration file as argument, e.g ./tty2mqtt --config someConfigA.ini

Configuration

The initial tty2mqtt.ini is found at the end of this article and may be tweaked as follows:

MQTT message broker

The MQTT message broker to use is configured in the [[broker]] portion of the [mqtt] section:

  • url: The URL of the message broker in question.
  • user: The user to use when accessing the according message broker.
  • secret: The user’s password to use when accessing the according message broker.

Publishing from the serial port

The MQTT publisher on the serial port is configured in the [[publisher]] portion of the [mqtt] section:

  • id: The ID we give the publisher on the serial port to be used when sending MQTT messages to the MQTT message broker.
  • topic: Use this topic in case none is found in the TTY (COM) serial payload (fallback), leave empty if messages without a topic are to be ignored (just logged). A topic can be defined in the serial port’s payload (see configuration further down).

Subscribing to the serial port

The MQTT subscriber for the serial port is configured in the [[subscriber]] portion of the [mqtt] section:

  • topic: The name of the topic which’s messages are to be passed (subscribed to) from the MQTT message broker to the TTY (COM) port.

  • mode: The subscriber mode denotes the mode of operation, either expecting binary (BINARY) or textual (ASCII) data, e.g. what kind of data is being expected to be passed (subscribed to) from the MQTT message broker to the TTY (COM) port: In ASCII mode, the message is being terminated by the suffix, in BINARY mode the message’s binary data is prefixed with a length header, which’s metrics are defined by the length’s width and endianess properties.

Serial port

The serial port is configured in the section [tty]:

  • port: The TTY (COM) port to use, e.g. COM1 on Windows or /dev/ttyS0 on Linux.
  • baud: The BPS to be used when communicating with the TTY (COM) port.
  • parity: The parity to use when operating the TTY (COM) port, see ./tty2mqtt --help for possible values.
  • dataBits:The number of data bits to use when operating the TTY (COM) port.
  • stopBits:The number of stop bits to use when operating the TTY (COM) port.

Run ./tty2mqtt --list to list all available TTY (COM) ports.

Serial port messages

The format of a message on the serial port is configured in the [[message]] portion of the [tty] section:

  • suffix: The suffix identifying the end of a TTY (COM) serial payload. A hex value (e.g. 0x00) denotes the actual value, an \n denotes a newline.

  • length: In case the mode property is set to BINARY, the length denotes the metrics of the length prefix of the binary data passed to the TTY (COM) port. The length property is made up of two sub properties width and endianess:

As the length is composed of two individual properties, the length opens up a new subsection [[[length]]] below the message subsection:

  • width: The number of bytes to use when prefixing the length of the binary data when mode is set to BINARY for data sent from MQTT to the TTY (COM) port (defaults to 2, e.g. a maximum 64 Kilobytes).

  • endianess: The endianess (BIG or LITTLE) to use for the prefixed length of the binary data when when mode is set to BINARY for data sent from MQTT to the TTY (COM) port (defaults to LITTLE).

Serial port comments

Sometimes it is useful to still use the TTY (COM) for printing out debugging information. This information must not be forwarded to the MQTT message broker. In such cases, the device attached to the TTY (COM) port may mark its payload as being a comment. The format of a comment on the serial port is configured in the [[[comment]]] portion of the [[message]] section:

  • prefix: The prefix character for TTY (COM) serial payloads which just to print out with INFO log level.

To print a comment to the TTY (COM) port on an Arduino when using the # character to prefix a comment might look as follows:

1
Serial.println("# The button one on the Arduino has been pressed!") // This is a comment, TTY2MQTT just logs this text

Topics in serial port payloads

The format of a topic embedded in the payload on the serial port is configured in the [[[topic]]] portion of the [[message]] section:

  • prefix: The prefix character identifying an MQTT topic.
  • separator: The separator character separating the topic from the actual message.

In general, the layout of a payload containing a topic is as follows:

<prefix>+ “topic” + <separator>+ “message” + <suffix>

For example using the topic prefix “@” and a separator “:”, a payload with a topic and a message might look as follows:

"@button1:Button 1 pressed\n"

Printing such a message to the TTY (COM) port on an Arduino might look as follows:

1
Serial.println("@button1:Button 1 pressed") // Use topic "button1" when TTY2MQTT publishes the message 

The instruction Serial.println already suffixes the text to be printed with a \n, therefore \n is not explicitly specified in the string to be printed.

Configuration file

You can use XML, JSON, YAML or INI (TOML) notations (including plain simple *.properties files with key=value pairs). Below find configurations using INI notation and also using plain properties:

Extended INI notation

Using the INInotation, the configuration is organized by sections embedded in square braces [...].

Note that the hierarchical order of the properties is achieved by the number of nested square braces, e.g. a portion belonging to a section [...] gets additional square braces as of [[...]] and is placed below the parent section it belongs to.

tty2mqtt.ini

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
[mqtt]

[[broker]]

url=tcp://localhost:1883
user=heinz
secret=ketchup

[[publisher]]

id=arduino

# Use this topic in case none is found in the TTY (COM) serial payload (fallback),
# leave empty if messages without a topic are to be ignored (just logged):
#
# topic=debug

# Whether or not messages published should be retained by the messaging engine:
#
# retained=true

# Sets the quality of service when publishing messages.
#
# qos=1

[[subscriber]]

# The topic to subscribe to and which's messages are to be sent 
# from the broker to the TTY (COM) port.
#
topic=ttyin

# The subscriber mode denotes the mode of operation, either expecting binary ("BINARY")
# or textual ("ASCII") data, e.g. what kind of data is being expected to be passed
# (subscribed to) from the MQTT message broker to the TTY (COM) port. In ASCII mode,
# the message is being terminated by the "suffix", in BINARY mode the message's
# binary data is prefixed with a length header, which's metrics are defined by the
# "length"'s "width" and "endianess" properties.
#
# mode=BINARY
mode=ASCII

[tty]
port=/dev/ttyS0
baud=9600

[[message]]

# The suffix identifying the end of a TTY (COM) serial payload when sending data
# from TTY (COM) to MQTT or when "mode" is set to "ASCII" and passing data from
# MQTT to the TTY (COM). A hex value (e.g. 0x00) denotes the actual value, an '\n'
# denotes a newline:
#
suffix=\n

[[[length]]]

# The number of bytes to use when prefixing the length of the binary data when
# "mode" is set to "BINARY" for data sent from MQTT to the TTY (COM) port.
#
width=2

# The endianess to use for the prefixed length of the binary data when "mode" is
# set to "BINARY" for data sent from MQTT to the TTY (COM) port.
#
endianess=LITTLE
# endianess=BIG

[[[comment]]]

# Just log any TTY (COM) serial payload prefixed with this char with INFO log level:
#
prefix=#

[[[topic]]]

prefix=@
separator=:

Java properties notation

This notation uses plain simple files with key=value pairs for each line.

Note that the hierarchical order of the properties is achieved by representing the properties with a path alike notation.

tty2mqtt.properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mqtt/broker/url=tcp://localhost:1883
mqtt/broker/user=heinz
mqtt/broker/secret=ketchup
mqtt/publisher/id=arduino
mqtt/subscriber/topic=ttyin
mqtt/subscriber/mode=ASCII
tty/port=/dev/ttyS0
tty/baud=9600
tty/message/suffix=\n
tty/message/comment/prefix=#
tty/message/length/width=2
tty/message/length/endianess=LITTLE
tty/message/topic/prefix=@
tty/message/topic/separator=:

See also