Interfacing LoRa with Raspberry Pi Pico

LoRa is a low-power long-range wireless communication protocol. It is very effective in remote areas where WiFi, LAN, and cellular networks are not available. Using LoRa you can receive data up to 10 km. In this tutorial, we will learn how we can interface LoRa with Raspberry Pi Pico, also build a small project using Raspberry Pi Pico, Arduino Uno, and LoRa sx1278 module.

What is LoRa?

LoRa (short for Long Range) is a wireless communication technology designed for long-range communication with low power consumption. It’s often used in Internet of Things (IoT) applications where devices need to communicate over long distances while consuming minimal power.

LoRa operates in unlicensed radio frequency bands, allowing for easy deployment without needing regulatory approval in most regions. It uses spread spectrum modulation techniques to achieve long-range communication and can penetrate obstacles like buildings and vegetation more effectively than traditional wireless technologies like Wi-Fi or Bluetooth.

LoRaWAN (LoRa Wide Area Network) is a protocol built on top of LoRa technology, providing features like secure communication, power management, and support for large-scale networks.

LoRa works with different frequency bands in different regions.

Europe868 MHz
North America915 MHz
Asia433 MHz

If you are interested in learning more about LoRa then read this article below:

Interfacing LoRa with Raspberry Pi Pico: The Project

In this project, the Raspberry Pi Pico acts as a sender node and Arduino Uno as a receiver node. We send a message from Raspberry Pi Pico and the Arduino Uno receives this message using LoRa communication. Both the sender (Raspberry Pi Pico) and receiver (Arduino Uno) microcontroller will communicate with LoRa using the SPI communication method. For this project, the code will written in Arduino IDE.

Interfacing between LoRa and Raspberry Pi Pico

Components list

Component NameQuantityPurchase Link
Respberry Pi Pico or Pico W1Amazon | AliExpress
LoRa Module2Amazon | AliExpress
Arduino Uno1Amazon | AliExpress
Breadboard2Amazon | AliExpress
Jumper Wire Pack1Amazon | AliExpress
Micro USB Cable1Amazon | AliExpress

LoRa Sender Circuit

LoRa Sender Circuit

LoRa Receiver  Circuit

LoRa Receiver  Circuit

Preparing Arduino IDE for the project

Installing Raspberry Pi Pico Board Manager

Open your Arduino IDE and go to Tools>>Board>>Board manager search for Pico and press enter then install this board manager for Raspberry Pi Pico or Pico W.

Installing Raspberry Pi Pico Board Manager in Arduino IDE

Installing Library

To install LoRa library open your Arduino IDE and go to tools>>manage libraries. In the search box search for Lora and install this library.

Installing LoRa Library for Arduino IDE

Raspberry Pi Pico SPI Scan

Using the SPI scan code you can easily find the SPI pins of your Raspberry Pi Pico or Pico W. This method saves you time. Open your Arduino IDE create a new sketch copy and paste this code and upload it to your Raspberry Pi Pico.

void setup() {
      Serial.begin(115200);
    }
    
    void loop() {
      Serial.print("MOSI: ");
      Serial.println(MOSI);
      Serial.print("MISO: ");
      Serial.println(MISO);
      Serial.print(" SCK: ");
      Serial.println(SCK);
      Serial.print("  SS: ");
      Serial.println(SS);
      Serial.println();
      delay(5000);
    }

Then, you can see the SPI pins of your Raspberry Pi Pico in the serial monitor of Arduino IDE. You may have different pins. In this case, your connection between Pico and LoRa module will be different which means according to SPI protocol.

SPI Pins of Raspberry Pi Pico / Pico WLoRa Module SPI Pins
MOSIMOSI
MISOMISO
SCKSCK
SSSS
Raspberry Pi Pico SPI Scan result
Raspberry Pi Pico SPI Scan result

LoRa Sender Code

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

//define the pins used by the sender module
#define ss 17
#define rst 27
#define dio0 28

int counter = 0;

void setup() {
  //initialize Serial Monitor
  Serial.begin(115200);
  while (!Serial);
  Serial.println("LoRa Sender");

  //setup LoRa sender module
  LoRa.setPins(ss, rst, dio0);
  
  //replace the LoRa.begin(---E-) argument with your location's frequency 
  //433E6 for Asia
  //866E6 for Europe
  //915E6 for North America
  while (!LoRa.begin(433E6)) {
    Serial.println(".");
    delay(500);
  }
   // Change sync word (0xF3) to match the receiver
  // The sync word assures you don't get LoRa messages from other LoRa transceivers
  // ranges from 0-0xFF
  LoRa.setSyncWord(0xF3);
  Serial.println("LoRa Initializing OK!");
}

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

  //Send LoRa packet to receiver
  LoRa.beginPacket();
  LoRa.print("EmbeddedThere ");
LoRa.print(counter);
  LoRa.endPacket();

  counter++;

  delay(10000);
}

Code Explanation

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

In these two lines of code, we include two important libraries: SPI.h for Serial Peripheral Interface communication and LoRa.h for LoRa communication. These libraries provide functions and definitions necessary for interacting with the LoRa transceiver module.

#define ss 17
#define rst 27
#define dio0 28

ss (Slave Select): The pin used for chip select in SPI communication.

rst (Reset): The reset pin for the LoRa module.

dio0 (Digital Input/Output 0): This pin is used for interrupt notifications from the LoRa module.

int counter = 0;

This line declares a global variable counter and initializes it to 0. This variable will be used to keep track of the number of packets sent.

void setup() {
    Serial.begin(115200);
    while (!Serial);
    Serial.println("LoRa Sender");
    LoRa.setPins(ss, rst, dio0);
    while (!LoRa.begin(433E6)) {
        Serial.println(".");
        delay(500);
    }
    LoRa.setSyncWord(0xF3);
    Serial.println("LoRa Initializing OK!");
}

In the setup() function, We initialize serial communication with the Serial Monitor at a baud rate of 115200. We set up the LoRa module by specifying the pins defined earlier and attempting to begin communication with it at a frequency of 433 MHz for Asia. Then, set the sync word to 0xF3 to ensure proper communication between the sender and receiver this must be the same for the receiver also. Finally, we print “LoRa Initializing OK!” to the Serial Monitor.

void loop() {
    Serial.print("Sending packet: ");
    Serial.println(counter);
    LoRa.beginPacket();
    LoRa.print("EmbeddedThere ");
    LoRa.print(counter);
    LoRa.endPacket();
    counter++;
    delay(10000);
}

In the loop() function, We continuously send LoRa packets. Print the current packet number to the Serial Monitor. We begin a LoRa packet, write data (“EmbeddedThere” followed by the packet counter) to the packet, and end the packet. Incrementing the counter variable to keep track of packets sent. Set a 10-second delay before sending the next packet.

LoRa Receiver Code

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

//define the pins used by the transceiver module
#define ss 10
#define rst 9
#define dio0 2

void setup() {
  //initialize Serial Monitor
  Serial.begin(9600);
  while (!Serial);
  Serial.println("LoRa Receiver");

  //setup LoRa transceiver module
  LoRa.setPins(ss, rst, dio0);
  
  //replace the LoRa.begin(---E-) argument with your location's frequency 
  //433E6 for Asia
  //866E6 for Europe
  //915E6 for North America
  while (!LoRa.begin(433E6)) {
    Serial.println(".");
    delay(500);
  }
   // Change sync word (0xF3) to match the receiver
  // The sync word assures you don't get LoRa messages from other LoRa transceivers
  // ranges from 0-0xFF
  LoRa.setSyncWord(0xF3);
  Serial.println("LoRa Initializing OK!");
}

void loop() {
  // try to parse packet
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    // received a packet
    Serial.print("Received packet '");

    // read packet
    while (LoRa.available()) {
      String LoRaData = LoRa.readString();
      Serial.print(LoRaData); 
    }

    // print RSSI of packet
    Serial.print("' with RSSI ");
    Serial.println(LoRa.packetRssi());
  }
}

Code Explanation

Before the setup function the first few lines are almost the same as the receiver except pin numbers. So, we can skip these lines.

void setup() {
    Serial.begin(9600);
    while (!Serial);
    Serial.println("LoRa Receiver");

    LoRa.setPins(ss, rst, dio0);

    while (!LoRa.begin(433E6)) {
        Serial.println(".");
        delay(500);
    }
    LoRa.setSyncWord(0xF3);
    Serial.println("LoRa Initializing OK!");
}

In the setup() function, Serial communication is initialized with the baud rate set to 9600. We wait for the Serial Monitor to open and then print “LoRa Receiver”. Similar to the sender code, we set the sync word to 0xF3 to ensure proper communication between the sender and receiver. All other lines are the same as the sender code.

void loop() {
    int packetSize = LoRa.parsePacket();
    if (packetSize) {
        Serial.print("Received packet '");
        while (LoRa.available()) {
            String LoRaData = LoRa.readString();
            Serial.print(LoRaData); 
        }
        Serial.print("' with RSSI ");
        Serial.println(LoRa.packetRssi());
    }
}

In the loop() function, We attempt to parse a LoRa packet using LoRa.parsePacket().

If a packet is received (packetSize is non-zero), we print “Received packet ‘” to the Serial Monitor.

While data is available from the LoRa module, we read the packet data as a string and print it to the Serial Monitor in my case it was “EmbeddedThere”. We also print the Received Signal Strength Indication (RSSI) of the packet using LoRa.packetRssi() function. LoRa operates RSSI between -30dBm to -150dBm. -30dBm means a very strong signal.

Uploading The Code

Copy and paste the sender code then save the file and hit the upload button to upload the code in your Raspberry Pi Pico or Pico W. If you are new in Arduino IDE and Pico then follow this article.

Also, For the receiver code copy and paste the receiver code and go to Tools>>Board>>Arduino AVR board>>select Arduino Uno. After again go to Tools>>port>>select the right Port(COM1, COM2, COM4,COM5..and so on). And hit the upload button to upload the code to your Arduino Uno.

The Result

On the serial monitor, you will see this message(receiver serial terminal).

Result on serial terminal

Rana Bhuiyan

I hold a B.Sc degree in Electrical & Electronic Engineering from Daffodil International University, Bangladesh. I am an Electronic circuit designer and Microcontroller programmer. I am interested in Robotics, Embedded System Design and IoT.

Recent Posts