esp32.diy

ESP32 LoRa Example: Send & Receive Messages Step-by-Step

Oct 14, 2026 · 6 min read · Beginner

ESP32 LoRa Example: Send & Receive Messages Step-by-Step
TL;DR Flash the Heltec sender sketch to one ESP32 LoRa board and the receiver sketch to a second, then open the serial monitor at 115200 baud to see numbered packets arrive with RSSI readings. The most common failure is a baud rate mismatch between the sketch and the serial monitor — the IDE defaults to 9600 while the Heltec library runs at 115200.
Boards neededTwo ESP32 LoRa modules (e.g. Heltec WiFi LoRa series)
Frequency bands868 MHz (EU) or 915 MHz (US/Americas) — both boards must match
Serial baud rate115200 baud
Max TX power via PABOOST20 dBm
Max TX power via RFO14 dBm
Required libraryheltec.h (Heltec Arduino library)

What do you need before you start?

You need two ESP32 LoRa boards. The Heltec WiFi LoRa series — which combines an ESP32 microcontroller, a LoRa radio, and an OLED display on one module — is a practical starting point because the official library ships with complete sender and receiver sketches. Attach an antenna to each board before applying power; running a LoRa radio without an antenna risks damaging the RF stage.

On the software side, collect the following:

Before writing a single line of code, decide on your frequency band. The example sketches define BAND as either 868E6 for Europe or 915E6 for North America and most of the Americas. Both boards in your pair must use the identical value — mismatched bands produce silence on the receiver.

A LoRa module with antenna and SPI wiring attached — ESP32 communicates with the LoRa radio chip over this same SPI interface.\2

A LoRa module with antenna and SPI wiring attached — ESP32 communicates with the LoRa radio chip over this same SPI interface. Image: The original uploader was Cnd at English Wikipedia ., CC0, via Wikimedia Commons

How does the ESP32 LoRa sender and receiver pattern work?

LoRa communication on ESP32 follows a straightforward packet model. The sending board opens a packet with LoRa.beginPacket(), writes payload data using LoRa.print(), and commits the transmission with LoRa.endPacket(). The receiving board runs a tight loop calling LoRa.parsePacket() on every iteration; when that function returns a non-zero byte count, a complete packet has arrived and is ready to drain.

The Heltec library manages all the low-level SPI traffic between the ESP32 and the LoRa radio chip. On Heltec boards, both the LoRa radio and the OLED display share the SPI bus, so Heltec.begin() initialises all three subsystems — display, radio, and serial port — in one call with four boolean parameters controlling each.

After reading a packet, LoRa.packetRssi() returns the received signal strength in dBm. A less-negative number means a stronger, cleaner link — useful for diagnosing range problems or evaluating antenna placement in a real ESP32 LoRa project.

The Ra-02 LoRa module, a common SPI-based radio module used in ESP32 LoRa projects.\2

The Ra-02 LoRa module, a common SPI-based radio module used in ESP32 LoRa projects. Image: VamosSandor, CC BY-SA 4.0, via Wikimedia Commons

Step-by-step: upload the sender sketch

  1. Open the Arduino IDE and select your Heltec ESP32 LoRa board from the board manager.
  2. Create a new sketch and paste the code below.
  3. Change BAND to 868E6 or 915E6 to match your region.
  4. Compile and upload to the first board.
#include "heltec.h"
#define BAND 915E6

int counter = 0;

void setup() {
  Heltec.begin(true /*Display*/, true /*LoRa*/, true /*Serial*/, true /*PABOOST*/, BAND);
}

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

  LoRa.beginPacket();
  LoRa.setTxPower(14, RF_PACONFIG_PASELECT_PABOOST);
  LoRa.print("hello ");
  LoRa.print(counter);
  LoRa.endPacket();

  counter++;
  digitalWrite(25, HIGH);
  delay(1000);
  digitalWrite(25, LOW);
  delay(1000);
}

The four true arguments to Heltec.begin() enable the OLED display, the LoRa radio, the serial port, and the PA boost output in that order. LoRa.setTxPower(14, RF_PACONFIG_PASELECT_PABOOST) sets transmit power to 14 dBm through the PABOOST output pin; the same pin can go up to 20 dBm. The alternative RFO_HF / RFO_LF output path tops out at 14 dBm. The LED on pin 25 blinks once per second to confirm the loop is running.

LILYGO T-Beam T22 v1.1 — an ESP32 LoRa board that integrates ESP32, a LoRa radio, and GPS on a single module, popular for tracking and mesh-networking projects.\2

LILYGO T-Beam T22 v1.1 — an ESP32 LoRa board that integrates ESP32, a LoRa radio, and GPS on a single module, popular for tracking and mesh-networking projects. Image: Valanagut, CC0, via Wikimedia Commons

Step-by-step: upload the receiver sketch

  1. Connect the second Heltec ESP32 LoRa board to a different USB port.
  2. In the Arduino IDE, switch to that board's port.
  3. Create a new sketch and paste the code below.
  4. Use the same BAND value as the sender — a mismatch means the receiver never sees a packet.
  5. Compile and upload.
#include "heltec.h"
#define BAND 915E6

void setup() {
  Heltec.begin(true, true, true, true, BAND);
}

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

LoRa.parsePacket() returns zero when nothing has arrived and the byte count of the waiting payload when a packet is ready. LoRa.available() and LoRa.read() drain the packet byte by byte; casting each byte to char and printing it rebuilds the text string on screen. If you need to run arithmetic on the received number rather than just display it, read all the bytes into a String object first, then call .toInt() or .toFloat() on that string to get a usable numeric type.

How do you verify the ESP32 LoRa link is working?

Open the serial monitor for the receiver board and set the baud rate selector at the bottom of the monitor window to 115200. Within a second or two of the sender powering up, you should see output like:

Received packet 'hello 0' with RSSI -45
Received packet 'hello 1' with RSSI -46
Received packet 'hello 2' with RSSI -44

On the sender board's monitor you should see Sending packet: 0, Sending packet: 1, and so on, with the pin-25 LED blinking between each transmission.

If you see garbled output such as ⸮⸮3⸮⸮JS⸮⸮⸮⸮⸮J)⸮⸮ on either monitor, the baud rate selector is set to the IDE's default of 9600 instead of 115200. Changing that one dropdown clears the problem immediately — no re-upload required. If both monitors look fine but no packets appear on the receiver, double-check that both sketches use the same BAND constant.

What mistakes do people commonly make with ESP32 LoRa?

Mistake Symptom Fix
Serial monitor left at IDE default of 9600 baud Random characters instead of readable text Change the baud rate dropdown to 115200
Sender and receiver set to different frequency bands Receiver never logs any packets Make both sketches use identical BAND values
Reading raw bytes but expecting a typed numeric value Logic that compares or calculates with the payload fails Buffer all bytes into a String, then use .toInt() or .toFloat()
Powering on without an antenna attached Very short range or no signal at all Always attach the correct antenna before applying power
Adding a third SPI device to a Heltec board carelessly Conflicts with LoRa radio or OLED display The Heltec board already uses SPI for both the LoRa chip and the OLED; a third SPI device needs careful free-pin selection and may require software bit-banging rather than hardware SPI

The baud rate issue is by far the most reported stumbling block for people running this example for the first time. The Arduino IDE serial monitor defaults to 9600 baud across all projects, but Heltec.begin() opens serial at 115200, so every character arrives as noise until the mismatch is corrected.

What ESP32 LoRa projects can you build once the basics work?

With a verified sender-receiver link, the payload string is yours to replace. Swap the incrementing counter for a temperature reading, a humidity value, or a GPS coordinate string, and the receiver side becomes a data logger or a dashboard feed. Because LoRa packet payloads are arbitrary bytes, almost any sensor reading that fits in a short string can travel over the link.

Beyond simple point-to-point data, ESP32 LoRa boards are the foundation for mesh networking and asset-tracking builds. LILYGO T-Beam boards — which put ESP32, a LoRa radio, and a GPS module on a single PCB — are widely used in tracking and off-grid communication projects. Meshtastic, an open-source mesh networking firmware, runs on T-Beam hardware and turns a group of ESP32 LoRa boards into a long-range, infrastructure-free messaging network. Both the hardware and the firmware pattern grow naturally from the sender/receiver example you just wired up.

Frequently asked questions

What baud rate should the serial monitor use with Heltec ESP32 LoRa sketches?

Set the serial monitor to 115200 baud. The Heltec.begin() call initialises serial at 115200, and the IDE's default of 9600 turns every character into garbled output. Change the baud selector in the monitor window — no re-upload is needed.

Can two LoRa boards on different frequencies communicate?

No. Both sender and receiver must use the same frequency band — 868E6 for Europe or 915E6 for North America. A mismatch produces complete silence on the receiver with no error message.

How do I read a LoRa packet as a number rather than raw characters?

Read all available bytes into a String object, then call .toInt() or .toFloat() on that String. Casting raw bytes directly to int gives incorrect results because each byte represents a single ASCII character, not a digit value.

Can I connect a third SPI device to the Heltec ESP32 LoRa board?

It is possible but complicated. The Heltec board already uses its SPI bus for both the LoRa radio and the OLED display, leaving few free SPI-capable pins. Adding a third device may require software bit-banging rather than hardware SPI, and pin conflicts are common.

What does LoRa.packetRssi() tell me?

It returns the received signal strength of the last packet in dBm. A less-negative value means a stronger link. Use it to assess link quality, antenna placement, or the effective range of your ESP32 LoRa module.

Bottom line

The Heltec ESP32 LoRa sender and receiver example is the fastest path to a working LoRa link — upload two sketches, open the serial monitor at 115200 baud, and packets appear within seconds. Both the frequency band and the baud rate must match exactly between the two boards, and those are the only two settings that trip up most beginners. Once that foundation is solid, the same code pattern scales directly into sensor telemetry, GPS tracking, and mesh networking projects.

Sources

stackoverflow.comHow to read LoRa Messages in Serial monitor via heltec esp32stackoverflow.comESP32 Heltec wifi LoRa, Waveshare e-Paper 4.2", how to connect via SPI and how to display something on the display (which library to use)?

This guide summarises the public sources listed above in our own words. Check the original documentation before relying on exact figures.