ESP Lora 32

By Ryan McDermott

TTGO Lora ESP32.

ESP32 with LoRa, wifi, BLE, and an OLED screen

This post is a work in progress

Available here for about $10

These appear to be clones or at least surface-compatible with the Heltc WiFi Lora 32. I found a good article about them here

Arduino IDE

Treat them as such in the arduino IDE.

To get support for the ESP32 in arduino, follow espressif’s directions here

You will also need several folders from this zip file:

Copy “LoRa” and “OLED” from the libraries folder inside of this zip to your own libraries folder.

(WiP. This will be obvious if you are very comfortable in arduino already, but if you are relatively new to that environment, it may be confusing. Email me blhack@gmail.com if you are reading this guide and need help)

Lora is one of the technologies that I am most excited about. It’s like bluetooth low energy (in regards to its power consumption), but it claims a range of 20km (LoS).

I’m also a big fan of cheap boards from china, and this one is pretty cheap!

It’s got wifi, bluetooth low energy, AND lora, AND a screen, all on a board with a JST connector for a battery AND a touchscreen (supposedly) for $10.

This is basically the holy grail (as far as I am concerned) for IoT devices. Cheap, lots of protocols, small, low power consumption…

I’m taking some notes here about getting it running because it seems non-obvious.

Here is some example code for Arduino:

Sender

 #include <SPI.h>
 #include <LoRa.h>
 #include<Arduino.h>
 #include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier
 #include "SSD1306.h" // alias for `#include "SSD1306Wire.h"`
 #include <WiFi.h>

 // GPIO5  -- SX1278's SCK
 // GPIO19 -- SX1278's MISO
 // GPIO27 -- SX1278's MOSI
 // GPIO18 -- SX1278's CS
 // GPIO14 -- SX1278's RESET
 // GPIO26 -- SX1278's IRQ(Interrupt Request)

 #define SS      18
 #define RST     14
 #define DI0     26
 #define BAND    433E6  //915E6 -- 这里的模式选择中,检查一下是否可在中国实用915这个频段

 SSD1306  display(0x3c, 4, 15);

 byte mac[6];
 String macString = "";

 int counter = 0;

 void writeOled(String message) {
   display.clear();
   display.setTextAlignment(TEXT_ALIGN_LEFT);
   display.setFont(ArialMT_Plain_10);
   display.drawStringMaxWidth(0, 0, 128, "Sender: " + message);
   display.display();
 }

 void setup() {
   pinMode(25,OUTPUT); //Send success, LED will bright 1 second

   Serial.begin(115200);
   while (!Serial); //If just the the basic function, must connect to a computer

   SPI.begin(5,19,27,18);
   LoRa.setPins(SS,RST,DI0);
 //  Serial.println("LoRa Sender");

   if (!LoRa.begin(BAND)) {
     Serial.println("Starting LoRa failed!");
     while (1);
   }
   Serial.println("LoRa Initial OK!");
   pinMode(16,OUTPUT);
   digitalWrite(16, LOW);    // set GPIO16 low to reset OLED
   delay(50); 
   digitalWrite(16, HIGH); // while OLED is running, must set GPIO16 in high
   display.init();
   display.flipScreenVertically();
   writeOled("Hello world.");

   WiFi.begin("","");
   WiFi.macAddress(mac);
   macString = String(mac[5], HEX) + String(mac[4], HEX) + String(mac[3], HEX) + String(mac[2], HEX) + String(mac[1], HEX) + String(mac[0], HEX);
   Serial.println(macString);
   WiFi.mode(WIFI_OFF);
 }

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

   writeOled(macString + "|" + String(counter));

   // send packet
   LoRa.beginPacket();
   LoRa.print(macString + "|" + String(counter));
   LoRa.endPacket();

   counter++;
   delay(5000);
 }

Receiver

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

 #include <HTTPClient.h>

 #if defined(ARDUINO_ARCH_ESP32)
 #include <WiFi.h>
 #else
 #include <ESP8266WiFi.h>
 #endif
 #include<Arduino.h>
 #include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier
 #include "SSD1306.h" // alias for `#include "SSD1306Wire.h"`
 #include <WiFi.h>

 const char* ssid = "";
 const char* password = "";

 #define SS      18
 #define RST     14
 #define DI0     26
 #define BAND    433E6

 SSD1306  display(0x3c, 4, 15);

 boolean ConnectWifi(void)
 {
   boolean state = true;
   int i = 0;
   Serial.println("going to try and connect to wifi");
   Serial.print("SSID: ");
   Serial.println(ssid);
   Serial.print("Password: ");
   Serial.println(password);
   WiFi.begin(ssid, password);
   Serial.println("");
   Serial.println("Connecting to WiFi");

   // Wait for connection
   Serial.print("Connecting");
   while (WiFi.status() != WL_CONNECTED) {
     delay(500);
     Serial.print(".");
     if (i > 20){
       state = false;
       break;
     }
     i++;
   }
   if (state) {
     Serial.println("");
     Serial.print("Connected to ");
     Serial.println(ssid);
     Serial.print("IP address: ");
     Serial.println(WiFi.localIP());
   } else {
     Serial.println("");
     Serial.println("Connection failed.");
   }

   return state;
 }

 void writeOled(String message) {
   display.clear();
   display.setTextAlignment(TEXT_ALIGN_LEFT);
   display.setFont(ArialMT_Plain_10);
   display.drawStringMaxWidth(0, 0, 128, "Sender: " + message);
   display.display();
 }

 void setup() {
   Serial.begin(115200);
   while (!Serial); //if just the the basic function, must connect to a computer
   delay(1000);

   ConnectWifi();  

   Serial.println("LoRa Receiver"); 

   SPI.begin(5,19,27,18);
   LoRa.setPins(SS,RST,DI0);

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

   Serial.println("LoRa Initial OK!");
   pinMode(16,OUTPUT);
   digitalWrite(16, LOW);    // set GPIO16 low to reset OLED
   delay(50); 
   digitalWrite(16, HIGH); // while OLED is running, must set GPIO16 in high
   display.init();
   display.flipScreenVertically();
   writeOled("Hello world.");

 }

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

     // read packet
     while (LoRa.available()) {
       if (gotAddress == false) {
         char thisChar = (char)LoRa.read();
         if (thisChar == '|') {
           gotAddress = true;
         } else {
           addressBuffer = addressBuffer + thisChar;
         }
       } else {
         char thisChar = (char)LoRa.read();
         payloadBuffer = payloadBuffer + thisChar;
       }
     }
     Serial.print("Address: ");
     Serial.println(addressBuffer);
     Serial.print("Payload: ");
     Serial.println(payloadBuffer);
   }
 }

To see an example of duplexing the radios, please see the excellent example by Sandeep Mistry here: https://github.com/sandeepmistry/arduino-LoRa/blob/master/examples/LoRaDuplex/LoRaDuplex.ino