ESP32 connected to a RFM95W LoRa module using interrupt to wake up from light sleep
// ESP32 connected to a RFM95W LoRa module
// on receive packet wakeup from light sleep
#include <SPI.h>
#include <LoRa.h>
#include "driver/rtc_io.h"
// ESP32 VSPI connections
// ESP32 SCK pin GPIO18 to RFM95_pin SCK
// ESP32 MISO pin GPIO19 to RFM95_pin MISO
// ESP32 MOSI pin GPIO23 to RFM95_pin MOSI
// ESP32 pin GPIO 5 to RFM95 SS
// ESP32 pin GPIO4 to RFM95 Reset
// ESP32 pin GPIO2 to RFM95 DIO0
// measure time between rising edge using micros()
#define WAKEUP_GPIO GPIO_NUM_27 // RFM95 DIO0 wakeup pin
void setup() {
Serial.begin(115200);
delay(5000);
Serial.println("\n\nESP32 LoRa RFM95W Receiver");
// void setPins(int ss = LORA_DEFAULT_SS_PIN, int reset = LORA_DEFAULT_RESET_PIN, int dio0 = LORA_DEFAULT_DIO0_PIN);
//LoRa.setPins(8, 4, 7); // for Lora 32u4
LoRa.setPins(5, 4, 27); // for ESP32
if (!LoRa.begin(866E6)) {
Serial.println("Starting LoRa failed!");
while (1)
;
}
Serial.println("Starting LoRa OK!");
}
// enable LoRa receiver, goto light sleep on wakeup read packet
void loop() {
LoRa.receive();
// set GPIO pin to wake on high pulse from RFM95 DIO0
gpio_wakeup_enable(WAKEUP_GPIO, GPIO_INTR_HIGH_LEVEL);
esp_sleep_enable_gpio_wakeup();
Serial.println("goto light sleep");
delay(1000);
esp_light_sleep_start(); // light sleep!!
Serial.begin(115200);
while (!Serial) { delay(500); }
Serial.println("wakeup from ligh sleep");
// now read received packet
int packetSize = LoRa.parsePacket(); // packet available
if (packetSize) {
Serial.print("Received packet '");
while (LoRa.available()) { // yes, read it
Serial.print((char)LoRa.read());
}
// print RSSI of packet
Serial.print("' with RSSI ");
Serial.println(LoRa.packetRssi());
}
}
result
ESP32 LoRa RFM95W Receiver
Starting LoRa OK!
goto light sleep
wakeup from ligh sleep
Received packet 'hello 1442' with RSSI -69
goto light sleep
wakeup from ligh sleep
Received packet 'hello 1443' with RSSI -70
goto light sleep
wakeup from ligh sleep
Received packet 'hello 1444' with RSSI -70
goto light sleep
wakeup from ligh sleep
Received packet 'hello 1445' with RSSI -68
goto light sleep
wakeup from ligh sleep
Received packet 'hello 1446' with RSSI -69
goto light sleep
waking up from deep sleep
// ESP32 connected to a RFM95W LoRa module
// when in deep sleep on receiving LoRa packet on a RTC_IO receiver wakes up
// In Deep-sleep mode, the CPUs, most of the RAM, and
// all digital peripherals that are clocked from APB_CLK are powered off.
// therefore any LoRa packet which caused wakeup from deep sleep will be lost
// one possible technique is
// 1. the receiver program enables LoRa receiver and goes to deep sleep
// 2. initially the transmitter sends a short wakeup packet followed short time later by a data packet
// (the short time is to allow time for the RTC_IO reset and initialze the LoRa receiver )
// 3. on receipt of the wakeup RTC_IO packet the receiver will then wait for a short time for the data packet
// 4. receiver will read data packet, process it and then go into deep sleep
// using low level RFM95W function calls it may be possible on wakeup from deep sleep
// to read the receiver data???? not attempted it!!
#include <SPI.h>
#include <LoRa.h>
#include "driver/rtc_io.h"
// ESP32 VSPI connections
// ESP32 SCK pin GPIO18 to RFM95_pin SCK
// ESP32 MISO pin GPIO19 to RFM95_pin MISO
// ESP32 MOSI pin GPIO23 to RFM95_pin MOSI
// ESP32 pin GPIO 5 to RFM95 SS
// ESP32 pin GPIO4 to RFM95 Reset
// ESP32 pin GPIO2 to RFM95 DIO0
// measure time between rising edge using micros()
#define WAKEUP_GPIO GPIO_NUM_2 // RFM95 DIO0 wakeup pin
// on reset this will display the reason
int print_wakeup_reason() {
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch (wakeup_reason) {
case ESP_SLEEP_WAKEUP_EXT0: Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case ESP_SLEEP_WAKEUP_EXT1: Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case ESP_SLEEP_WAKEUP_TIMER: Serial.println("Wakeup caused by timer"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD: Serial.println("Wakeup caused by touchpad"); break;
case ESP_SLEEP_WAKEUP_ULP: Serial.println("Wakeup caused by ULP program"); break;
default:
Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason);
return -1;
break;
}
return wakeup_reason;
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\n\nESP32 LoRa RFM95W Receiver");
// void setPins(int ss = LORA_DEFAULT_SS_PIN, int reset = LORA_DEFAULT_RESET_PIN, int dio0 = LORA_DEFAULT_DIO0_PIN);
//LoRa.setPins(8, 4, 7); // for Lora 32u4
LoRa.setPins(5, -1, 2); // for ESP32
if (!LoRa.begin(866E6)) {
Serial.println("Starting LoRa failed!");
while (1)
;
}
Serial.println("Starting LoRa OK!");
// if woken up by external EXT0 from RFM95 DIO0
if (print_wakeup_reason() == ESP_SLEEP_WAKEUP_EXT0) {
// wait for a following packet
unsigned long timer1 = millis();
while (millis() - timer1 < 10000) {
int packetSize = LoRa.parsePacket();
if (packetSize) {
Serial.print("Received packet '");
while (LoRa.available()) {
Serial.print((char)LoRa.read());
}
// print RSSI of packet
Serial.print("' with RSSI ");
Serial.println(LoRa.packetRssi());
break;
}
}
}
// enable LoRa receiver and goto deep sleep waiting for next packet
LoRa.receive();
esp_sleep_enable_ext0_wakeup(WAKEUP_GPIO, 1); //1 = High, 0 = Low
// Configure pullup/downs via RTCIO to tie wakeup pins to inactive level during deepsleep.
// EXT0 resides in the same power domain (RTC_PERIPH) as the RTC IO pullup/downs.
// No need to keep that power domain explicitly, unlike EXT1.
rtc_gpio_pullup_dis(WAKEUP_GPIO);
rtc_gpio_pulldown_en(WAKEUP_GPIO);
//Go to sleep now
Serial.println("Going to sleep now");
esp_deep_sleep_start();
Serial.println("This will never be printed");
}
void loop() {}
results - LoRa transmitter regularly transmits a test packet incrementing a count by one
first packet wakes receiver from deep sleep - second packet is received and is displayed
hence received packet count is 282 284 286 etc
ESP32 LoRa RFM95W Receiver
Starting LoRa OK!
Wakeup was not caused by deep sleep: 0
Going to sleep now
ets Jul 29 2019 12:21:46
rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4916
load:0x40078000,len:16436
load:0x40080400,len:4
ho 8 tail 4 room 4
load:0x40080404,len:3524
entry 0x400805b8
ESP32 LoRa RFM95W Receiver
Starting LoRa OK!
Wakeup caused by external signal using RTC_IO
Received packet 'hello 282' with RSSI -64
Going to sleep now
ESP32 LoRa RFM95W Receiver
Starting LoRa OK!
Wakeup caused by external signal using RTC_IO
Received packet 'hello 284' with RSSI -65
Going to sleep now
when LoRa.begin(866E6) is called the LoRa packet which caused wakeup from deep sleep is lost
using low level RFM95W function calls it may be possible on wakeup from deep sleep to read the receiver data???? not attempted it!!