Home / Blog / Games

Building a Custom Meshtastic Node with ESP32 + SX1262 (DIY Guide)

Created 2026-02-01 • Updated 2026-02-01

I want this guide to constantly evolve. If you want to suggest changes I could make I have uploaded the markdown file from which this blog post is being generated here: https://cdn.merlin-glander.de/posts/assets/cheap-meshtastic-node.md For changes you want to suggest, email me here: merlin@merlin-glander.de

This guide documents how to build a fully custom Meshtastic node using a generic ESP32 DevKit and an SX1262 LoRa module, powered from a single 18650 battery with proper charging, protection, and voltage regulation.

The focus of this guide is doing it the correct way:

If you are comfortable with soldering and the terminal, this guide is for you.


Why Build a Custom Node?

Building your own Meshtastic node gives you:

This setup is electrically equivalent to many commercial nodes — just without the markup.


Important Concepts (Read This First)

Radio pins are compile-time only

Meshtastic does not allow changing LoRa radio pins at runtime via the CLI or the mobile app.

All radio pin assignments:

If you try to set radio pins using the CLI, it will not work.


SX1262 is not “just SPI”

Unlike older SX127x radios, the SX1262 requires additional control signals:

If any of these are missing or miswired, the radio will fail with:

SX126x init result -2

This error almost always means wiring, not software.


Hardware Used

Core electronics

Power system

Misc

⚠️ SX1262 is 3.3 V only. Never connect it to 5 V.


Power System Design (Battery + Charging)

This build uses a safe and robust battery system suitable for unattended operation.

Components and roles

TP4056 (with protection)

MT3608 boost converter


Power wiring overview

18650 Battery
   │
   ▼
TP4056 (with protection)
   ├─ B+ / B- → Battery
   └─ OUT+ / OUT- → MT3608 input
                      │
                      ▼
               MT3608 (set to 5.0 V)
                      │
                      ▼
              ESP32 VIN / VN

Why this works well


SX1262 ↔ ESP32 Pin Assignment

This is the exact pin mapping used in the working firmware.

SX1262 PinESP32 GPIOPurpose
VCC3V3Radio power
GNDGNDCommon ground
NSS (CS)GPIO5SPI chip select
SCKGPIO18SPI clock
MOSIGPIO23SPI data (ESP32 → radio)
MISOGPIO19SPI data (radio → ESP32)
NRSTGPIO14Radio reset
DIO1GPIO26Radio interrupt (IRQ)
BUSYGPIO25Radio busy indicator
DIO2Not used
DIO3Not used
TXENNot used
RXENNot used

Wiring Checklist

Before powering on:

Most SX1262 problems are wiring mistakes — triple-check this.


Getting the Meshtastic Firmware

Meshtastic uses PlatformIO, not the Arduino IDE.

git clone https://github.com/meshtastic/firmware.git
cd firmware
git checkout develop

Creating a Custom Variant

Meshtastic organizes board definitions as variants.

Create a new variant directory:

cd variants
mkdir esp32_devkit_sx1262

Directory structure:

variants/esp32_devkit_sx1262/
├── platformio.ini
└── variant.h

platformio.ini (Exact Working Configuration)

[env:esp32_devkit_sx1262]
extends = esp32_base
board = esp32doit-devkit-v1

build_flags =
  ${esp32_base.build_flags}
  -D PRIVATE_HW
  -I variants/esp32_devkit_sx1262

lib_deps =
  ${esp32_base.lib_deps}

What this does


variant.h (Exact Working Configuration)

#pragma once

// Minimal custom variant for ESP32 DevKit + external SX1262 module

// --- Radio selection ---
#define USE_SX1262

// --- SX1262 control pins ---
#define SX126X_CS    5    // NSS / CS
#define SX126X_RESET 14   // NRST
#define SX126X_BUSY  25   // BUSY
#define SX126X_DIO1  26   // DIO1 (IRQ)

// --- SPI bus (ESP32 VSPI) ---
#define LORA_SCK  18
#define LORA_MOSI 23
#define LORA_MISO 19

// Compatibility with older Meshtastic code paths
#define LORA_CS   SX126X_CS
#define LORA_DIO1 SX126X_DIO1

// Maximum safe output power for most SX1262 modules
#define SX126X_MAX_POWER 22

// Enable these ONLY if your module explicitly requires them
// #define SX126X_DIO3_TCXO_VOLTAGE 1.8
// #define SX126X_DIO2_AS_RF_SWITCH

Building the Firmware

From the firmware root:

pio run -e esp32_devkit_sx1262

If the build complains about mklittlefs, install a prebuilt mklittlefs binary and ensure it is available in your PATH.


Flashing the ESP32

pio run \
  -e esp32_devkit_sx1262 \
  -t upload \
  --upload-port /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0

A successful flash ends with:

Hash of data verified.
Hard resetting via RTS pin...
[SUCCESS]

Verifying Radio Initialization

Open a serial monitor:

picocom -b 115200 /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0

Expected output:

SX126xInterface(cs=5, irq=26, rst=14, busy=25)
SX126x init result 0

If you see init result -2, recheck wiring.


Connecting to Meshtastic

Serial

meshtastic --port /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0 --info

Bluetooth


Setting the Regulatory Region

Always set the correct region:

meshtastic --port /dev/serial/... --set lora.region EU_868

Common Pitfalls


Final Thoughts

This build gives you:

Once the SX1262 initializes correctly, Meshtastic is extremely stable and reliable.

Happy building 🛰️