Skip to main content

Working with Arduino

This chapter contains the following sections. Please read as needed:

Setting Up Development Environment

1. Installation and Configuration

  • For setting up the Arduino environment and basic usage, please refer to this R4 link; R3 comes pre-installed by default.
  • After setting up the environment, connect the sensor and download the example package.

2. Hardware Configuration

  • The IO level of the Arduino development board must be 3.3V. If using 5V IO levels, a level shifter is required; otherwise the sensor may be damaged.
  • When using Waveshare R3/R4, the following jumper caps must be set to 3.3V before use.
ImageDescription
Arduino UNO R3Arduino UNO R3
Arduino UNO R4Arduino UNO R4
Arduino UNO R4 WIFIArduino UNO R4 WIFI

Hardware Connection

Connect according to the table below.

Core2021-XFArduino UNO
CLK13
MISO12
MOSI11
CS10
DIO112
RESET3
BUSY9

Example

  • Arduino example programs are located in the core2021-xf\examples\arduino directory of the example package.
  • Examples 01, 02, and 03 require two Core2021-XF modules: one for transmission and one for reception.
ExampleBasic DescriptionDependency Library
01_lr2021_txLR2021 TransmitRadioLib
02_lr2021_rxLR2021 ReceiveRadioLib
03_lr2021_pingpongLR2021 Ping‑PongRadioLib
04_lr2021_tx_cwLR2021 CW Mode TransmitRadioLib
05_lr2021_LoRaWANLoRaWAN (not available on Arduino R3)RadioLib
  • Select the development board:

    ImageDescription
    Arduino UNO R3Arduino UNO R3
    Arduino UNO R4Arduino UNO R4
  • Select the port for the development board, then compile and upload.

  • After the upload is completed, open the serial port monitor, and the relevant information will be output.

01_lr2021_tx

Example Description

  • Based on the Core2021-XF module, implements periodic LoRa packet transmission using interrupts.
  • Uses non‑blocking transmission, does not occupy CPU resources in the main loop.
  • After each packet is sent, automatically delays 1 second before sending the next packet.
  • Supports string data transmission, with a built‑in packet sequence number for easy debugging.

Code Analysis

  • radio.irqDioNum = 11: Configures the LR2021 interrupt mapping pin; must be set before initialization.
  • radio.XTAL = true: Enables the external crystal oscillator to ensure frequency accuracy.
  • setFlag(void): Interrupt callback function triggered automatically after the module finishes transmission, sets a transmission‑complete flag.
  • radio.setPacketSentAction(setFlag): Binds the transmission‑complete interrupt function.
  • radio.startTransmit("content"): Starts asynchronous LoRa transmission (supports string / byte array).
  • radio.finishTransmit(): Cleanup after transmission, turns off the transmit circuit and resets the module state.
  • loop() main logic: Check transmission‑complete flag → print status → delay → send next packet with sequence number.

Operation Result

  • After compiling and uploading, open the serial monitor to see logs indicating transmission completion, as shown below (in combination with 02_lr2021_rx):

02_lr2021_rx

Example Description

  • Based on the Core2021-XF module, implements wireless LoRa packet reception using interrupts.
  • Uses non‑blocking listening mode; the module automatically waits for data without consuming CPU resources.
  • After successful reception, automatically parses the data and prints the packet content, RSSI, and SNR.
  • The same frequency, spreading factor, bandwidth, and coding rate must be configured on both the transmitter and receiver for successful communication.

Code Analysis

  • radio.irqDioNum = 11: Configures the LR2021 interrupt mapping pin; must be set before initialization.
  • radio.XTAL = true: Enables the external crystal oscillator to ensure frequency accuracy and improve reception stability.
  • setFlag(void): Interrupt callback function triggered automatically after a complete packet is received, sets a reception‑complete flag.
  • radio.setPacketReceivedAction(setFlag): Binds the reception‑complete interrupt service function.
  • radio.startReceive(): Starts continuous LoRa reception mode, enters a data‑waiting state.
  • radio.readData(str): Reads the received wireless data (supports string parsing).
  • radio.getRSSI() / radio.getSNR(): Retrieves signal quality parameters for debugging and link evaluation.
  • loop() main logic: Check reception‑complete flag → read data → parse and print → continue listening.

Operation Result

  • After compiling and uploading, open the serial monitor to see real‑time reception logs including data content, RSSI, and SNR, as shown below (in combination with 01_lr2021_tx):

03_lr2021_pingpong

Example Description

  • Based on the Core2021-XF module, implements LoRa automatic ping‑pong (question‑answer) two‑way communication.
  • Two modules can send and receive to each other without manual control.
  • Enabling INITIATING_NODE sets the module as the initiator; the other module acts as the responder.
  • Automatically switches between transmit and receive states, driven by non‑blocking interrupts.

Code Analysis

  • radio.irqDioNum = 11: Configures the LR2021 interrupt mapping pin; must be set before initialization.
  • radio.XTAL = true: Enables the external crystal oscillator to ensure communication frequency accuracy.
  • setFlag(void): General interrupt callback, triggered on either transmit or receive completion.
  • radio.setIrqAction(setFlag): Binds the shared transmit/receive interrupt function.
  • INITIATING_NODE macro: Used to distinguish the initiating node.
  • radio.startTransmit(): Starts packet transmission.
  • radio.startReceive(): Switches the module to listening (receive) mode.
  • radio.readData(str): Reads the received LoRa packet.
  • loop() main logic: Transmit complete → enter receive; receive complete → delay reply → transmit again.

Operation Result

  • Flash the program onto two modules, enabling the INITIATING_NODE macro on one of them.
  • After power‑on, they automatically send and receive to each other; the serial monitor prints the transmit/receive status, data, RSSI, and SNR, as shown below:

04_lr2021_tx_cw

Example Description

  • Based on the Core2021-XF module, implements LoRa continuous wave (CW) / direct transmit.
  • Outputs a fixed‑frequency carrier signal without packet formatting, used for band testing, signal detection, and instrument calibration.
  • Fixed frequency 868 MHz, transmit power 22 dBm.
  • Upon power‑up, transmits continuously with no additional logic.

Code Analysis

  • radio.XTAL = true: Enables the external crystal oscillator to ensure carrier frequency accuracy.
  • OUT_HZ 868000000UL: Defines the direct transmit frequency (868 MHz); can be modified.
  • radio.setOutputPower(22): Sets the transmit power to 22 dBm.
  • radio.transmitDirect(OUT_HZ): Enters continuous direct transmission mode, outputting a fixed‑frequency carrier.
  • loop(): No business logic; the carrier continues to transmit without program intervention.

Operation Result

  • After flashing, the module immediately outputs a fixed‑frequency carrier signal.

  • The serial port prints initialization and transmission start status; a spectrum analyzer or receiving module can detect the continuous RF signal, as shown below:

05_lr2021_LoRaWAN

Example Description

  • Based on the Core2021-XF module + Arduino UNO R4 platform, implements LoRaWAN OTAA join and uplink/downlink communication.
  • Supports OTAA dynamic join, and EEPROM‑based session storage to quickly restore connection after power‑off reboot.
  • Periodically sends uplink data (default every 5 minutes) and listens for server downlink messages.
  • Automatically prints the received data in both HEX and ASCII formats, and supports signal quality monitoring.

Code Analysis

  • radio.irqDioNum = 11: Configures the LR2021 interrupt mapping pin; must be set before initialization.
  • radio.XTAL = true: Enables the external crystal oscillator to ensure LoRaWAN frequency accuracy.
  • EEPROM.begin(): Initializes the on‑chip EEPROM for storing LoRaWAN session information.
  • restoreLoRaWANState(): Restores join session and random values from EEPROM to achieve fast reconnection.
  • node.beginOTAA(): Initializes OTAA join parameters (JoinEUI, DevEUI, AppKey, NwkKey).
  • node.activateOTAA(): Initiates an OTAA join request to the server.
  • saveLoRaWANState(): Saves session information to EEPROM after successful join.
  • node.sendReceive(): Sends uplink data and automatically opens receive windows to listen for downlink messages.
  • printHex / printAscii: Prints the downlink data in hexadecimal and ASCII formats.

Operation Result

  • Refer to the LoRaWAN environment setup document for environment configuration.

  • After flashing, the module automatically performs OTAA join; once joined successfully, it periodically uploads data.

  • The serial port prints join status, uplink/downlink messages, RSSI, SNR, etc., as shown below: