Mari is a lightweight wireless connectivity solution designed for dense IoT networks, with a focus on supporting real-time interactions and fast over-the-air (OTA) updates.
The driving use case for the design of Mari is the OpenSwarm Testbed of 1,000 DotBots. Mari is suitable for any dense IoT deployment requiring low-latency communication.
This repository ships two halves:
firmware/β the C firmware that implements the Mari TSCH-over-BLE link layer on Nordic nRF52840 / nRF5340.marilib/β the Python control plane (mari-edge,mari-cloudCLI agents) that talks to a Mari gateway over UART or MQTT and renders a Rich-based real-time TUI.
Each half is self-contained: its build config, tests, and examples live in its own directory.
- TSCH over BLE: Time-Synchronized Channel Hopping (TSCH) over Bluetooth Low Energy 2 Mbps PHY
- Multi-Gateway Architecture: scale by adding more gateways
- Non-Coordinated Gateways: gateways are independent β infrastructure setup is simple
- Fast Handovers: quick transitions between gateways as nodes move
- Low-Power Operation: energy-efficient for battery-powered devices
- Real-Time Communication: 100β150 ms average latency with 100 nodes per gateway
- Reasonable Throughput for OTAP: about 10 Kb/s downlink
- Quick Network Join: 150 ms best-case, 6 s worst-case
- Dense Network Support: scales for hundreds to thousands of nodes
mari/
βββ firmware/ # C firmware (mari TSCH-over-BLE link layer)
β βββ app/ # Applications and tests
β βββ drv/ # Hardware drivers
β βββ mari/ # Core protocol implementation
β βββ nRF/ # Nordic Semiconductor SDK files
βββ marilib/ # Python package + tests + examples
βββ marilib/ # The importable Python package
βββ tests/
βββ examples/
βββ pyproject.toml
βββ install_marilib.sh
Validated on Nordic nRF52833, nRF52840, and nRF5340 (dual-core; gateway on the network core).
cd firmware
make node # nrf52840dk node
make gateway # nRF5340 net-core gateway
make all # default
make docker # CI path (Docker-wrapped SEGGER ES)The project uses SEGGER Embedded Studio .emProject files, clang-format v15, and pre-commit (root config).
// Gateway init
mari_init(MARI_GATEWAY, MARI_NET_ID_DEFAULT, schedule, event_callback);
// Node init
mari_init(MARI_NODE, MARI_NET_ID_PATTERN_ANY, schedule, event_callback);To run a Mari network on your computer, follow the wiki: https://github.com/DotBots/mari/wiki/Getting-started#running-mari-network-on-your-computer
cd marilib
python -m venv .venv && source .venv/bin/activate
pip install -e .For a Raspberry Pi edge node, ./install_marilib.sh (inside marilib/) bootstraps a venv and installs the package.
mari-edge -m mqtts://argus.paris.inria.fr:8883 # UART-attached gateway
mari-cloud -n 0x0100 -m mqtts://argus.paris.inria.fr:8883 # cloud bridge over MQTTmari-edge --help documents all flags. The TUI shows real-time network state with an ASN-decomposed latency breakdown (host/dl/app/ul) and a Q (sf) column for per-node uplink-queue depth β see marilib/AGENTS.md for column semantics.
import time
from marilib.marilib import MarilibEdge
from marilib.serial_uart import get_default_port
def main():
mari = MarilibEdge(lambda event, data: print(event.name, data), get_default_port())
while True:
for node in mari.gateway.nodes:
mari.send_frame(dst=node.address, payload=b"A" * 3)
time.sleep(0.25)
if __name__ == "__main__":
main()More examples in marilib/examples/.
cd marilib
hatch test # pytest --doctest-modules --cov=marilib
hatch fmt --check
hatch buildThis repository uses gitflow: develop is the integration branch, main is releases. Feature branches off develop; PRs target develop.
If you are an AI coding agent working in this repo, read AGENTS.md (cross-cutting), firmware/AGENTS.md, and marilib/AGENTS.md.
Apache 2.0 β see LICENSE.
- Fedrecheski et al., "Mari: Connecting Large Scale Robot Swarms over BLE using TSCH with Multiple Independent Gateways", CrystalFreeIoT Workshop 2025 [Forthcoming]
This project has received funding from the EU's Horizon Europe Framework Programme under Grant Agreement No. 101093046.