Open mofm opened 7 months ago
Hard to tell without knowing what you're compiling. You are not also including the ESP32 EEPROM.h
, are you? You can only include one of the two as they both offer the EEPROM
instance, which is by design: this is to make existing code compatible.
Hi @ropg ,
First of all, thank you for your quick answer.
Yes, including only ESP32_RTC_EEPROM.
Sample Code:
#include <RadioLib.h>
#include <Wire.h>
#include <SPI.h>
#include <ESP32_RTC_EEPROM.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include "boards.h"
// The same network data that you used in the LoRaWAN_TTN example.
uint64_t joinEUI = 0x0000000000000000;
uint64_t devEUI = 0x0000000000000000;
uint8_t nwkKey[] = { 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--,
0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x-- };
uint8_t appKey[] = { 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--,
0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x-- };
// Pause between sends in seconds, so this is every 30 minutes.
#define MINIMUM_DELAY 1800
// Create a backup copy of the RTC RAM to flash every so many times
#define BACKUP_EVERY 100
// The LoRaWAN specification provides a port field (FPort) to distinguish
// between different types of messages on the receiving end. It's one byte, but
// FPort 0 is reserved for LoRaWAN-internal MAC messages, and values 224 through
// 255 (0xE0…0xFF) are reserved for future standardized application extensions,
// so don't use those.
#define FPORT 10
// create the node instance on the EU-868 band using the radio module and the
// encryption key make sure you are using the correct band based on your
// geographical location!
LoRaWANNode node(&radio, &EU868);
// for fixed bands with subband selection such as US915 and AU915, you must
// specify the subband that matches the Frequency Plan that you selected on your
// LoRaWAN console LoRaWANNode node(&radio, &US915, 2);
// Variables that are placed in RTC RAM survive deep sleep. This counter tells
// us how many times we've booted since the last reset or power loss.
RTC_DATA_ATTR int count = 1;
// This flag is set when we receive a downlink packet, so we can save to flash.
bool gotDownlink = false;
void helper_deep_sleep(int seconds = 0) {
// It seems to make no sense to do a .begin() here, but in case the radio is
// not interacted with at all before sleep, it will not respond to just
// .sleep() and then consumes 800 µA more than it should in deep sleep.
radio.begin();
// 'false' here is to not have a warm start, we re-init the after sleep.
radio.sleep(false);
u8g2->sleepOn();
SPI.end();
SDSPI.end();
pinMode(RADIO_CS_PIN, INPUT);
pinMode(RADIO_RST_PIN, INPUT);
pinMode(RADIO_DIO1_PIN, INPUT);
pinMode(RADIO_BUSY_PIN, INPUT);
pinMode(I2C_SDA, INPUT);
pinMode(I2C_SCL, INPUT);
pinMode(RADIO_SCLK_PIN, INPUT);
pinMode(RADIO_MISO_PIN, INPUT);
pinMode(RADIO_MOSI_PIN, INPUT);
// Set timer wakeup if applicable
if (seconds > 0) {
esp_sleep_enable_timer_wakeup(seconds * 1000000);
}
// and off to bed we go
esp_deep_sleep_start();
}
void setup() {
initBoard();
bme.begin();
// initialize radio
Serial.println("Radio init");
RADIOLIB(radio.begin());
if (_radiolib_status != RADIOLIB_ERR_NONE) {
goToSleep(); // Does not return, program starts over next round
}
// Manages uplink intervals to the TTN Fair Use Policy
node.setDutyCycle(true, 1250);
// We tell the LoRaWAN code about our battery level in case the network
// asks for battery-level and SNR with a MAC_DEV_STATUS message.
// ( 0 for external power source, 1 for lowest battery, 254 for highest battery,
// 255 for unable to measure.)
uint8_t battLevel = 146;
node.setDeviceStatus(battLevel);
// Join the network, or resume previous saved session
if (count == 1) {
// If this is the first boot, we woke up with a wiped RTC RAM. We assume we
// were rebooted, have lost RTC RAM (and thus the uplink packet counter
// FCntUp) and need to join the network again with our keys and nonces saved
// in flash.
Serial.printf("Joining (forced)\n");
RADIOLIB(node.beginOTAA(joinEUI, devEUI, nwkKey, appKey, RADIOLIB_LORAWAN_DATA_RATE_UNUSED, true));
} else {
// If we woke up with RTC RAM intact, continue with what we have.
Serial.printf("Joining\n");
RADIOLIB(node.beginOTAA(joinEUI, devEUI, nwkKey, appKey));
}
// Let's see what happened when we tried to join
if (_radiolib_status != RADIOLIB_ERR_NONE && _radiolib_status != RADIOLIB_LORAWAN_MODE_OTAA) {
Serial.printf("Join failed, trying again next time.");
goToSleep(); // Does not return, program starts over next round
}
// If we're still here, it means we joined, and we can send something
sendPacket();
goToSleep(); // Does not return, program starts over next round
}
void loop() {
// This is never called. There is no repetition: we always go back to deep
// sleep one way or the other at the end of setup()
}
void sendPacket() {
// 5-byte packet
uint8_t packet[5] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (it's a very slow sensor)
float h = bme.readHumidity();
// Read temperature as Celsius (the default)
float t = bme.readTemperature();
// Temperatue and Humidity
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from BME sensor!");
// just leaves the 0xFFs in the packets
} else {
Serial.printf("Temperature %.2f°C, Relative humidity %.2f%%\n", t, h);
packet[0] = int(t);
packet[1] = int((float)(t - packet[0]) * 100);
packet[2] = int(h);
packet[3] = int((float)(h - packet[2]) * 100);
}
// Send the packet. If no RX_TIMEOUT, it may mean we got a downlink packet, so
// we store to flash before going to sleep.
if (node.sendReceive(packet, 5, FPORT) == RADIOLIB_ERR_NONE) {
gotDownlink = true;
}
}
void goToSleep() {
// allows recall of the session after deepsleep
node.saveSession();
// If we woke up with wiped RTC RAM, or received a message, or we've
// reached BACKUP_EVERY, we back it up to flash before going to sleep.
if (count == 1 || gotDownlink == true || count % BACKUP_EVERY == 0) {
Serial.println("RTC RAM -> flash.");
EEPROM.toNVS();
}
// Raise the boot counter, kept in RTC RAM
count++;
// Calculate minimum duty cycle delay (per FUP & law!)
uint32_t interval = node.timeUntilUplink();
// And then pick it or our MINIMUM_DELAY, whichever is greater
uint32_t delayMs = max(interval, (uint32_t)MINIMUM_DELAY * 1000);
Serial.printf("Next TX in %i s\n", delayMs/1000);
Serial.println("Deep sleep now");
// Make sure this still prints before sleep
delay(10);
// And off to bed we go
helper_deep_sleep((delayMs / 1000) - 5);
}
I wanted to try this lib in my project to test it. But while compiling it on Arduino IDE, I got the following error: