ESP32 LoRa Send & Receive Test (TTGO LoRa32 SX1276 + OLED)

This project shows how to do a simple LoRa “Hello World” send & receive test using two TTGO LoRa32 (SX1276) boards with built-in 0.96″ SSD1306 OLED displays.

We’ll configure one board as a sender, which sends a counter every second, and another board as a receiver, which displays the received message and RSSI (signal strength) on its OLED and on the Serial Monitor.

1. Hardware Required

You’ll need:

  • 2 × TTGO LoRa32 SX1276 boards (with integrated OLED)
  • 2 × Micro-USB cables
  • A computer with Arduino IDE installed

The code below assumes the typical TTGO LoRa32 pinout:

  • LoRa SPI pins
    • SCK → GPIO 5
    • MISO → GPIO 19
    • MOSI → GPIO 27
    • SS (NSS) → GPIO 18
    • RST → GPIO 14
    • DIO0 → GPIO 26
  • OLED pins
    • SDA → GPIO 4
    • SCL → GPIO 15
    • RST → GPIO 16

2. Frequency Band

The sketch uses:

#define BAND 866E6

This is the 866 MHz band (Europe).

If you are in a different region, use the appropriate value:

  • 433E6 – Asia (433 MHz)
  • 866E6 – Europe (866 MHz)
  • 915E6 – North America (915 MHz)

Both sender and receiver must use the same BAND.

3. Arduino IDE Setup

  1. Install ESP32 Board Support
    • In Arduino IDE:
      File → Preferences → Additional Boards Manager URLs:
      Add:
      https://dl.espressif.com/dl/package_esp32_index.json
    • Then: Tools → Board → Boards Manager…
      Search for “esp32” and install “esp32 by Espressif Systems”.
  2. Select the Board
    • Tools → Board → ESP32 Arduino → TTGO LoRa32-OLED V1
      (or similar; choose the appropriate TTGO/ESP32 board if listed.)
  3. Install Required Libraries
    • LoRa by Sandeep Mistry
    • Adafruit GFX Library
    • Adafruit SSD1306
    Install via: Tools → Manage Libraries… and search for each by name.

4. LoRa Sender Sketch

Upload this code to the first TTGO LoRa32 (the sender).
It sends "hello <counter>" once per second and shows the counter on the OLED.

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/ttgo-lora32-sx1276-arduino-ide/
*********/

//Libraries for LoRa
#include <SPI.h>
#include <LoRa.h>

//Libraries for OLED Display
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

//define the pins used by the LoRa transceiver module
#define SCK 5
#define MISO 19
#define MOSI 27
#define SS 18
#define RST 14
#define DIO0 26

//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define BAND 866E6

//OLED pins
#define OLED_SDA 4
#define OLED_SCL 15 
#define OLED_RST 16
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

//packet counter
int counter = 0;

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);

void setup() {
  //initialize Serial Monitor
  Serial.begin(115200);

  //reset OLED display via software
  pinMode(OLED_RST, OUTPUT);
  digitalWrite(OLED_RST, LOW);
  delay(20);
  digitalWrite(OLED_RST, HIGH);

  //initialize OLED
  Wire.begin(OLED_SDA, OLED_SCL);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(2);
  display.setCursor(0,0);
  display.print("LORA SENDER ");
  display.display();
  
  Serial.println("LoRa Sender Test");

  //SPI LoRa pins
  SPI.begin(SCK, MISO, MOSI, SS);
  //setup LoRa transceiver module
  LoRa.setPins(SS, RST, DIO0);
  
  if (!LoRa.begin(BAND)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
  Serial.println("LoRa Initializing OK!");
  display.setCursor(0,10);
  display.print("LoRa Initializing OK!");
  display.display();
  delay(2000);
}

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

  //Send LoRa packet to receiver
  LoRa.beginPacket();
  LoRa.print("hello ");
  LoRa.print(counter);
  LoRa.endPacket();
  
  display.clearDisplay();
  display.setCursor(0,0);
  display.setTextSize(2);
  display.print("Counter: ");
  display.print(counter);      
  display.display();

  counter++;
  
  delay(1000);
}

What this sketch does:

  • Initializes the OLED and prints “LORA SENDER” and “LoRa Initializing OK!”
  • Configures LoRa with the selected band and pins.
  • In the loop():
    • Prints the counter on the Serial Monitor.
    • Sends "hello <counter>" via LoRa.
    • Updates the OLED display showing the current counter value.
    • Increments the counter every second.

5. LoRa Receiver Sketch

Upload this code to the second TTGO LoRa32 (the receiver).
It listens for packets, prints them to Serial, and shows the last message and RSSI on the OLED.

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/ttgo-lora32-sx1276-arduino-ide/
*********/

//Libraries for LoRa
#include <SPI.h>
#include <LoRa.h>

//Libraries for OLED Display
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

//define the pins used by the LoRa transceiver module
#define SCK 5
#define MISO 19
#define MOSI 27
#define SS 18
#define RST 14
#define DIO0 26

//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define BAND 866E6

//OLED pins
#define OLED_SDA 4
#define OLED_SCL 15 
#define OLED_RST 16
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);

String LoRaData;

void setup() { 
  //initialize Serial Monitor
  Serial.begin(115200);
  
  //reset OLED display via software
  pinMode(OLED_RST, OUTPUT);
  digitalWrite(OLED_RST, LOW);
  delay(20);
  digitalWrite(OLED_RST, HIGH);
  
  //initialize OLED
  Wire.begin(OLED_SDA, OLED_SCL);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setTextSize(2);
  display.setCursor(0,0);
  display.display();

  //SPI LoRa pins
  SPI.begin(SCK, MISO, MOSI, SS);
  //setup LoRa transceiver module
  LoRa.setPins(SS, RST, DIO0);

  if (!LoRa.begin(BAND)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
  Serial.println("LoRa Initializing OK!");
  display.setCursor(0,10);
  display.display();  
}

void loop() {

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

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

    //print RSSI of packet
    int rssi = LoRa.packetRssi();
    Serial.print(" with RSSI ");    
    Serial.println(rssi);

    // Display information
    display.clearDisplay();
    display.setCursor(0,0);
    display.setCursor(0,20);
    display.setCursor(0,00);
    display.print(LoRaData);
    display.setCursor(0,40);
    display.print("RSSI: ");
    display.print(rssi);
    display.display();   
  }
}

What this sketch does:

  • Initializes the OLED and LoRa radio exactly as the sender.
  • In the loop():
    • Calls LoRa.parsePacket() to check if a packet was received.
    • If a packet is available:
      • Reads the entire payload into LoRaData.
      • Prints the received string and its RSSI on the Serial Monitor.
      • Displays:
        • The received text (e.g. hello 42) on the OLED.
        • The packet RSSI (e.g. RSSI: -85).

6. Uploading & Testing

  1. Connect the sender board via USB.
    • Select the correct port in Arduino IDE.
    • Upload the sender sketch.
    • Open Serial Monitor at 115200 baud to watch sent packets.
  2. Connect the receiver board via USB.
    • Select its port.
    • Upload the receiver sketch.
    • Open another Serial Monitor at 115200 baud (or use two IDE windows).
  3. Place the two boards a few meters apart (or more) and power them both.

You should see:

  • Sender Serial Monitor:
    Sending packet: 0
    Sending packet: 1
    Sending packet: 2
  • Receiver Serial Monitor:
    Received packet hello 0 with RSSI -45
    Received packet hello 1 with RSSI -46
    Received packet hello 2 with RSSI -47
  • Receiver OLED:
    Top line: hello <counter>
    Bottom line: RSSI: <value>

If nothing appears on the receiver:

  1. Check Frequency Band
    • Both sketches must use the same BAND (866E6 in this example).
  2. Check Board Selection & Port
    • Verify correct board and COM port are selected for each TTGO.
  3. Antenna
    • Make sure each TTGO has its LoRa antenna connected.
    • Never transmit LoRa without an antenna, you can damage the RF stage.
  4. Libraries & Versions
    • Confirm LoRa, Adafruit GFX, and Adafruit SSD1306 are installed and up to date.
    • If the OLED shows nothing, double-check I²C address (0x3C) and pins.
  5. Serial Monitor Baud Rate
    • Must be set to 115200 to match Serial.begin(115200);.

8. Next Steps

Once your basic LoRa send/receive test works, you can extend this setup to:

  • Send sensor data (temperature, humidity, etc.) instead of a simple counter.
  • Add a node ID in the payload and build a small multi-node LoRa network.
  • Integrate with ESP32 deep sleep to build low-power battery-powered nodes.
  • Forward data from the receiver to MQTT / Home Assistant / InfluxDB.
Share your love

Newsletter Updates

Enter your email address below and subscribe to our newsletter

Leave a Reply

Your email address will not be published. Required fields are marked *