LoRa868 v1.2 Module

The LoRa868 v1.2 Module is part of the M5Stack stackable module series. It is a LoRa communication module that operates at a 900MHz frequency and utilizes the SX1262 chip solution.

Support the following products:

LoRa868Module v1.2

UiFlow2 Example

Note

Before using the following examples, please check the DIP switches on the module to ensure that the pins used in the example match the DIP switch positions. For specific configurations, please refer to the product manual page. The SPI configuration has been implemented internally, so users do not need to worry about it.

Sender

Open the cores3_lora_sx1262_tx_example.m5f2 project in UiFlow2.

This example sends data every second.

UiFlow2 Code Block:

cores3_lora_sx1262_tx_example.png

Example output:

None

Receiver

Open the cores3_lora_sx1262_rx_example.m5f2 project in UiFlow2.

This example receives and displays data.

UiFlow2 Code Block:

cores3_lora_sx1262_rx_example.png

Example output:

None

MicroPython Example

Note

Before using the following examples, please check the DIP switches on the module to ensure that the pins used in the example match the DIP switch positions. For specific configurations, please refer to the product manual page. The SPI configuration has been implemented internally, so users do not need to worry about it.

Sender

This example sends data every second.

MicroPython Code Block:

 1# SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
 2#
 3# SPDX-License-Identifier: MIT
 4
 5import os, sys, io
 6import M5
 7from M5 import *
 8from module import LoRaSx1262Module
 9import time
10
11
12title0 = None
13label_t = None
14label_time = None
15label_tx = None
16label_ts = None
17lora868v12_0 = None
18
19
20count = None
21last_time = None
22timestamp = None
23
24
25def setup():
26    global \
27        title0, \
28        label_t, \
29        label_time, \
30        label_tx, \
31        label_ts, \
32        lora868v12_0, \
33        count, \
34        last_time, \
35        timestamp
36
37    M5.begin()
38    Widgets.fillScreen(0x222222)
39    title0 = Widgets.Title("LoRa Module Tx", 3, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu18)
40    label_t = Widgets.Label("Send:", 5, 50, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18)
41    label_time = Widgets.Label("1", 118, 150, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18)
42    label_tx = Widgets.Label("hello", 65, 50, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18)
43    label_ts = Widgets.Label("timestamp:", 5, 150, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18)
44
45    lora868v12_0 = LoRaSx1262Module(5, 1, 10, 2, 868000, "250", 8, 8, 12, 0x12, 10)
46    count = 0
47    last_time = time.ticks_ms()
48
49
50def loop():
51    global \
52        title0, \
53        label_t, \
54        label_time, \
55        label_tx, \
56        label_ts, \
57        lora868v12_0, \
58        count, \
59        last_time, \
60        timestamp
61    M5.update()
62    if (time.ticks_diff((time.ticks_ms()), last_time)) >= 1000:
63        last_time = time.ticks_ms()
64        count = count + 1
65        timestamp = lora868v12_0.send((str("hello M5 ") + str(count)), None)
66        label_tx.setText(str((str("hello M5 ") + str(count))))
67        label_time.setText(str(last_time))
68
69
70if __name__ == "__main__":
71    try:
72        setup()
73        while True:
74            loop()
75    except (Exception, KeyboardInterrupt) as e:
76        try:
77            from utility import print_error_msg
78
79            print_error_msg(e)
80        except ImportError:
81            print("please update to latest firmware")

Example output:

None

Receiver

This example receives and displays data.

MicroPython Code Block:

  1# SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
  2#
  3# SPDX-License-Identifier: MIT
  4
  5import os, sys, io
  6import M5
  7from M5 import *
  8from module import LoRaSx1262Module
  9import time
 10
 11
 12title0 = None
 13label_r = None
 14label_rx = None
 15label_t = None
 16label_time = None
 17label_rssi = None
 18label_snr = None
 19label_rssi_v = None
 20label_snr_v = None
 21lora868v12_0 = None
 22
 23
 24lora868v12_data = None
 25rssi = None
 26snr = None
 27last_time = None
 28
 29
 30def lora868v12_0_receive_event(received_data):
 31    global \
 32        title0, \
 33        label_r, \
 34        label_rx, \
 35        label_t, \
 36        label_time, \
 37        label_rssi, \
 38        label_snr, \
 39        label_rssi_v, \
 40        label_snr_v, \
 41        lora868v12_0, \
 42        lora868v12_data, \
 43        rssi, \
 44        snr, \
 45        last_time
 46    lora868v12_data = received_data
 47    label_rx.setText(str(lora868v12_data.decode()))
 48    rssi = lora868v12_data.rssi
 49    snr = lora868v12_data.snr
 50    label_rssi_v.setText(str(rssi))
 51    label_snr_v.setText(str(snr))
 52
 53
 54def setup():
 55    global \
 56        title0, \
 57        label_r, \
 58        label_rx, \
 59        label_t, \
 60        label_time, \
 61        label_rssi, \
 62        label_snr, \
 63        label_rssi_v, \
 64        label_snr_v, \
 65        lora868v12_0, \
 66        lora868v12_data, \
 67        rssi, \
 68        snr, \
 69        last_time
 70
 71    M5.begin()
 72    Widgets.fillScreen(0x222222)
 73    title0 = Widgets.Title("LoRa Module Rx", 3, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu18)
 74    label_r = Widgets.Label("Recv:", 5, 50, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18)
 75    label_rx = Widgets.Label(" ", 65, 50, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18)
 76    label_t = Widgets.Label("timestamp:", 5, 150, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18)
 77    label_time = Widgets.Label("1", 118, 150, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18)
 78    label_rssi = Widgets.Label("RSSI: ", 5, 80, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18)
 79    label_snr = Widgets.Label("SNR: ", 5, 108, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18)
 80    label_rssi_v = Widgets.Label(" ", 65, 80, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18)
 81    label_snr_v = Widgets.Label(" ", 65, 108, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18)
 82
 83    lora868v12_0 = LoRaSx1262Module(5, 1, 10, 2, 868000, "250", 8, 8, 12, 0x12, 10)
 84    lora868v12_0.set_irq_callback(lora868v12_0_receive_event)
 85    lora868v12_0.start_recv()
 86    last_time = time.ticks_ms()
 87
 88
 89def loop():
 90    global \
 91        title0, \
 92        label_r, \
 93        label_rx, \
 94        label_t, \
 95        label_time, \
 96        label_rssi, \
 97        label_snr, \
 98        label_rssi_v, \
 99        label_snr_v, \
100        lora868v12_0, \
101        lora868v12_data, \
102        rssi, \
103        snr, \
104        last_time
105    M5.update()
106    if (time.ticks_diff((time.ticks_ms()), last_time)) >= 1000:
107        last_time = time.ticks_ms()
108        label_time.setText(str(last_time))
109
110
111if __name__ == "__main__":
112    try:
113        setup()
114        while True:
115            loop()
116    except (Exception, KeyboardInterrupt) as e:
117        try:
118            from utility import print_error_msg
119
120            print_error_msg(e)
121        except ImportError:
122            print("please update to latest firmware")

Example output:

None

API

class LoRaSx1262Module

class module.lora_sx1262.LoRaSx1262Module(pin_rst=5, pin_cs=1, pin_irq=10, pin_busy=2, freq_khz=868000, bw='250', sf=8, coding_rate=8, reamble_len=12, syncword=0x12, output_power=10)

Create an LoRaSx1262Module object.

Parameters:
  • timer_id (int) – The Timer ID. Range: 0~3. Default is 0.

  • pin_rst (int) – (RST) Reset pin number.

  • pin_cs (int) – (NSS) Chip select pin number.

  • pin_irq (int) – (IRQ) Interrupt pin number.

  • pin_busy (int) – (BUSY) Busy pin number.

  • freq_khz (int) – LoRa RF frequency in KHz, with a range of 850000 KHz to 930000 KHz.

  • bw (str) –

    Bandwidth, options include:

    • "7.8": 7.8 KHz

    • "10.4": 10.4 KHz

    • "15.6": 15.6 KHz

    • "20.8": 20.8 KHz

    • "31.25": 31.25 KHz

    • "41.7": 41.7 KHz

    • "62.5": 62.5 KHz

    • "125": 125 KHz

    • "250": 250 KHz

    • "500": 500 KHz

  • sf (int) – Spreading factor, range from 7 to 12. Higher spreading factors allow reception of weaker signals but with slower data rates.

  • coding_rate (int) – Forward Error Correction (FEC) coding rate expressed as 4/N, with a range from 5 to 8.

  • preamble_len (int) – Length of the preamble sequence in symbols, range from 0 to 255.

  • syncword (int) – Sync word to mark the start of the data frame, default is 0x12.

  • output_power (int) – Output power in dBm, range from -9 to 22.

UiFlow2 Code Block:

init.png

MicroPython Code Block:

from module import LoRaSx1262Module

lora868v12_0 = LoRaSx1262Module(5, 1, 10, 2, 868000, '250', 8, 8, 12, 0x12, 10)
set_irq_callback(callback)

Set the interrupt callback function to be executed on IRQ.

Parameters:

callback – The callback function to be invoked when the interrupt is triggered. The callback should not take any arguments and should return nothing.

Call start_recv() to begin receiving data.

UiFlow2 Code Block:

set_irq_callback.png

MicroPython Code Block:

lora868v12_0.set_irq_callback()
start_recv()

Start receive data.

This method initiates the process to begin receiving data.

UiFlow2 Code Block:

start_recv.png

MicroPython Code Block:

lora868v12_0.start_recv()
recv(self, timeout_ms, rx_length, rx_packet)

Receive data.

Parameters:
  • timeout_ms (int) – Timeout in milliseconds (optional). Default is None.

  • rx_length (int) – Length of the data to be read. Default is 0xFF.

  • rx_packet (RxPacket) – An instance of RxPacket (optional) to reuse.

Returns:

Received packet instance

Return type:

RxPacket

Attempt to receive a LoRa packet. Returns None if timeout occurs, or returns the received packet instance.

UiFlow2 Code Block:

recv.png

MicroPython Code Block:

data = lora868v12_0.recv()
send(buf, tx_at_ms=None)

Send data.

Parameters:
  • packet (str | list | tuple | int | bytearray) – The data to be sent.

  • tx_at_ms (int) – The timestamp in milliseconds when to send the data (optional). Default is None.

Returns:

Returns a timestamp (result of time.ticks_ms()) indicating when the data packet was sent.

Return type:

int

Send a data packet and return the timestamp after the packet is sent.

UiFlow2 Code Block:

send.png

MicroPython Code Block:

lora868v12_0.send()
standby()

Set module to standby mode.

Puts the LoRa module into standby mode, consuming less power.

UiFlow2 Code Block:

standby.png

MicroPython Code Block:

lora868v12_0.standby()
sleep()

Put the module to sleep mode.

Reduces the power consumption by putting the module into deep sleep mode.

UiFlow2 Code Block:

sleep.png

MicroPython Code Block:

lora868v12_0.sleep()
irq_triggered()

Check IRQ trigger.

Returns:

Returns True if an interrupt service routine (ISR) has been triggered since the last send or receive started.

Return type:

bool

UiFlow2 Code Block:

irq_triggered.png

MicroPython Code Block:

lora868v12_0.irq_triggered()

class RxPacket

class lora.RxPacket

Create an RxPacket object.

decode()

Decode the received data.

ticks_ms()

Timestamp of when the data was received.

rssi()

Received signal strength (units: dBm).

snr()

Signal-to-noise ratio (units: dB * 4).

valid_crc()

CRC validity check.