Skip to content

Well-annotated MicroPython codes to operate SX1276 LoRa modem

Notifications You must be signed in to change notification settings


Folders and files

Last commit message
Last commit date

Latest commit



27 Commits

Repository files navigation


  • SX1276 is a LoRa modem that can send and receive data over a long distance (kilometers away) in an enery-efficient way.
  • This repo is to help the beginner learning how to operate the SX1276 chip (do basic transmittion/Tx and reception/Rx).
  • This repo is almost a rewrite of martynwheeler/u-lora with extensive annotations.
  • Code is compatible with jgromes/RadioLib (An popular Arduino LoRa Library)

Where to find SX1276

  • Many ESP32 LoRa development boards (Heltec WiFi LoRa 32 V2, TTGO T-Beam V1.1 ) are using SX1276.
  • Adafruit created a standalone breakout based on SX1276: Adafruit RFM95W
  • Either way, the MCU talks to the SX1276 chip via a SPI interface.

Repo for production use

  • MAC link layer is implemented in another repo
    • Adressing
    • Broadcasting
    • Request Acknowledgement
  • Frequency Hopping is also implemented to tranmit large packet since we abide by FCC 15.247: Don't jam one frequency.

See the wiring

Wiring RFM95W with Pico
  • We decide which GPIO we want to use
 # RFM95W         Pico GPIO
 LoRa_MISO_Pin  = 16
 LoRa_CS_Pin    = 17
 LoRa_SCK_Pin   = 18
 LoRa_MOSI_Pin  = 19
 LoRa_G0_Pin    = 20 # DIO0_Pin
 LoRa_EN_Pin    = 21
 LoRa_RST_Pin   = 22
 SPI_CH         =  0

Heltec WiFi LoRa 32 V2
  • Predefined (see the pinout)
 LoRa_MISO_Pin = 19
 LoRa_MOSI_Pin = 27
 LoRa_SCK_Pin  =  5
 LoRa_CS_Pin   = 18
 LoRa_RST_Pin  = 14
 LoRa_DIO0_Pin = 26
 LoRa_DIO1_Pin = 35
 LoRa_DIO2_Pin = 34
 SPI_CH        =  1

TTGO T-Beam V1.1
  • Predefined (see the pinout)
 LoRa_MISO_Pin = 19
 LoRa_MOSI_Pin = 27
 LoRa_SCK_Pin  =  5
 LoRa_CS_Pin   = 18
 LoRa_RST_Pin  = 23
 LoRa_DIO0_Pin = 26

How to use SX1276

  • Enable the Adafruit RFM95W before use (No enable pin on other ESP32 development boards so they are always enabled)
  • Configure SPI communication to control the LoRa modem
  • Choose LoRa mode instead of FSK/OOK mode
  • Set parameters: bandwidth (bw), coding rate (CR), header mode, spreading factor (SF), syncword, preamble length, frequency, amplifier.
    • Following waterfall diagram is what the signal out of LoRa modem looks like, I might provide a tutorial about parameters in the future
  • Set an interrupt routine service (IRS) to read incoming message and to monitor modem's working status
  • When message is received during Rx, an IRS is triggered and we read FIFO data buffer. We write FIFO data buffer before the message is sent and then an IRS is triggered during Tx.

Packet Structure

  • Waterfall diagram that shows the physical representation of modulated signal.
  • Header (exists in explicit mode): Payload length, payload's coding rate
  • Explicit header's coding rate is 4/8 and payload's could be different (Tx tells Rx which CR Tx uses).
  • SF is for whole packet

4.1.2. LoRa ® Digital Interface

  • The LoRa ® modem comprises three types of digital interface,
    • static configuration registers
    • status registers
    • a 256-byte user-defined FIFO data buffer
  • We control the modem through this digital interface
    • Practically, we read/write modem's registers via SPI protocol so we can configure its parameters (static configuration registers), query status, send or receive data (buffer registers).

FIFO Buffer

  • In order to write packet data into FIFO user should:
    1. Set register RegFifoAddrPtr's content to *RegFifoTxBaseAddr (register RegFifoTxBaseAddr's content).
    2. Write *RegPayloadLength bytes to the FIFO (RegFifo)
  • In order to read packet data from FIFO user should:
    1. Set RegFifoAddrPtr to *RegFifoRxCurrentAddr.
    2. Read RegRxNbBytes from RegFifo

Jargon in Datasheet

  • RF: Radio Frequency
  • RFI: RF Input
  • RFO: RF Output
  • { High Frequency: {Band 1: ~915MHz}, LF: {Band 2: ~433MHz, Band 3: ~150MHz} }
  • PA: Power Amplifier
  • Three amplifiers: RFO_LF, RFO_HF, PA_BOOST
  • PA_HP: High Power
  • PA_HF and PA_LF are high efficiency amplifiers
  • AFC: automatic frequency correction
  • RFOP: RF output power

Data Transmission Sequence (Datasheet Figure 9)

  • Change to Standby mode so the modem initializes everything
  • Start Tx loop
    • Prepare payload to Tx
    • Fill FIFO data buffer with payload
    • Change to Tx mode
    • Wait for TxDone IRQ
      • In ISR, do something and clear IRQ Flags
    • Fall back to Standby mode automatically

Continous Mode Data Reception Sequence (Figure 10)

  • Change to Standby mode so the modem initiate everything
  • Change to Rx Continuous mode
  • Wait for IRQ (RxDone and ValidHeader/PayloadCrcError)
    • In ISR, Read FIFO data buffer to get payload
  • Next IRQ and next FIFO reading

Follow annotated code to learn SX1276

  • Use Rasberry Pi Pico and Adafruit RFM95W as the learning platform
    • How to run MicroPython on Pico
  • MicroPython codes Tx and Rx are commented extensively for learning
    • They are compatible with RadioLib library.
  • Thanks martynwheeler/u-lora and jgromes


Well-annotated MicroPython codes to operate SX1276 LoRa modem







No releases published


No packages published