Files
micromesh/README.md
T
2026-07-31 23:46:37 -07:00

4.1 KiB

MicroMesh

MicroMesh is a small, dependency-free Meshtastic client for MicroPython. It talks to a Meshtastic device over its serial API and implements the protobuf wire format directly, so google.protobuf, threads, and pyserial are not required.

The initial release supports:

  • serial ToRadio / FromRadio framing and resynchronization;
  • the configuration handshake and a small in-memory node list;
  • text, arbitrary data, and position packets;
  • routing acknowledgements, node/user data, waypoints, and device metrics;
  • familiar generated-protobuf methods: SerializeToString, ParseFromString, CopyFrom, HasField, ClearField, and WhichOneof;
  • preservation of unknown protobuf fields for forward compatibility.

This is intentionally not a complete replacement for the desktop meshtastic package. Configuration and admin messages are currently returned as raw encoded bytes.

Install

From a checkout of this repository, install with a current mpremote:

mpremote mip install package.json

Alternatively, copy the micromesh directory to /lib on the board. After this repository is published on GitHub it can also be installed as mpremote mip install github:ORG/micromesh.

It can also be installed on CPython for development:

python -m pip install .

After the first PyPI release, install it by name with:

python -m pip install micromesh

Quick start

from machine import UART, Pin
from micromesh import PortNum, SerialInterface

uart = UART(1, baudrate=115200, tx=Pin(17), rx=Pin(16), timeout=0)

def received(packet):
    if packet.WhichOneof("payload_variant") != "decoded":
        return
    if packet.decoded.portnum == PortNum.TEXT_MESSAGE_APP:
        print("from !%08x:" % packet.from_, packet.decoded.payload.decode())

mesh = SerialInterface(uart, on_packet=received)
mesh.connect()
mesh.sendText("hello mesh")

while True:
    mesh.poll()

The UART baud rate and pins depend on the attached Meshtastic device. poll() is non-blocking when the UART is configured with timeout=0.

Ready-to-run wiring and code for the Seeed Studio XIAO RP2040, Raspberry Pi Pico, and generic ESP32 boards are in examples/.

Direct messages accept either an integer or Meshtastic's hexadecimal node ID:

mesh.sendText("hello", destinationId="!a1b2c3d4", wantAck=True)
mesh.sendPosition(45.5152, -122.6784, altitude=15)
mesh.sendData(b"custom", portNum=PortNum.PRIVATE_APP)

Protobufs

Messages can be used without a radio:

from micromesh import Data, PortNum

data = Data(portnum=PortNum.TEXT_MESSAGE_APP, payload=b"hello")
encoded = data.SerializeToString()
decoded = Data().ParseFromString(encoded)

Generated-module-style imports are available as micromesh.mesh_pb2 and micromesh.portnums_pb2 for easier porting from the desktop library.

Only the commonly useful schemas are modeled. Unknown fields survive a decode/encode round trip, but their contents are not interpreted. A field named from is accessed as packet.from_ because from is a Python keyword.

Development

python -m unittest discover -s tests

Releasing to PyPI

PyPI publishing uses GitHub Trusted Publishing, so no API token is stored in the repository. Configure a pending publisher at pypi.org/manage/account/publishing with these values:

  • PyPI project name: micromesh
  • GitHub owner: pdxlocations
  • Repository: micromesh
  • Workflow: release.yaml
  • Environment: pypi

Keep the version in pyproject.toml, package.json, and micromesh/__init__.py in sync. Push the change, create a matching GitHub release such as v0.1.0, and publish the release. The workflow builds, validates, and uploads both the wheel and source distribution.

The API protocol is defined by the meshtastic/protobufs project. Update the field declarations in micromesh/messages.py when adopting newer schemas.

manifest.py is also included for freezing the package into custom MicroPython firmware.