Firmware: Persist FrameCounter in EEPROM
This commit is contained in:
parent
31063b01d2
commit
361f8e0b85
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue