Skip to content

sokolpezinok/yaroc

Repository files navigation

YAROC

yaroc-logo

Yet Another ROC. Radio Online Control for orienteering and other sports that use SportIdent timing (trail running, MTB enduro).

Python (Linux) Python (Windows) Rust

It's as if ROC and jSh.radio had a baby.

Features

  • 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

Etymology

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.

Installation

Install the yaroc package from PyPI, which provides the send-punch and yarocd commands. We recommend using uv for easy installation:

uv tool install yaroc

Usage

Send punches from an online control

First, 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

Send punches using LoRa radio

Follow the official Meshtastic documentation:

  1. Flash firmware

  2. Configure the radio. We recommend using a private encrypted channel to avoid unnecessary traffic on public meshes.

    1. Use the client role.

    2. Use the LOCAL_ONLY rebroadcast mode

    3. Set Ok to MQTT to true in the LoRa configuration to allow your packets to be bridged by MQTT:

      meshtastic --set lora.ok_to_mqtt true
    4. Add a channel named serial, it'll be used to transport punches through LoRa. Set Uplink Enabled to true for the serial channel (and any other channel you want to bridge). If your serial channel is at index 1:

      meshtastic --ch-index 1 --ch-set uplink_enabled true
    5. 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 500 instead of 300 (see issue #8619).

  3. Attach SportIdent's SRR module to a UART pin, a photo will be added later. Configure it using instructions below.

  4. 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.

    1. Enable MQTT in the Meshtastic settings, set the broker URL and root topic to yar.

      meshtastic --set mqtt.enabled true --set mqtt.root yar
    2. 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 "" 

Configure meshtastic UART

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 100

Next, configure the correct pins based on the device you own.

RAK4631

We recommend using UART1: RXD1 (15) and TXD1 (16).

meshtastic --set serial.rxd 15 --set serial.txd 16

You can also use UART0: RXD0 (19) and TXD0 (20).

Lilygo T-Beam

We recommend using RXD 13 and TXD 14 for Lilygo T-Beam.

meshtastic --set serial.rxd 13 --set serial.txd 14

Receive punches

First, 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 = 10000

With a config file present, we are able to run the YAROC daemon called yarocd:

yarocd

Development

In order to start developing, install the dependencies using uv:

cd python
uv sync --all-extras

This 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.

Other projects

Contributors

Languages