Lesson 13: SX1262 Wireless Module: LoRa Transceiver¶
Compatible development boards: CrowPanel Advanced 7 / 9 / 10.1-inch ESP32-P4 HMI AI Display Development Boards
Model interchangeability: The 7-inch, 9-inch, and 10.1-inch models are fully interchangeable in terms of hardware interfaces and software code; only their physical dimensions differ. Please select a model based on your actual display size and use case; no code modifications are required for this lesson.
1. Course Introduction¶
In this lesson, we will use the Arduino IDE to drive the SX1262 LoRa module via the SPI interface and the RadioLib library, implementing point-to-point wireless data transmission and reception. The lesson includes two projects—the transmitter (TX) and the receiver (RX)—which require two ESP32-P4 development boards to be paired and used together. The TX board sends an incrementing counter data packet TX_Hello World:N once per second and displays the counter value on the screen; upon receiving a data packet, the RX board displays the counter value as RX_Hello World:N on the screen, along with the RSSI and SNR values. After flashing the program, the TX board's screen displays a white background with black text "TX_Hello World:N", and the number increments once per second; the RX board's screen displays the "RX_Hello World:N" counter, which increments each time data is received, and shows the RSSI and SNR in real time. Through this experiment, learners will complete validation of a full wireless communication link, covering SPI bus configuration, SX1262 LoRa initialization, interrupt-driven transmit/receive operations, and real-time LVGL display.
2. Learning Objectives¶
Upon completing this lesson, you should be able to:
- Understand the responsibilities of the TX/RX ends and the fully identical LoRa parameters.
- Be able to explain the SX1262 SPI connections (SCK/MISO/MOSI/NSS/IRQ/NRST/BUSY) and the function of each pin.
- Be able to explain the meaning of the LoRa parameters (frequency 915 MHz, BW 125 kHz, SF7, CR7).
- Be able to complete compilation and flashing of both boards, and observe the TX count incrementing, the RX count incrementing with reception, and real-time RSSI/SNR updates.
3. Preparation¶
- Hardware: Two CrowPanel Advanced 7 / 9 / 10.1-inch ESP32-P4 HMI AI Display development boards; two USB Type-C data cables that support data transfer; two SX1262 LoRa modules, with one module connected to each development board.
Code reference link: https://github.com/Elecrow-RD/CrowPanel-Advanced-7inch-ESP32-P4-HMI-AI-Display-1024x600-IPS-Touch-Screen/tree/master/example
4. Software Operation Steps¶
Double-click to open the Lesson 13 code (.ino file).
(There are two sets of code here, one for transmitting and one for receiving.)
After opening the code, first go to bsp_wireless.h and enable the definitions related to the SX1262 module used in this lesson.
Configure the relevant options as follows.
- Board:
ESP32P4 Dev Module - Core Debug Level:
Info - Flash Frequency / Mode / Size:
80MHz/QIO/16MB (128Mb) - Partition Scheme:
16M Flash (3MB APP/9.9MB FATFS) - PSRAM:
Enabled - USB Mode:
Hardware CDC and JTAG - Port: After connecting the USB data cable to the board's UART0, select the newly appeared COM port under "Tools → Port".
Follow the library import steps explained in detail in Lesson 1 to import the library files required by this project into the development environment, ensuring that the code can correctly locate the relevant dependencies during compilation, thereby guaranteeing proper program operation.
5. Hardware Operation Steps¶
Now that the code is ready, we need to flash the ESP32-P4 to see the results in action.
First, connect the Advance-P4 device to your computer host via a USB cable.
With the power off, install the two SX1262 LoRa modules into the wireless module slots.
When running multiple peripherals, add independent Type-C power to the USB 2.0 port.
Before uploading the code, first select the upload configuration by following "4. Software Operation Steps".
Connect UART0, compile and upload using the general configuration; keep the development board powered.
After the code is uploaded successfully:
The TX board displays TX_Hello World:i; the RX board displays RX_Hello World:i, and shows RSSI (dBm) and SNR (dB).
Both ends must use the same frequency, bandwidth, spreading factor, coding rate, and sync word.
6. Key Code Explanation¶
6.1 TX Counter UI and Transmission Tasks¶
sx1262_tx_init();
lvgl_show_counter_label_init();
uint32_t i = sx1262_get_tx_counter();
lv_label_set_text(s_hello_label, text);
TickType_t last_wake_time = xTaskGetTickCount();
const TickType_t frequency = pdMS_TO_TICKS(1000);
while (1) {
bool ok = send_lora_pack_radio();
if (!ok) MAIN_ERROR("LoRa TX failed");
vTaskDelayUntil(&last_wake_time, frequency);
}
The TX sketch initializes the radio, creates the TX_Hello World:0 label under a non-blocking LVGL lock, then runs two pinned FreeRTOS tasks. lora_tx_task() calls send_lora_pack_radio() every second with vTaskDelayUntil(), while ui_counter_task() reads sx1262_get_tx_counter(), updates the label under the LVGL lock, and logs the text.
6.2 RX Callback and LVGL¶
if (sx1262_is_data_received()) {
size_t len = sx1262_get_received_len();
received_lora_pack_radio(len);
}
vTaskDelay(10 / portTICK_PERIOD_MS);
The RX task polls the SX1262 data flag every 10 ms, obtains the actual packet length, and forwards the packet to received_lora_pack_radio(). The registered callback increments the counter, formats the message/RSSI/SNR labels while holding lvgl_port_lock(-1), and logs the received measurements.
7. Experimental Observations¶
-
The TX counter increments by approximately 1 per second; the RX displays the corresponding message and increments only after receiving real data.
-
The RX can display RSSI/SNR, and the values change with distance, obstruction, and antenna orientation.
8. Frequently Asked Questions and Troubleshooting¶
- When there is no data, sequentially check the module orientation, the SPI/CS/RST/IRQ/BUSY pins, the frequency/bandwidth/spreading factor/coding rate, the antenna, and the code branch on both ends.
- If the device restarts during operation, first add independent power to the USB 2.0 port.








