From 15be5fc61141e028634dbfadfe1347fc04f23f15 Mon Sep 17 00:00:00 2001 From: SQ2CPA Date: Thu, 21 Mar 2024 17:31:54 +0100 Subject: [PATCH] feat: battery voltage cutoff monitor --- src/LoRa_APRS_iGate.cpp | 10 ++++++++-- src/battery_utils.cpp | 42 ++++++++++++++++++++++++++++++++++++++--- src/battery_utils.h | 1 + src/pins_config.h | 3 +++ src/utils.cpp | 8 +++++--- src/web_utils.cpp | 1 - 6 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index 6a27fa1..1101730 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -18,7 +18,7 @@ #include "display.h" #include "utils.h" #include - +#include "battery_utils.h" Configuration Config; WiFiClient espClient; @@ -42,6 +42,8 @@ bool WiFiConnected = false; bool WiFiAutoAPStarted = false; long WiFiAutoAPTime = false; +uint32_t lastBatteryCheck = 0; + uint32_t bmeLastReading = -60000; String batteryVoltage; @@ -56,7 +58,7 @@ String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seven void setup() { Serial.begin(115200); - #if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) + #if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_WSL) pinMode(batteryPin, INPUT); #endif #ifdef HAS_INTERNAL_LED @@ -94,6 +96,10 @@ void loop() { return; // Don't process IGate and Digi during OTA update } + if (BATTERY_Utils::checkIfShouldSleep()) { + ESP.deepSleep(1800000000); // 30 min sleep (60s = 60e6) + } + thirdLine = Utils::getLocalIP(); WIFI_Utils::checkWiFi(); // Always use WiFi, not related to IGate/Digi mode diff --git a/src/battery_utils.cpp b/src/battery_utils.cpp index c8f9490..e17c316 100644 --- a/src/battery_utils.cpp +++ b/src/battery_utils.cpp @@ -2,7 +2,13 @@ #include "configuration.h" #include "pins_config.h" +// Uncomment if you want to monitor voltage and sleep if voltage is too low (<3.1V) +#define LOW_VOLTAGE_CUTOFF + +float cutOffVoltage = 3.1; + extern Configuration Config; +extern uint32_t lastBatteryCheck; float adcReadingTransformation = (3.3/4095); float voltageDividerCorrection = 0.288; @@ -16,11 +22,15 @@ float multiplyCorrection = 0.035; namespace BATTERY_Utils { + float mapVoltage(float voltage, float in_min, float in_max, float out_min, float out_max) { + return (voltage - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + } + float checkBattery() { int sample; int sampleSum = 0; for (int i=0; i<100; i++) { - #if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) + #if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_WSL) sample = analogRead(batteryPin); #endif #if defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa) @@ -29,7 +39,12 @@ namespace BATTERY_Utils { sampleSum += sample; delayMicroseconds(50); } - return (2 * (sampleSum/100) * adcReadingTransformation) + voltageDividerCorrection; + + float voltage = (2 * (sampleSum/100) * adcReadingTransformation) + voltageDividerCorrection; + + return voltage; // raw voltage without mapping + + // return mapVoltage(voltage, 3.34, 4.71, 3.0, 4.2); // mapped voltage } float checkExternalVoltage() { @@ -40,7 +55,28 @@ namespace BATTERY_Utils { sampleSum += sample; delayMicroseconds(50); } - return ((((sampleSum/100)* adcReadingTransformation) + readingCorrection) * ((R1+R2)/R2)) - multiplyCorrection; + + float voltage = ((((sampleSum/100)* adcReadingTransformation) + readingCorrection) * ((R1+R2)/R2)) - multiplyCorrection; + + return voltage; // raw voltage without mapping + + // return mapVoltage(voltage, 5.05, 6.32, 4.5, 5.5); // mapped voltage + } + + bool checkIfShouldSleep() { + #ifdef LOW_VOLTAGE_CUTOFF + if (lastBatteryCheck == 0 || millis() - lastBatteryCheck >= 15 * 60 * 1000) { + lastBatteryCheck = millis(); + + float voltage = checkBattery(); + + if (voltage < cutOffVoltage) { + return true; + } + } + #endif + + return false; } } \ No newline at end of file diff --git a/src/battery_utils.h b/src/battery_utils.h index 1e5ee1a..6dd1794 100644 --- a/src/battery_utils.h +++ b/src/battery_utils.h @@ -8,6 +8,7 @@ namespace BATTERY_Utils { float checkBattery(); float checkExternalVoltage(); + bool checkIfShouldSleep(); } diff --git a/src/pins_config.h b/src/pins_config.h index f7a1f0c..c10f083 100644 --- a/src/pins_config.h +++ b/src/pins_config.h @@ -119,6 +119,9 @@ #define HAS_INTERNAL_LED #endif +#ifdef HELTEC_WSL +#define batteryPin 1 +#endif #if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) #define internalLedPin 25 // Green Led #define batteryPin 35 diff --git a/src/utils.cpp b/src/utils.cpp index b04384b..9b5abe5 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -115,15 +115,17 @@ namespace Utils { secondaryBeaconPacket = iGateLoRaBeaconPacket + Config.beacon.comment; } - #if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) + #if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_WSL) if (Config.sendBatteryVoltage) { - beaconPacket += " (Batt=" + String(BATTERY_Utils::checkBattery(),2) + "V)"; + beaconPacket += " Batt=" + String(BATTERY_Utils::checkBattery(),2) + "V"; + secondaryBeaconPacket += " Batt=" + String(BATTERY_Utils::checkBattery(),2) + "V"; sixthLine = " (Batt=" + String(BATTERY_Utils::checkBattery(),2) + "V)"; } #endif if (Config.externalVoltageMeasurement) { - beaconPacket += " (Ext V=" + String(BATTERY_Utils::checkExternalVoltage(),2) + "V)"; + beaconPacket += " Ext=" + String(BATTERY_Utils::checkExternalVoltage(),2) + "V"; + secondaryBeaconPacket += " Ext=" + String(BATTERY_Utils::checkExternalVoltage(),2) + "V"; sixthLine = " (Ext V=" + String(BATTERY_Utils::checkExternalVoltage(),2) + "V)"; } diff --git a/src/web_utils.cpp b/src/web_utils.cpp index d5125c7..d8c35cb 100644 --- a/src/web_utils.cpp +++ b/src/web_utils.cpp @@ -168,7 +168,6 @@ namespace WEB_Utils { String type = request->getParam("type", false)->value(); if (type == "send-beacon") { - Serial.println(lastBeaconTx); lastBeaconTx = 0; request->send(200, "text/plain", "Beacon will be sent in a while");