Documentation

Ra-02 SX1278 LoRa 433MHz Wireless Transceiver Module for Arduino, ESP32, STM32 & Raspberry Pi | ShillehTek Product Manual
Documentation / Ra-02 SX1278 LoRa 433MHz Wireless Transceiver Module for Arduino, ESP32, STM32 & Raspberry Pi | ShillehTek Product Manual

Ra-02 SX1278 LoRa 433MHz Wireless Transceiver Module for Arduino, ESP32, STM32 & Raspberry Pi | ShillehTek Product Manual

Overview

The Ra-02 is Ai-Thinker's LoRa module built on the Semtech SX1278 — the radio that made kilometer-range, battery-friendly links a hobbyist reality. LoRa's chirp spread-spectrum modulation digs signals out from far below the noise floor, so two of these modules can exchange sensor packets across 2-5 km line-of-sight (hundreds of meters through buildings) while transmitting at just +20 dBm from a coin-sized board. It operates in the 433 MHz ISM band and also speaks FSK/GFSK/OOK for conventional radio work.

The module talks SPI — NSS, SCK, MOSI, MISO plus a RESET line and six DIO event pins (DIO0 signals "packet received/sent" and is the only one most libraries use). Sixteen castellated pads on 2mm pitch, a U.FL connector for the antenna, and that's the whole interface. It is strictly a 3.3V device: 5V on VCC or the SPI pins kills it, so classic 5V Arduinos need a level shifter while ESP32, Pi, and Pico connect directly.

One hard rule before anything else: never power it up and transmit without an antenna attached — the reflected RF destroys the output stage in seconds. Screw a 433 MHz antenna onto the U.FL (or a U.FL-to-SMA pigtail) first, then enjoy the fun parts: remote weather stations, farm and greenhouse telemetry, GPS trackers, off-grid text messaging, and multi-node sensor networks that WiFi could never reach.

At a Glance

Radio
Semtech SX1278 LoRa
Frequency
433 MHz ISM band
TX Power
Up to +20 dBm
Range
2-5 km line of sight
Interface
SPI + DIO0..DIO5
Supply Voltage
3.3V ONLY

Specifications

Parameter Value
Module / Chipset Ai-Thinker Ra-02, Semtech SX1278
Frequency Range 410 - 525 MHz (433 MHz band typical)
Modulation LoRa chirp spread spectrum; FSK/GFSK/OOK modes
Max TX Power +20 dBm (~100 mW) via PA_BOOST
Sensitivity Down to -148 dBm (SF12, narrow BW)
Spreading Factor / BW SF6-SF12; 7.8 kHz - 500 kHz bandwidth
Data Rate ~18 bps (max range) to ~37.5 kbps
Supply Voltage 1.8 - 3.7V (3.3V nominal) — NOT 5V tolerant
Current ~120 mA TX @ +20 dBm, ~12 mA RX, ~1 uA sleep
Interface SPI (NSS/SCK/MOSI/MISO) + RESET + DIO0-DIO5
Antenna U.FL/IPEX connector — 433 MHz antenna required
Size 17 x 16 mm, 16 castellated pads (2.0 mm pitch)

Pinout Diagram

Pins 1-8 down the left: GND, GND, 3.3V, RESET, DIO0, DIO1, DIO2, DIO3. Pins 9-16 up the right: GND, DIO4, DIO5, SCK, MISO, MOSI, NSS, GND. The U.FL antenna socket sits at the top corner. For basic LoRa links you wire the SPI four, RESET, DIO0, power and ground — DIO1-DIO5 can stay unconnected.

Ra-02 SX1278 LoRa 433MHz module pinout diagram showing GND, 3.3V, RESET, DIO0-DIO5, NSS, MOSI, MISO and SCK pins

Wiring Guide

Arduino Wiring (3.3V caution!)

A 5V Uno/Nano needs its SPI outputs level-shifted down to 3.3V. Use a level shifter module or resistor dividers on SCK, MOSI, NSS, and RESET; MISO (module → Arduino) connects directly.

Ra-02 Pin Arduino Pin Details
3.3V 3.3V NOT 5V — add 100uF locally
GND (any) GND
NSS D10 (via shifter) Chip select
SCK / MOSI D13 / D11 (via shifter) SPI
MISO D12 (direct) 3.3V high reads fine
RESET D9 (via shifter)
DIO0 D2 (direct) RX/TX done interrupt
Warning: The Uno's 3.3V regulator supplies only ~50 mA — not enough for +20 dBm transmit bursts (~120 mA). Use an external 3.3V regulator (AMS1117 breadboard module) with grounds tied, or better, drive the Ra-02 from a natively-3.3V board.

ESP32 Wiring (direct, no shifting)

Ra-02 Pin ESP32 Pin Details
3.3V / GND 3V3 / GND
NSS GPIO 5 Chip select
SCK GPIO 18 VSPI
MOSI GPIO 23
MISO GPIO 19
RESET GPIO 14
DIO0 GPIO 26 Interrupt

Raspberry Pi Wiring (SPI0)

Ra-02 Pin Pi Pin Details
3.3V / GND Pin 1 / Pin 6
NSS Pin 24 (GPIO 8, CE0)
SCK Pin 23 (GPIO 11)
MOSI Pin 19 (GPIO 10)
MISO Pin 21 (GPIO 9)
RESET Pin 15 (GPIO 22)
DIO0 Pin 18 (GPIO 24)
Tip: Enable SPI in raspi-config first. The Pi's 3.3V rail handles the TX bursts fine — no external regulator needed.

Raspberry Pi Pico Wiring (SPI0)

Ra-02 Pin Pico Pin Details
3.3V / GND 3V3(OUT) / GND
NSS GP5 Chip select
SCK GP2 (SPI0 SCK)
MOSI GP3 (SPI0 TX)
MISO GP4 (SPI0 RX)
RESET GP6
DIO0 GP7

Code Examples

The Arduino/ESP32 sketches use Sandeep Mistry's LoRa library (a sender and a receiver — flash one of each). The Pi and Pico examples use popular SX127x Python/MicroPython drivers. Both ends of a link must match frequency, spreading factor, bandwidth, and sync word.

Arduino / ESP32 — Sender (Arduino IDE)

ra02_sender.ino
// Ra-02 SX1278 - LoRa Sender (Arduino IDE)
// Library: "LoRa" by Sandeep Mistry (Library Manager)
// ESP32 pins: NSS=5, RESET=14, DIO0=26 (change for your wiring)

#include <SPI.h>
#include <LoRa.h>

const long FREQ = 433E6;
int counter = 0;

void setup() {
  Serial.begin(115200);
  LoRa.setPins(5, 14, 26);          // NSS, RESET, DIO0

  if (!LoRa.begin(FREQ)) {
    Serial.println("LoRa init failed - check wiring/antenna!");
    while (1);
  }
  LoRa.setSpreadingFactor(9);       // 7 = fast, 12 = max range
  LoRa.setSignalBandwidth(125E3);
  LoRa.setTxPower(17);              // dBm (max 20)
  LoRa.setSyncWord(0x12);           // private-network marker
  Serial.println("LoRa sender ready");
}

void loop() {
  Serial.print("Sending packet ");
  Serial.println(counter);

  LoRa.beginPacket();
  LoRa.print("Hello #");
  LoRa.print(counter++);
  LoRa.endPacket();

  delay(2000);
}

Arduino / ESP32 — Receiver (Arduino IDE)

ra02_receiver.ino
// Ra-02 SX1278 - LoRa Receiver (Arduino IDE)
// Same library and settings as the sender.

#include <SPI.h>
#include <LoRa.h>

void setup() {
  Serial.begin(115200);
  LoRa.setPins(5, 14, 26);

  if (!LoRa.begin(433E6)) {
    Serial.println("LoRa init failed!");
    while (1);
  }
  LoRa.setSpreadingFactor(9);
  LoRa.setSignalBandwidth(125E3);
  LoRa.setSyncWord(0x12);
  Serial.println("LoRa receiver ready");
}

void loop() {
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    String msg = "";
    while (LoRa.available()) {
      msg += (char)LoRa.read();
    }
    Serial.print("Received: '");
    Serial.print(msg);
    Serial.print("'  RSSI: ");
    Serial.print(LoRa.packetRssi());
    Serial.print(" dBm  SNR: ");
    Serial.println(LoRa.packetSnr());
  }
}

Raspberry Pi (Python)

ra02_rpi.py
#!/usr/bin/env python3
# Ra-02 SX1278 - Raspberry Pi LoRa receiver (pyLoRa)
# Install: pip3 install pyLoRa spidev RPi.GPIO
# Wiring: NSS->CE0, RESET->GPIO22, DIO0->GPIO24 (BOARD mode in lib config)

from SX127x.LoRa import LoRa
from SX127x.board_config import BOARD
import time

BOARD.setup()

class Receiver(LoRa):
    def __init__(self):
        super(Receiver, self).__init__(verbose=False)
        self.set_mode(0x80)          # sleep, LoRa mode
        self.set_freq(433.0)
        self.set_spreading_factor(9)
        self.set_bw(7)               # 7 = 125 kHz
        self.set_sync_word(0x12)
        self.set_rx_crc(True)

    def on_rx_done(self):
        payload = self.read_payload(nocheck=True)
        text = bytes(payload).decode(errors="ignore")
        print("Received: '{}'  RSSI: {} dBm".format(
            text, self.get_pkt_rssi_value()))
        self.set_mode(0x85)          # back to RX continuous

lora = Receiver()
print("LoRa receiver ready (433 MHz, SF9)")
lora.set_mode(0x85)                  # RX continuous

try:
    while True:
        time.sleep(0.5)
except KeyboardInterrupt:
    BOARD.teardown()
    print("Stopped by user")

Raspberry Pi Pico (MicroPython)

ra02_pico.py
# Ra-02 SX1278 - Pico MicroPython sender
# Driver: copy sx127x.py from the micropython-lora project
#   (github.com/martynwheeler/u-lora or similar sx127x.py) to the Pico
# Wiring: SCK=GP2, MOSI=GP3, MISO=GP4, NSS=GP5, RESET=GP6, DIO0=GP7

from machine import Pin, SPI
from sx127x import SX127x
import time

lora_cfg = {
    "frequency": 433E6,
    "spreading_factor": 9,
    "signal_bandwidth": 125E3,
    "tx_power_level": 17,
    "sync_word": 0x12,
}

spi = SPI(0, baudrate=5_000_000,
          sck=Pin(2), mosi=Pin(3), miso=Pin(4))

lora = SX127x(spi,
              pins={"ss": 5, "reset": 6, "dio_0": 7},
              parameters=lora_cfg)

counter = 0
print("LoRa sender ready (433 MHz, SF9)")
while True:
    msg = "Pico #{}".format(counter)
    print("Sending:", msg)
    lora.println(msg)
    counter += 1
    time.sleep(2)

Frequently Asked Questions

Do I really need the antenna before powering it on?
Yes — treat it as law. Transmitting into no antenna reflects the full +20 dBm back into the SX1278's power amplifier, which can die in a handful of packets. Receiving without an antenna is harmless but nearly deaf. Screw on a 433 MHz whip via a U.FL pigtail before the first power-up and leave it on.
LoRa.begin() fails / the library never initializes. What now?
That's SPI not reaching the chip: check NSS, SCK, MOSI, MISO one by one against your setPins() call, confirm RESET is wired (the library pulses it), and verify 3.3V at the module's pin under load. On breadboards, the 2mm-pitch module on an adapter with long jumpers sometimes needs the SPI clock dropped. A quick sanity test is reading the version register — 0x12 means the chip is alive.
The two modules just won't hear each other.
Every radio parameter must match: frequency (433E6 both ends), spreading factor, bandwidth, sync word, and CRC setting. A mismatch in any one means silence. Also confirm both antennas are for 433 MHz — an 868/915 MHz whip looks identical and cuts range brutally. Start with the two boards a few meters apart (not centimeters — extreme close range can overload the receiver).
How do I get maximum range?
Raise the spreading factor (SF11/SF12), narrow the bandwidth (62.5 or 125 kHz), use +20 dBm, and — above all — get antennas high and in clear line of sight; elevation beats every software setting. The cost is airtime: an SF12 packet takes over a second, drains batteries, and limits how often you may legally transmit. SF9/125 kHz is a sweet spot for km-class links.
Is 433 MHz legal where I live?
433 MHz is an ISM band in ITU Region 1 (Europe, Africa, Russia) and widely used elsewhere, but rules differ: the US ISM band for LoRa is 915 MHz, and 433 MHz there falls under amateur licensing. Duty-cycle limits (often 1-10%) apply in the EU. Check your local regulations — and if you need 868/915 MHz, use the matching Ra-01/other SX127x variant instead.
Can it connect to WiFi-style networks or the internet? What about LoRaWAN?
LoRa is point-to-point packet radio — no TCP/IP, no pairing. You define the protocol, which is the fun part. LoRaWAN is a separate network layer on top (gateways, network servers, TTN); the SX1278 hardware supports it via LMIC-type libraries, but 433 MHz LoRaWAN coverage is rare — most public LoRaWAN runs at 868/915 MHz. For internet bridging, pair one Ra-02 node with an ESP32 that relays over WiFi.
How long can a battery node last?
Very: the SX1278 sleeps at ~1 uA, and a transmit burst is ~120 mA for well under a second at moderate SF. A node that wakes every 10 minutes, reads a sensor, and fires one SF9 packet can run months to years on AA cells — provided the microcontroller also deep-sleeps and the regulator's quiescent draw is tiny. The radio is rarely the limiting factor; the rest of the board is.

Related Tutorials