-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #76 from matthias-bs/feature-lightning-postproc
Feature lightning postproc
- Loading branch information
Showing
7 changed files
with
873 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"configuration": "Revision=TTGO_LoRa32_v21new,FlashFreq=80,UploadSpeed=921600,DebugLevel=debug,EraseFlash=none", | ||
"board": "esp32:esp32:ttgo-lora32", | ||
"programmer": "esptool", | ||
"sketch": "examples/BresserWeatherSensorBasic/BresserWeatherSensorBasic.ino" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"configurations": [ | ||
{ | ||
"name": "Linux", | ||
"includePath": [ | ||
"${workspaceFolder}/**" | ||
], | ||
"defines": [], | ||
"compilerPath": "/usr/bin/gcc", | ||
"cStandard": "c17", | ||
"cppStandard": "gnu++17", | ||
"intelliSenseMode": "linux-gcc-x64" | ||
}, | ||
{ | ||
"name": "Arduino", | ||
"includePath": [ | ||
"${workspaceFolder}/**", | ||
"/home/mp/Arduino/libraries/**" | ||
], | ||
"defines": [], | ||
"intelliSenseMode": "${default}", | ||
"configurationProvider": "vsciot-vscode.vscode-arduino" | ||
} | ||
], | ||
"version": 4 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/////////////////////////////////////////////////////////////////////////////////////////////////// | ||
// Lightning.cpp | ||
// | ||
// Post-processing of lightning sensor data | ||
// | ||
// Input: | ||
// * Timestamp (time and date) | ||
// * Sensor startup flag | ||
// * Accumulated lightning event counter | ||
// * Estimated distance of last strike | ||
// | ||
// Output: | ||
// * Number of events during last update cycle | ||
// * Timestamp of last event | ||
// * Number of strikes during past 60 minutes | ||
// | ||
// Non-volatile data is stored in the ESP32's RTC RAM to allow retention during deep sleep mode. | ||
// | ||
// https://github.com/matthias-bs/BresserWeatherSensorReceiver | ||
// | ||
// | ||
// created: 07/2023 | ||
// | ||
// | ||
// MIT License | ||
// | ||
// Copyright (c) 2023 Matthias Prinke | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in all | ||
// copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
// SOFTWARE. | ||
// | ||
// History: | ||
// | ||
// 20220721 Created | ||
// | ||
// ToDo: | ||
// - Store non-volatile data in NVS Flash instead of RTC RAM | ||
// (to support ESP8266 and to keep data during power-off) | ||
// | ||
/////////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
||
#include <Arduino.h> | ||
#include "Lightning.h" | ||
|
||
#ifndef RTC_DATA_ATTR | ||
#define RTC_DATA_ATTR static | ||
#endif | ||
#if !defined(ESP32) | ||
#pragma message("Lightning with SLEEP_EN only supported on ESP32!") | ||
#endif | ||
|
||
/** | ||
* \typedef nvData_t | ||
* | ||
* \brief Data structure for lightning sensor to be stored in non-volatile memory | ||
* | ||
* On ESP32, this data is stored in the RTC RAM. | ||
*/ | ||
typedef struct { | ||
/* Data of last lightning event */ | ||
int prevCount; | ||
int events; | ||
uint8_t distance; | ||
time_t timestamp; | ||
|
||
/* Data of past 60 minutes */ | ||
uint16_t hist[LIGHTNING_HIST_SIZE]; | ||
|
||
} nvLightning_t; | ||
|
||
RTC_DATA_ATTR nvLightning_t nvLightning = { | ||
.prevCount = -1, | ||
.events = 0, | ||
.distance = 0, | ||
.timestamp = 0, | ||
.hist = {0} | ||
}; | ||
|
||
void | ||
Lightning::reset(void) | ||
{ | ||
nvLightning.prevCount = -1; | ||
nvLightning.events = -1; | ||
nvLightning.distance = 0; | ||
nvLightning.timestamp = 0; | ||
} | ||
|
||
void | ||
Lightning::init(uint16_t count) | ||
{ | ||
for (int i=0; i<LIGHTNING_HIST_SIZE; i++) { | ||
nvLightning.hist[i] = count; | ||
} | ||
} | ||
|
||
void | ||
Lightning::update(time_t timestamp, int count, uint8_t distance, bool startup) | ||
{ | ||
// currently unused | ||
(void)startup; | ||
|
||
if (nvLightning.prevCount == -1) { | ||
nvLightning.prevCount = count; | ||
return; | ||
} | ||
|
||
if (nvLightning.prevCount < count) { | ||
nvLightning.events = count - nvLightning.prevCount; | ||
nvLightning.prevCount = count; | ||
nvLightning.distance = distance; | ||
nvLightning.timestamp = timestamp; | ||
} | ||
|
||
|
||
struct tm timeinfo; | ||
localtime_r(×tamp, &timeinfo); | ||
|
||
int min = timeinfo.tm_min; | ||
int idx = min / LIGHTNING_UPD_RATE; | ||
nvLightning.hist[idx] = count; | ||
|
||
// Search for skipped entries, i.e. entries which are smaller than their predecessor | ||
|
||
for (int i=0; i<LIGHTNING_HIST_SIZE; i++) { | ||
log_d("i=%d: hist[i]=%d\n", i, nvLightning.hist[i]); | ||
if ((i == idx) || (i == inc(idx))) { | ||
continue; | ||
} | ||
if (nvLightning.hist[i] < nvLightning.hist[dec(i)]) { | ||
log_d("Marking %d as invalid\n", i); | ||
nvLightning.hist[i] = -1; | ||
} | ||
} | ||
log_d("\n"); | ||
} | ||
|
||
bool | ||
Lightning::lastEvent(time_t ×tamp, int &events, uint8_t &distance) | ||
{ | ||
if (nvLightning.events == -1) { | ||
return false; | ||
} | ||
|
||
events = nvLightning.events; | ||
distance = nvLightning.distance; | ||
timestamp = nvLightning.timestamp; | ||
|
||
return true; | ||
} | ||
|
||
bool | ||
Lightning::pastHour(time_t timestamp, int &events) | ||
{ | ||
struct tm timeinfo; | ||
localtime_r(×tamp, &timeinfo); | ||
|
||
int min = timeinfo.tm_min; | ||
int idx = min / LIGHTNING_UPD_RATE; | ||
|
||
if (nvLightning.hist[inc(idx)] == -1) { | ||
log_d("Invalid\n"); | ||
return false; | ||
} | ||
events = nvLightning.hist[idx] - nvLightning.hist[inc(idx)]; | ||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
/////////////////////////////////////////////////////////////////////////////////////////////////// | ||
// Lightning.h | ||
// | ||
// Post-processing of lightning sensor data | ||
// | ||
// Input: | ||
// * Timestamp (time and date) | ||
// * Sensor startup flag | ||
// * Accumulated lightning event counter | ||
// * Estimated distance of last strike | ||
// | ||
// Output: | ||
// * Number of events during last update cycle | ||
// * Timestamp of last event | ||
// * Number of strikes during past 60 minutes (TBD) | ||
// | ||
// Non-volatile data is stored in the ESP32's RTC RAM to allow retention during deep sleep mode. | ||
// | ||
// https://github.com/matthias-bs/BresserWeatherSensorReceiver | ||
// | ||
// | ||
// created: 07/2023 | ||
// | ||
// | ||
// MIT License | ||
// | ||
// Copyright (c) 2023 Matthias Prinke | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in all | ||
// copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
// SOFTWARE. | ||
// | ||
// History: | ||
// | ||
// 20220721 Created | ||
// | ||
// ToDo: | ||
// - Store non-volatile data in NVS Flash instead of RTC RAM | ||
// (to support ESP8266 and to keep data during power-off) | ||
// - Handle sensor counter overflow and startup flag | ||
// - Number of strikes during past 60 minutes | ||
// | ||
/////////////////////////////////////////////////////////////////////////////////////////////////// | ||
|
||
#include "time.h" | ||
#if defined(ESP32) || defined(ESP8266) | ||
#include <sys/time.h> | ||
#endif | ||
|
||
/** | ||
* \def | ||
* | ||
* Set to the value which leads to a reset of the lightning sensor counter output to zero (overflow). | ||
*/ | ||
#define LIGHTNINGCOUNT_MAX_VALUE 100 | ||
|
||
/** | ||
* \def | ||
* | ||
* Lightning sensor update rate [min] | ||
*/ | ||
#define LIGHTNING_UPD_RATE 6 | ||
|
||
/** | ||
* \def | ||
* | ||
* Set to 3600 [sec] / update_rate_rate [sec] | ||
*/ | ||
#define LIGHTNING_HIST_SIZE 10 | ||
|
||
/** | ||
* \class Lightning | ||
* | ||
* \brief Calculation number of lightning events during last sensor update cycle and | ||
* during last hour (past 60 minutes); storing timestamp and distance of last event. | ||
*/ | ||
class Lightning { | ||
public: | ||
float countCurr; | ||
|
||
Lightning() {}; | ||
|
||
/** | ||
* Initialize/reset non-volatile data | ||
*/ | ||
void reset(void); | ||
|
||
|
||
/** | ||
* Initialize memory for hourly (past 60 minutes) events | ||
* | ||
* \param count accumulated number of events | ||
*/ | ||
void init(uint16_t count); | ||
|
||
|
||
/** | ||
* \fn update | ||
* | ||
* \brief Update lightning data | ||
* | ||
* \param timestamp timestamp (epoch) | ||
* | ||
* \param count accumulated number of events | ||
* | ||
* \param startup sensor startup flag | ||
* | ||
* \param lightningCountMax overflow value; when reached, the sensor's counter is reset to zero | ||
*/ | ||
void update(time_t timestamp, int count, uint8_t distance, bool startup = false /*, uint16_t lightningCountMax = LIGHTNINGCOUNT_MAX */); | ||
|
||
|
||
/** | ||
* \fn pastHour | ||
* | ||
* \brief Get number of lightning events during past 60 minutes | ||
* | ||
* \param timestamp current time | ||
* \param events return number of events during past 60 minutes | ||
* | ||
* \return true if valid | ||
*/ | ||
bool pastHour(time_t timestamp, int &events); | ||
|
||
/* | ||
* \fn lastCycle | ||
* | ||
* \brief Get number of events during last update cycle with detected lightning events | ||
* | ||
* \return number of lightning events | ||
*/ | ||
int lastCycle(void); | ||
|
||
/* | ||
* \fn lastEvent | ||
* | ||
* \brief Get data of last lightning event | ||
* | ||
* \param timestamp timestamp of last event | ||
* \param events number of lightning strikes | ||
* \param distance estimated distance | ||
* | ||
* \return true if valid | ||
*/ | ||
bool lastEvent(time_t ×tamp, int &events, uint8_t &distance); | ||
|
||
private: | ||
inline int inc(int x) | ||
{ | ||
return ((x + 1) == LIGHTNING_HIST_SIZE) ? 0 : ++x; | ||
} | ||
|
||
inline int dec(int x) | ||
{ | ||
return (x == 0) ? (LIGHTNING_HIST_SIZE - 1) : --x; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
#define RTC_DATA_ATTR static | ||
#define log_d(...) { printf(__VA_ARGS__); } |
Oops, something went wrong.