Mesh-PI is, as far as I know, the smallest SX1262 LoRa board ever made for the Raspberry Pi. It's built around the ultra-small 10×10 mm Ebyte E22-900MM22S (Semtech SX1262, 868/915 MHz) module — the board is barely bigger than the module itself.
It's designed to run Meshtastic with the Linux-native daemon meshtasticd, but since it's just a plain SX1262 on the SPI bus, it works with any LoRa / LoRa-mesh stack — Meshtastic, Reticulum / RNode, your own RadioLib project… Ideal for a compact, always-on router / MQTT gateway node, with the full power of Linux behind it: SSH, MQTT, Home Assistant, scripting…
Version 1.0
- Placement for Ebyte E22-900MM22S module — SX1262, 868/915 MHz ISM, up to 22 dBm, ~7 km range, 10×10 mm
- u.FL antenna connector — or solder an edge-mount SMA connector / wire antenna instead
- 2 status LEDs (Green = OK, Red = fault) driven from GPIO
- Powered straight from the Pi 3.3 V rail, with proper bulk + low-ESR decoupling (100 µF tantalum + 47 µF MLCC + 100 nF)
- Designed for
meshtasticd(Meshtastic Linux-native)
Mesh-PI is deliberately minimal and purpose-built for a static router node — small, cheap, efficient, and it does exactly that job, perfectly.
- No GPS — on purpose. Dropped to save space and cost. A fixed router doesn't move, so its location is set once as a fixed position in Meshtastic; an on-board GPS would only add size, price and power draw for nothing.
- 22 dBm — on purpose. The board uses the SX1262's native 22 dBm rather than a 1 W (30 dBm) amplified front-end. Going 1 W would mean tapping the Pi 5 V rail and adding a dedicated 3.3 V regulator for the extra current — which would blow up the whole "tiny shield" idea. At 22 dBm the module runs straight off the Pi 3.3 V and stays cool. The E22-900 covers 850–930 MHz, so it works in EU868, US915 and the other 900 MHz regions.
⚠️ Meshtastic does not auto-cap the output to the EU legal limit — you must set the TX power yourself (see the Power limits & regulations section below).
Small, focused, and it just works. 🎯
SPI is the classic MOSI / MISO / SCLK. NSS (chip-select) sits on GPIO25 — a free GPIO, not CE0 — to avoid the cs-gpios conflict of recent Raspberry Pi kernels (meshtasticd / RadioLib drives it directly). The RF switch uses DIO2 for TX (DIO2_AS_RF_SWITCH) and a GPIO for RX.
Raspberry PI E22-900MM22S (SX1262)
GPIO25 <----> NSS (chip select)
SCLK <----> SCK
MOSI <----> MOSI
MISO <----> MISO
GPIO23 <----> NRST (reset, active low)
GPIO27 <----> BUSY
GPIO24 <----> DIO1 (IRQ)
GPIO22 <----> RXEN
DIO2 <----> TXEN (tied together -> DIO2_AS_RF_SWITCH)
DIO3 : not connected (32 MHz XTAL on module, no TCXO)
Raspberry PI On Board LEDs
GPIO18 <----> Green LED (status OK)
GPIO17 <----> Red LED (fault)
Mesh-PI is a partial HAT — its 2×7 socket plugs onto a 14-pin block of the Pi's 40-pin GPIO header: physical pins 11 → 24. Position it exactly as shown, and it can only go one way:
- The socket covers pins 11–24 — pins 1–10 stay free on the SD-card side, 25–40 free on the other side.
- Mount it exactly as in the photo above — don't shift it by a row or plug it in flipped: any offset puts the radio on the wrong pins.
- Press it fully and squarely onto the header before powering the Pi.
Need an enclosure? Finn designed a neat Meshtastic Raspberry Pi Zero 2 W case with foot on Printables — a simple, stationary enclosure with an integrated stand, purpose-built for a headless Pi Zero 2 W LoRa node (no buttons, GPS or display to cut out). A great way to finish off a Mesh-PI router.
Big thanks to Finn for designing and sharing it! 🙏
Install the Meshtastic Linux daemon (see the official docs), then declare the radio in /etc/meshtasticd/config.yaml:
Lora:
Module: sx1262
CS: 25
IRQ: 24
Busy: 27
Reset: 23
RXen: 22
DIO2_AS_RF_SWITCH: true
# No DIO3_TCXO_VOLTAGE — the E22-900MM22S uses a passive 32 MHz XTAL, not a TCXO
⚠️ Do NOT setDIO3_TCXO_VOLTAGEon this board. The MM22S variant is crystal-based; setting it would tell the SX1262 to power a non-existent TCXO and the radio would fail to init (-707). (The larger M22S is TCXO — that's a different module.)
Enable SPI and set the boot state of the reset / LED pins in /boot/firmware/config.txt:
dtparam=spi=on
# Keep the radio out of reset from the bootloader (NRST is active-low -> drive high)
gpio=23=op,dh
# LEDs off at boot (active-high -> drive low)
gpio=17,18=op,dl
Then set the LoRa region and node role from any Meshtastic client (the phone app), or the Meshtastic Python CLI — install it with pipx install meshtastic, then:
meshtastic --host localhost --set lora.region EU_868 --set device.role ROUTER
The E22-900MM22S can transmit at up to 22 dBm (~160 mW), and Meshtastic's EU_868 preset will happily let it — on a Mesh-PI I measured Final Tx power: 22 dBm, not capped to any lower value.
In the EU, the 868 MHz ISM band is legally limited — over most of the band that's 25 mW ERP (~14 dBm). Running the radio at 22 dBm where that isn't permitted is a regulatory violation, and it is entirely up to you to comply with your own country's rules.
So on this board, set the TX power yourself — don't leave it at the region maximum. It's the lora.tx_power setting, in dBm:
meshtastic --host localhost --set lora.tx_power 14
(or in the phone app: LoRa → Tx Power). A value of 0 means "use the region maximum", so set an explicit value — e.g. 14 for the EU — to stay within your legal limit.
Disclaimer: you alone are responsible for operating this board within your local radio regulations. The author is not responsible for any misuse, non-compliant configuration, or interference caused by running it above the legal power limit for your region.
The two on-board LEDs give an at-a-glance health status, blinked from GPIO by a small systemd service:
- 🟢 Green (GPIO18) blinks when WiFi and
meshtasticdare both up - 🔴 Red (GPIO17) blinks when either one is down
The script is scripts/monitoring-led.sh (uses gpioset from libgpiod v2).
# 1. Copy the script in place
sudo install -m 0755 scripts/monitoring-led.sh /usr/local/bin/monitoring-led.sh
# 2. Create the systemd service
sudo tee /etc/systemd/system/monitoring-led.service > /dev/null <<'EOF'
[Unit]
Description=Mesh-PI monitoring LEDs (green=OK, red=fault)
After=NetworkManager.service meshtasticd.service
[Service]
Type=simple
ExecStart=/usr/local/bin/monitoring-led.sh
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# 3. Enable + start (runs at every boot)
sudo systemctl enable --now monitoring-ledCheck with systemctl status monitoring-led — the green LED should start blinking. The gpio=17,18=op,dl line in config.txt above keeps both LEDs off during boot, before the service takes over.
This design is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License — build it, tweak it, share it, but not for commercial use.
No need to — Mesh-PI is available fully assembled and tested on my Lectronz store, built and shipped from France. It's coming to my Tindie store as well.
European customers may prefer ordering on Lectronz, which offers additional payment methods and pricing in Euros.
News and other projects on my blog.







