TTGO LoRa32 SX1276 OLED Board: Getting Started with Arduino IDE

The TTGO LoRa32 SX1276 OLED is an ESP32 development board with a built-in LoRa chip and an SSD1306 0.96 inch OLED display. In this guide, we’ll show you how to: send and receive LoRa packets (point to point communication) and use the OLED display with Arduino IDE.

TTGO LoRa32 OLED SX1276 Board: Getting Started with Arduino IDE

For an introduction to LoRa communication, read: ESP32 with LoRa using Arduino IDE.

TTGO LoRa32 SX1276 OLED Overview

The TTGO LoRa32 SX1276 OLED is a development board with an ESP32, a built-in LoRa chip and an SSD1306 OLED display. This is the OLED model display we use in most of our electronics projects (Guide for OLED display with ESP32).

 TTGO LoRa32 OLED SX1276 Overview

The board also features several GPIOs to connect peripherals, PRG (BOOT) and RST buttons, and a lithium battery connector. For a more in-depth overview of this board, read: TTGO LoRa32 SX1276 OLED Review.

Where to buy?

You can go to the TTGO LoRa32 SX1276 OLED page on Maker Advisor to find the best price at different stores. To complete this tutorial, you’ll need two TTGO LoRa32 boards.

TTGO LoRa32 OLED SX1276

TTGO LoRa32 SX1276 OLED

The following figure shows the TTGO LoRa32 OLED board pinout.

 TTGO LoRa32 OLED SX1276 Pinout Diagram

The OLED displays communicates using I2C communication protocol. It is internally connected to the ESP32 on the following pins:

OLED (built-in)ESP32
SDAGPIO 4
SCLGPIO 15
RSTGPIO 16

The SX1276 LoRa chip communicates via SPI communication protocol, and it is internally connected to the ESP32 on the following GPIOs:

SX1276 LoRaESP32
MISOGPIO 19
MOSIGPIO 27
SCKGPIO 5
CSGPIO 18
IRQGPIO 26
RSTGPIO 14

Recommended reading: ESP32 Pinout Reference Guide

Install ESP32 Boards on Arduino IDE

To program the TTGO LoRa32 board, we’ll use Arduino IDE. So, you must have Arduino IDE installed as well as the ESP32 add-on. Follow the next guide to install the ESP32 package on Arduino IDE, if you haven’t already:

Installing OLED Libraries

There are several libraries available to control the OLED display with the ESP32. In this tutorial we’ll use two Adafruit libraries: Adafruit_SSD1306 library and Adafruit_GFX library.

Follow the next steps to install those libraries.

1. Open your Arduino IDE and go to Sketch > Include Library > Manage Libraries. The Library Manager should open.

2. Type “SSD1306” in the search box and install the SSD1306 library from Adafruit.

Installing the Adafruit SSD1306 library for OLED display Arduino IDE

3. After installing the SSD1306 library from Adafruit, type “GFX” in the search box and install the library.

Installing GFX Library for ESP32 Arduino IDE

Installing LoRa Library

There are several libraries available to easily send and receive LoRa packets with the ESP32. In this example we’ll be using the arduino-LoRa library by sandeep mistry.

Open your Arduino IDE, and go to Sketch > Include Library > Manage Libraries and search for “LoRa“. Select the LoRa library highlighted in the figure below, and install it.

Installing LoRa Library for ESP32 Arduino IDE

After installing the libraries, restart your Arduino IDE.

LoRa Sender Sketch

Copy the following code to your Arduino IDE. This code sends a “hello” message followed by a counter via LoRa every 10 seconds. It also displays the counter on the OLED display.

/*********
  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() {

  //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(1);
  display.setCursor(0,0);
  display.print("LORA SENDER ");
  display.display();
  
  //initialize Serial Monitor
  Serial.begin(115200);
  
  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.println("LORA SENDER");
  display.setCursor(0,20);
  display.setTextSize(1);
  display.print("LoRa packet sent.");
  display.setCursor(0,30);
  display.print("Counter:");
  display.setCursor(50,30);
  display.print(counter);      
  display.display();

  counter++;
  
  delay(10000);
}

View raw code

How the code works

Start by including the libraries to interact with the LoRa chip.

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

Then, include the libraries to interface with the I2C 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

Select the LoRa frequency:

#define BAND 866E6

Define the OLED pins.

#define OLED_SDA 4
#define OLED_SCL 15 
#define OLED_RST 16

Define the OLED size.

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Create a counter variable to keep track of the number of LoRa packets sent.

int counter = 0;

Create an Adafruit_SSD1306 object called display.

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

setup()

In the setup(), to start using the OLED you need to do a manual reset via software using the RST pin. To do this reset, you need to declare the RST pin as an output, set it to LOW for a few milliseconds and then, set it to HIGH again.

pinMode(OLED_RST, OUTPUT);
digitalWrite(OLED_RST, LOW);
delay(20);
digitalWrite(OLED_RST, HIGH);

Start an I2C communication using the defined OLED_SDA and OLED_SCL pins using Wire.begin().

Wire.begin(OLED_SDA, OLED_SCL);

After that, initialize the display with the following parameters. The parameters set as false ensure that the library doesn’t use the default I2C pins and use the pins defined in the code (GPIO 4 and GPIO 15).

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32
  Serial.println(F("SSD1306 allocation failed"));
  for(;;); // Don't proceed, loop forever
}

Then, you can use the methods from the Adafruit library to interact with the OLED display. To learn more you can read our tutorial about the I2C OLED display with the ESP32.

Write the message “LORA SENDER” to the display.

display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0,0);
display.print("LORA SENDER ");
display.display();

Initialize the serial monitor for debugging purposes.

Serial.begin(115200);
Serial.println("LoRa Sender Test");

Define the SPI pins used by the LoRa chip.

SPI.begin(SCK, MISO, MOSI, SS);

And set up the LoRa transceiver module.

LoRa.setPins(SS, RST, DIO0);

Finally, initialize the LoRa transceiver module using the begin() method on the LoRa object and pass the frequency as argument.

if (!LoRa.begin(BAND)) {
  Serial.println("Starting LoRa failed!");
  while (1);
}

If we succeed in initializing the display, we write a success message on the OLED display.

display.setCursor(0,10);
display.print("LoRa Initializing OK!");
display.display();

loop()

In the loop() is where we’ll send the packets. You initialize a packet with the beginPacket() method.

LoRa.beginPacket();

You write data into the packet using the print() method. As you can see in the following two lines, we’re sending a hello message followed by the counter.

LoRa.print("hello ");
LoRa.print(counter);

Then, close the packet with the endPacket() method.

LoRa.endPacket();

Next, write the counter on the OLED display

display.clearDisplay();
display.setCursor(0,0);
display.println("LORA SENDER");
display.setCursor(0,20);
display.setTextSize(1);
display.print("LoRa packet sent.");
display.setCursor(0,30);
display.print("Counter:");
display.setCursor(50,30);
display.print(counter);
display.display();

After this, the counter message is incremented by one in every loop, which happens every 10 seconds.

counter++;
delay(10000);

Testing the LoRa Sender

Upload the code to your board. You need to select the right board and COM port you’re using.

To select the board, in the Arduino IDE, go to Tools > Board and select the TTGO LoRa32-OLED V1 board.

Select TTGO LoRa32 OLED V1 in Arduino IDE

After uploading the code to your board, it should start sending LoRa packets.

TTGO LoRa ESP32 Dev Board Sender

LoRa Receiver Sketch

Now, upload the receiver sketch to another TTGO LoRa32 OLED board. This sketch listens for LoRa packets within its range and prints the content of the packets on the OLED, as well as the RSSI (relative received signal strength).

/*********
  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() { 
  
  //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(1);
  display.setCursor(0,0);
  display.print("LORA RECEIVER ");
  display.display();
  
  //initialize Serial Monitor
  Serial.begin(115200);

  Serial.println("LoRa Receiver 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.println("LoRa Initializing OK!");
  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);

   // Dsiplay information
   display.clearDisplay();
   display.setCursor(0,0);
   display.print("LORA RECEIVER");
   display.setCursor(0,20);
   display.print("Received packet:");
   display.setCursor(0,30);
   display.print(LoRaData);
   display.setCursor(0,40);
   display.print("RSSI:");
   display.setCursor(30,40);
   display.print(rssi);
   display.display();   
  }
}

View raw code

This sketch is very similar with the previous one. We just need to modify some lines to receive LoRa packets instead of sending.

In the loop(), we check if there are new packets to receive using the parsePacket() method.

int packetSize = LoRa.parsePacket();

If there’s a new packet, we’ll read its content. To read the incoming data, use the readString() method. The data received is saved on the LoRaData variable.

if (packetSize) {
  //received a packet
  Serial.print("Received packet ");

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

We also get the RSSI of the received packet by using the packetRSSI() method.

int rssi = LoRa.packetRssi();

Finally, display the received message, as well as the RSSI.

display.clearDisplay();
display.setCursor(0,0);
display.print("LORA RECEIVER");
display.setCursor(0,20);
display.print("Received packet:");
display.setCursor(0,30);
display.print(LoRaData);
display.setCursor(0,40);
display.print("RSSI:");
display.setCursor(30,40);
display.print(rssi);
display.display();

Testing the LoRa Receiver

Upload the code to your board. Don’t forget you need to select the TTGO LoRa32-OLED V1 in the Boards menu.

After uploading the code, it should start receiving the LoRa packets from the other board.

TTGO LoRa ESP32 Dev Board Receiver

Wrapping Up

This article was a quick getting started guide for the TTGO LoRa32 board how to: send LoRa packets in point to point communication and use the OLED display.

Now, the idea is to combine what you’ve learned here to build IoT projects. LoRa can be specially useful if you want to receive sensor readings that are not covered by your wi-fi network and are several meters apart. Additionally, you can also connect your board to the TTN (The Things Network).

We hope you’ve found this tutorial useful. Learn more about the ESP32 with our resources:

Thanks for reading.


Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »

Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »


Enjoyed this project? Stay updated by subscribing our weekly newsletter!

9 thoughts on “TTGO LoRa32 SX1276 OLED Board: Getting Started with Arduino IDE”

  1. How i can transfer from this board using UART the data to a pic18.
    I would like to have a Pic18 + Lora+ ESP and be able to send 30 bytes to a second Pic18, or receive from other PIC18 a group of 30 bytes.

  2. The TTGO series of boards are great, they have loads of really odd ones too, like esp32 + a camera, or SIM card, or GPS, or DHT sensor, just about any project you want, there is a TTGO board for it.
    Only thing I’ve found is the range of the TTGO LoRa is pretty poor, I’m only getting a couple 100m in clear open countryside, rather than the 1000s of m it should really be.

  3. Hello Rui and Sara.
    I can send and receive text via Lora.
    But I would like to send an analog value and an on / or switch command to a receiver. I have not yet succeeded. Have you already done something with it? It seems very nice to be able to read something from a greater distance and to switch than just to transfer text.
    I just have no idea how to handle that and I need a hint. The Text distance that I have already covered here is not that great yet. About 1000 Meters, but that is also sufficient for me.
    Greetings from bert from (cold) Netherlands.

    • Hi Bert.
      You just need to send your sensor readings as a String.
      For example, the following snipet sends several sensor readings on the same message. Note that each reading is separated by a special character. This way, on the receiver side, you know how to split the message.

      void sendReadings() {
      // Send packet data
      // Send temperature in Celsius
      message = String(readingID) + “/” + String(tempC) + “&” +
      String(soilMoisture) + “#” + String(batteryLevel);
      // Uncomment to send temperature in Fahrenheit
      //message = String(readingID) + “/” + String(tempF) + “&” +
      // String(soilMoisture) + “#” + String(batteryLevel);
      delay(1000);
      LoRa.beginPacket();
      LoRa.print(message);
      LoRa.endPacket();
      }

      This works the same way if you want to sendo commands to turn something on or off.
      On the receiver side, we use the following to read and split the data:

      void getLoRaData() {
      Serial.print(“Lora packet received: “);
      // Read packet
      while (LoRa.available()) {
      String LoRaData = LoRa.readString();
      // LoRaData format: readingID/temperature&soilMoisture#batterylevel
      // String example: 1/27.43&654#95.34
      Serial.print(LoRaData);

      // Get readingID, temperature and soil moisture
      int pos1 = LoRaData.indexOf(‘/’);
      int pos2 = LoRaData.indexOf(‘&’);
      int pos3 = LoRaData.indexOf(‘#’);
      readingID = LoRaData.substring(0, pos1);
      temperature = LoRaData.substring(pos1 +1, pos2);
      soilMoisture = LoRaData.substring(pos2+1, pos3);
      batteryLevel = LoRaData.substring(pos3+1, LoRaData.length());
      }

      Now, feel free to modify these functions to use in your project.
      REgards,
      Sara

  4. Hi
    I have used these boards to control my outdoor light etc.
    i have connected them with solar cells and 18650 battery with charger module as instructed in Learn ESP32 for Arduino.

    everything has been working perfectly for a month until the battery runs out of power.
    after that I cannot contact the board over USB

    the first time it happened I thought it was a bad board
    but today it happened again with two boards running out of power
    no sun in DanmarK 🙁

    it may be a problem that they get power through the lithium battery. Connecting even if they write is ok?

    Regards
    Aage

Leave a Comment

Download our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.