1) The secret of the BLE packages
- (FW -> BLE -> APP) Types and structure of the packages
- (FW <- BLE <- APP) Aufforderungen an die FW via BLE
1.1) The different types of BLE packages
The current state of knowledge is that there are basically 2 different BLE packets that are received from the FW via BLE and that can be recognized by the 1st character (ASCII/byte):
- Messages in general:
@...
- data packets (JSON):
D{"KEY":"value", ...}
- Are there any others?
1.1.1) Receive messages via BLE
The structure of a message package dates back to the very early days of FW development and it will be difficult to change this in FW v4.xx. There may be changes to the structure in FW v5.xx.
The structure of the message protocol (FW -> BLE -> APP) is a mixture of ASCII + bytes + combo bytes + UTF-8, which makes decoding more difficult.
bb
= Byte
hh
= binary combo
aa
= Path [ASCII]
dt
= Destination + Type [ASCII] (different variants)
[Further parameters] depend on the subtype of a message
Type | Msg-ID | Hop | Path | del | dest | Message | del | [other parameters] |
---|---|---|---|---|---|---|---|---|
@: | bb bb bb bb bb | hh | aa ... aa | > | dt | UTF-8 ... | 00 | bb .. bb |
Variants for dt
-
*:
= Message to all -
123:
= Message to Group 123 -
OE3WAS-12:
= DM (DirectMessage) to OE3WAS-12 -
*:{CET}
= Date & Time (only transmitted if GW is; not for CL) -
*!
= POS string -
DM is when DM == own CALL
-
GRP-Msg is used for comparison with the subscribed groups
1.1.2) Receive ACK packet
Type | Msg-ID | ACK |
---|---|---|
@A | bb bb bb bb bb | bb bb bb bb bb bb bb bb |
- | - | - |
1.1.3) response Messages
...
...
[TODO] This data structure & list may be incomplete and may be subject to change based on new findings.
1.1.4) Receive data packets via BLE
Since data packets are formatted as a JSON string, the "key":"value"
decode pairs quite easily. It would have been so easy to receive all BLE data as a string. But due to the unspeakable structure of the message protocol, it was necessary, receive all data as bytes and convert this byte sequence to UTF-8.
The basic structure of the data packets is as follows: in the key "TYP":"xx"
the "xx"
(Value) can assume different values and thus differentiate the packages.
The following types (value) are currently known:
- "I" ==
--info
- "SE" ==
--seset
- "SW" ==
--wifiset
- "SN" ==
--nodeset
- "W" ==
--wx
|--weather
- "G" ==
--pos
- "SA" ==
--aprsset
- "IO" ==
--io
- "TM" ==
--tel
- "AN" ==
--analogset
- "MH"
1.2) Requirement packages from the APP to the FW
There are various request packets for the FW, i.e. the "send".
Unless otherwise noted, representation is as hex bytes (0x..).
1.2.1) {HELLO}
First of all, the initial start of communication must take place with the so-called {HELLO} packet, which must be sent.
04 10 20 30 |
---|
The FW then sends several data packets containing the parameters (I, SE, SW, SN, W, G, SA).
The messages still received and stored in the FW are also transmitted (@:).
The data packet with the "TYPE": "MH" is sent once in between.
The end of this transmission is signaled by a special data packet:
D{„TYP“:“CONFFIN“} |
---|
1.2.1.1) Timestamp
The APP then sends a timestamp packet to CONFFIN, e.g:
06 20 CF 7D DE 67
[BLE] Timestamp from phone (sec) <UTC>: 1742634447 -> 2025.03.22 09:07:27
You can then send your own commands and messages to the FW.
1.2.2) Send (text) messages & commands to the FW via BLE
Messages and commands are basically structured in the same way, whereby len
is the number of message bytes, followed by the Msg-ID and the message bytes.
ATTENTION: In UTF-8 there are sometimes more than 1 byte/character!
len+2 | A0 | Message bytes |
---|
1.2.2.1) Examples:
len
& ID
are represented as hex bytes, the message or command is represented as ASCII/UTF-8. The commands are not case-sensitive and are only written differently here for the sake of clarity.
len+2 | ID | (Text)Message/Command |
---|---|---|
08 | A0 | -info |
15 | A0 | -setCALL OE3WAS-12 |
1C | A0 | {123}Message to group 123 |
27 | A0 | {OE3WAS-11}Direct message to OE3WAS-11 |
- | - | - |
1.2.3) Config Messages
There is a group of commands that have a different ID but are basically structured in the same way. However, the respective command logically has its own syntax.
In the meantime, all these config messages are also available as --command
to be sent.
Msg-ID:
- 0x20 - Timestamp from phone (
--settime
) [4Bytes] - 0x50 - Callsign (
--setCALL
) [1Byte len - Callsign] - 0x55 - Wifi SSID (
--setSSID
) and PWD (--setPWD
) [1Byte - SSID Length - SSID - 1Byte PWD Length - PWD] - 0x70 - Latitude (
--setLAT
) [1Byte length + 1Byte Msg-ID + 4Bytes lat + 1Byte save_flag] - 0x80 - Longitude (
--setLON
) [1Byte length + 1Byte Msg-ID + 4Bytes lon + 1Bytes save_flag] - 0x90 - Altitude (
--setALT
) [1Byte length + 1Byte Msg-ID + 4Bytes alt + 1Byte save_flag] - 0x95 - APRS Symbols (
--symID
--symCD
) - 0xF0 - Save Settings to Flash (
--save
) - save_flag is
0x0A
for save and0x0B
for don't save (From Z.365ff https://github.com/icssw-org/MeshCom-Firmware/blob/oe1kfr_434q/src/phone_commands.cpp)
[TODO] more info to follow ...
2) External hardware
Various sensors and a digital I/O extension are described as "external hardware".
2.1) Sensors
Various sensors are supported in MT-FW 4.34v. Not all of them are currently sufficiently described. Therefore, I will try to create a detailed description with the individual parameters for the respective sensors.
2.1.1) Environmental data
The most important common environmental data are: Temperature [°C], relative humidity [%rH], air pressure [hPa]
Further parameters are: Air quality, CO2 [ppm] and others.
Type | IO | Addr | Measured values |
---|---|---|---|
BMP280 | I²C | 76 | T* [°C] - P [hPa] /T=[°C] /P=[hPa] BLE: ... |
BME280 | I²C | 76 | T* [°C] - H [%rH] - P [hPa] /T=[°C] /H=[%rH] /P=[hPa] /Q=[hPa] BLE: ... |
BME680 | I²C | 76/77 | T [°C] - H [%rH] - P [hPa] - GASres [kΩ] /T=[°C] /H=[%rH] /P=[hPa] /F=[m] /G=[kΩ] /V=3 BLE: ... |
DS18B20 | 1-W | - | T [°C] /O=[°C] BLE: ... |
MCU811 | I²C | 5A | CO2 [ppm] /C=[ppm] /V=2 BLE: ... |
- Addr in Hex
- /X = Identifier in POS-Msg (V=2 has priority over V=3)
- (*) = the temperature is used for internal compensation and is therefore slightly higher than the real environment.
- MCU811 WAK-GND connection in addition to I²C.
2.1.2) Measured values
Currently, only one INA226 (voltage [V]-current [A]-power [W] sensor in the 20A version with an RS=2 mΩ [R002]) is officially supported.
Type | IO | Addr | Measured values |
---|---|---|---|
INA226 | I²C | 40 | /U=vbus[V], /I=vcurrent[A] /V=5 BLE: ... |
2.1.3) Digital I/O MCP23017
An MCP23017 16-pin I/O on I²C Addr=0x20 is supported.
The 16 IOs are identified by A0..A7, B0..B7. Control is possible via terminal, BLE & UDP (web client).
Type | IO | Addr | Measured values as BLE-JSON package |
---|---|---|---|
MCP23017 | I²C | 20 | D{„TYP“:“IO“,“MCP23017″:true,“AxOUT“:“00000000″,“AxVAL“:“11111111″, „BxOUT“:“00000000″,“BxVAL“:“11111111″} |
Parameter | |
---|---|
MCP23017 | {true | false} = recognized? |
AxOUT | "00000000" = A7..A0, "1" = OUTPUT, "0" = INPUT |
AxVAL | "00000000" = A7..A0, "1" = HIGH, "0" = LOW |
BxOUT | "00000000" = B7..B0, "1" = OUTPUT, "0" = INPUT |
BxVAL | "00000000" = B7..B0, "1" = HIGH, "0" = LOW |
Commands via terminal & BLE APP:
--io
delivers a JSON package on BLE--setio clear
sets all IOs to INPUT--setio {A0..A7,B0..B7} {in | out}
sets the function of the selected IO to INPUT or OUTPUT--setout {A0..A7,B0..B7} {high | low}
sets the selected IO to HIGH or LOW
©️ 11.7.2025 by OE3WAS - Wolfgang