Yet Another ROC. Radio Online Control for orienteering and other sports that use SportIdent timing (trail running, MTB enduro).
It's as if ROC and jSh.radio had a baby.
- Very low latency, very low bandwidth: Wi-Fi or LTE/LTE-M can achieve latencies as low as 100–200ms. Bandwidth usage under 1 MB per day allows the use of cheap IoT SIM cards. Uses Protobuf for data serialization to minimize packet size.
- Support for multiple physical layers: NB-IoT, LTE-M, Radio (LoRa), LTE, Wi-Fi, LAN. Also supports BLE and USB for short-range communication.
- Radio mesh: Seamless integration with Meshtastic allows for LoRa-based mesh networks. Punches can be hopped across multiple nodes to reach a gateway, which can then bridge the data to the internet or directly to orienteering software (MeOs, etc.).
- Simple integration via USB recognizable by most orienteering software. Plug an ethernet cable into a Raspberry Pi in the finish area, connect it via USB cable to a computer and you are done!
- Broad hardware compatibility: Runs on everything from Linux machines (Raspberry Pi, PC) to specialized microcontrollers like the nRF52840.
- Reliability: Features built-in retries, exponential backoff, and buffering to ensure no punch is lost during network outages.
- Multiple output protocols: Integration with ROC, SIRAP, MQTT, and MeOS (MOP) protocols.
- Generator of fake SportIdent punches: Very useful for load testing of the system, for example to determine the right LoRa settings respecting duty cycle limits.
- Open-source
YAROC is pronounced phonetically as "jarok" (/'jarɔk/), which is the Slovak word for a small ditch or minor water channel.
Reflecting this name, the project's logo is based on the orienteering ISOM map symbol 306 Minor/seasonal water channel.
Install the yaroc package from PyPI, which provides the send-punch and yarocd commands. We recommend using uv for easy installation:
uv tool install yarocFirst, create a send-punch.toml file where you configure punch sources and clients for sending the punches.
log_level = "info"
[punch_source.usb]
enable = true
[punch_source.fake]
enable = true
interval = 8
[client.mqtt]
enable = true
broker_url = "broker.emqx.io"With a config file present, we are able to run send-punch:
send-punch
Follow the official Meshtastic documentation:
-
Configure the radio. We recommend using a private encrypted channel to avoid unnecessary traffic on public meshes.
-
Use the client role.
-
Use the LOCAL_ONLY rebroadcast mode
-
Set Ok to MQTT to
truein the LoRa configuration to allow your packets to be bridged by MQTT:meshtastic --set lora.ok_to_mqtt true -
Add a channel named
serial, it'll be used to transport punches through LoRa. Set Uplink Enabled totruefor theserialchannel (and any other channel you want to bridge). If yourserialchannel is at index 1:meshtastic --ch-index 1 --ch-set uplink_enabled true -
Enable device telemetry (every 5 minutes) to monitor mesh health and battery status:
meshtastic --set telemetry.device_telemetry_enabled true --set telemetry.device_update_interval 300
Note: This is not a bug, but a "feature" of some Meshtastic versions: the telemetry interval is scaled down to 60% for small meshes, so an interval of 5 minutes becomes 3 minutes in reality. To achieve a 5-minute update interval, set it to
500instead of300(see issue #8619). -
-
Attach SportIdent's SRR module to a UART pin, a photo will be added later. Configure it using instructions below.
-
Gateway/MQTT configuration: At least one node in the mesh needs to be connected to the internet (via Wi-Fi or Ethernet) to bridge the packets to MQTT.
-
Enable MQTT in the Meshtastic settings, set the broker URL and root topic to
yar.meshtastic --set mqtt.enabled true --set mqtt.root yar -
Set the MQTT server to the one you use in
yarocd.toml(e.g.,broker.emqx.io) and the same username and password. Or set it to empty, if not used.meshtastic --set mqtt.address broker.emqx.io --set mqtt.username "" --set mqtt.password ""
-
To forward SportIdent's SRR punches over LoRa, we need to configure meshtastic to send them over LoRa. First, enable the right serial mode.
meshtastic --set serial.mode SIMPLE --set serial.enabled true -set serial.baud BAUD_38400 \
--set serial.timeout 100Next, configure the correct pins based on the device you own.
We recommend using UART1: RXD1 (15) and TXD1 (16).
meshtastic --set serial.rxd 15 --set serial.txd 16You can also use UART0: RXD0 (19) and TXD0 (20).
We recommend using RXD 13 and TXD 14 for Lilygo T-Beam.
meshtastic --set serial.rxd 13 --set serial.txd 14First, create a yarocd.toml file where you configure the MAC addresses to receive the punches from, as well as all the clients that should send the punches: ROC, SIRAP, serial, etc.
# "SPE" is the shortcut for "Sokol Pezinok", our club name. We use it to name things,
# so our YAROC units are prefixed "SPE-".
log_level = "info"
# You can use a Waveshare e-ink display to show a status table of all YAROC units.
display = "epd2in66"
[mqtt]
broker_url = "broker.emqx.io"
# username = joe
# password = mynameisjoe
[mac-addresses]
spe01 = "b827eb78912e" # YAROC unit with a SIM card
spr01 = "4e18f7a5" # Meshtastic node (uses a 32-bit ID, which is 8 hex characters)
spr02 = "7bfaf584"
[meshtastic]
main_channel = "spe"
# By default, Meshtastic packets are received via MQTT but you can also connect a Meshtastic
# device using a USB cable. `watch_usb` set to true will watch for USB Meshtastic devices.
watch_usb = true
[client.roc]
enable = true
[client.roc.override]
# If you don't have a device registered for ROC, you can remap the device MAC address to
# another one. Useful for meshtastic devices, which can't be registered to ROC directly.
spr01 = "b827eba22867"
spr02 = "b827eba22867"
[client.serial]
# Connect a "UART to USB" board to your Raspberry Pi and receive punches directly into
# orienteering software (MeOS, etc.) over USB.
# Each punch is resent after 1 minute and 10 minutes, because the serial interface does not
# acknowledge receiving punches. The times are not yet configurable.
enable = true
port = "/dev/serial0" # Use "/dev/serial0" on Raspberry Pi
[client.sirap]
# Note: SIRAP is not well tested, use with caution
enable = true
ip = "192.168.1.10"
port = 10000With a config file present, we are able to run the YAROC daemon called yarocd:
yarocdIn order to start developing, install the dependencies using uv:
cd python
uv sync --all-extrasThis will create a .venv and install all extras including dev and lsp. The package is installed in edit mode by default, so you can test each file modification immediately.
