Firmware: Persist FrameCounter in EEPROM

This commit is contained in:
seiichiro 2020-04-21 07:57:23 +02:00
parent 31063b01d2
commit 361f8e0b85
1 changed files with 47 additions and 2 deletions

View File

@ -31,11 +31,13 @@
#include <Arduino.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <EEPROM.h>
#include <tinySPI.h>
// secconfig.h Configures RF Module, TTN Keys / RF Networks and used Sensor
#include "secconfig.h"
// Create needed Variables and Objects for RF Module
#ifdef RF_LORA
// Include LoRaWAN
#include <LoRaWAN.h>
@ -52,7 +54,7 @@
RFM69 radio;
#endif
// Sensorclass and deepsleep interval (for measurement about every 10Min)
// Create Sensor Class
#ifdef HAS_BME280
#include <BME280.h>
BME280 sensor;
@ -63,7 +65,7 @@
SHT21 sensor;
#endif
// Global Variable used for deep sleep
// Global Variable to Track Deep Sleep
uint16_t sleep_interval;
#ifdef LED_PIN
@ -129,6 +131,22 @@ int32_t readVcc() {
return result;
}
// Crude Wear Leveling Algorithm to Spread the EEPROM Cell Wear Over
// the first 64 Byte. Using this Method the Theoretical EEPROM Livetime
// should be around 60 Years at a 10 Minute Sending Interval
// (100000 Erase Cycles per Cell * 32 Locations / 144 Measurements a day * 365)
//
// Returns the Next EEPROM Address for Saving the Frame Counter
uint8_t calcEepromAddr(uint16_t framecounter) {
uint8_t eeprom_addr = ((framecounter%32)*sizeof(framecounter));
if (eeprom_addr == 0) {
eeprom_addr = 62;
} else {
eeprom_addr = eeprom_addr-sizeof(framecounter);
}
return eeprom_addr;
}
void setup()
{
// Initialize Sleep Timer
@ -139,9 +157,34 @@ void setup()
// Setup LoraWAN
rfm.init();
lora.setKeys(NwkSkey, AppSkey, DevAddr);
// Get Framecounter from EEPROM
// Check if EEPROM is initialized
if (EEPROM.read(511) != 0x42) {
// Set first 64 byte to 0x00 for the wear leveling hack to work
for (int i = 0; i < 64; i++)
EEPROM.write(i, 0x00);
// Write the magic value so we know it's initialized
EEPROM.write(511, 0x42);
} else {
// Get the Last Saved (=Highest) Frame Counter
uint16_t Frame_Counter_Sv = 0x00000000;
uint8_t eeprom_addr = 0x0000;
EEPROM.get(eeprom_addr, Frame_Counter_Sv);
while (eeprom_addr < 32*sizeof(Frame_Counter_Tx)) {
if (Frame_Counter_Sv > Frame_Counter_Tx) {
Frame_Counter_Tx = Frame_Counter_Sv;
} else {
break;
}
eeprom_addr += sizeof(Frame_Counter_Tx);
EEPROM.get(eeprom_addr, Frame_Counter_Sv);
}
}
#endif
#ifdef RF_RFM69
// Setup RFM69 Module
radio.initialize(RF69_433MHZ,RFM69_NODEID,RFM69_NETWORKID);
#ifdef RFM69_ENCKEY
radio.encrypt(RFM69_ENCKEY);
@ -216,6 +259,8 @@ void loop()
lora.Send_Data((unsigned char *)&data, sizeof(data), Frame_Counter_Tx, SF7BW125, 0x01);
Frame_Counter_Tx++;
#endif
// Save the next FrameCounter to EEPROM
EEPROM.put(calcEepromAddr(Frame_Counter_Tx), Frame_Counter_Tx);
#endif
#ifdef RF_RFM69