Merge pull request #64 from SQ2CPA/main

Experimental Low power mode and Low voltage cut off
This commit is contained in:
Ricardo Guzman (Richonguzman) 2024-03-28 16:20:08 -03:00 committed by GitHub
commit c1bb6e39ef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 176 additions and 32 deletions

View file

@ -21,7 +21,7 @@ jobs:
- "ttgo-t-beam-v1_SX1268"
- "ttgo-t-beam-v1_2_SX1262"
- "heltec_wireless_stick"
- "heltec_wireless_stick_lite"
- "heltec_ht-ct62"
steps:
- uses: actions/checkout@v3
@ -41,6 +41,7 @@ jobs:
- name: Move Files
run: |
mkdir -p installer/firmware
cp .pio/build/${{ matrix.target }}/firmware.bin installer/ota_update.bin
cp .pio/build/${{ matrix.target }}/firmware.bin installer/firmware/
cp .pio/build/${{ matrix.target }}/bootloader.bin installer/firmware/
cp .pio/build/${{ matrix.target }}/partitions.bin installer/firmware/

View file

@ -22,7 +22,7 @@ jobs:
- "ttgo-t-beam-v1_SX1268"
- "ttgo-t-beam-v1_2_SX1262"
- "heltec_wireless_stick"
- "heltec_wireless_stick_lite"
- "heltec_ht-ct62"
steps:
- uses: actions/checkout@v3

View file

@ -65,6 +65,8 @@
"rememberStationTime": 30,
"sendBatteryVoltage": false,
"externalVoltageMeasurement": false,
"externalVoltagePin": 34
"externalVoltagePin": 34,
"lowPowerMode": false,
"lowVoltageCutOff": 0
}
}

View file

@ -1236,6 +1236,72 @@
</div>
</div>
</div>
<hr />
<div class="row my-5 d-flex align-items-top">
<div class="col-lg-3 col-sm-12">
<h5>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="currentColor"
class="bi bi-heart-pulse-fill"
viewBox="0 0 16 16"
>
<path
d="M1.475 9C2.702 10.84 4.779 12.871 8 15c3.221-2.129 5.298-4.16 6.525-6H12a.5.5 0 0 1-.464-.314l-1.457-3.642-1.598 5.593a.5.5 0 0 1-.945.049L5.889 6.568l-1.473 2.21A.5.5 0 0 1 4 9z"
/>
<path
d="M.88 8C-2.427 1.68 4.41-2 7.823 1.143q.09.083.176.171a3 3 0 0 1 .176-.17C11.59-2 18.426 1.68 15.12 8h-2.783l-1.874-4.686a.5.5 0 0 0-.945.049L7.921 8.956 6.464 5.314a.5.5 0 0 0-.88-.091L3.732 8z"
/>
</svg>
Experimental
</h5>
<small>You can test new features. <u>Use at your own risk!</u></small>
</div>
<div class="col-lg-9 col-sm-12">
<div class="row">
<div class="col-12">
<div class="form-check form-switch">
<div class="form-text">
WiFi disabled. Sleep mode. Best for solar Digi with SX126X.
</div>
<input
type="checkbox"
name="other.lowPowerMode"
id="other.lowPowerMode"
class="form-check-input"
/>
<label
for="other.lowPowerMode"
class="form-label"
>Low power mode</label
>
</div>
</div>
<div class="col-12 mt-3">
<label
for="other.lowVoltageCutOff"
class="form-label"
>Low voltage cut off <small>(Deep sleep below specific voltage)</small></label
>
<input
type="text"
name="other.lowVoltageCutOff"
id="other.lowVoltageCutOff"
placeholder="0"
min="0"
step="0.01"
class="form-control"
/>
<div class="form-text">
MCU will deep sleep when below provided battery voltage to save power. Set to <strong>0</strong> if you don't want this option. <u>Please calibrate your voltage reading first!</u>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
<footer

View file

@ -213,6 +213,10 @@ function loadSettings(settings) {
settings.lora.codingRate4;
document.getElementById("lora.power").value = settings.lora.power;
// Experimental
document.getElementById("other.lowPowerMode").checked = settings.other.lowPowerMode;
document.getElementById("other.lowVoltageCutOff").value = settings.other.lowVoltageCutOff || 0
updateImage();
refreshSpeedStandard();
toggleFields();

View file

@ -136,11 +136,11 @@ build_flags =
-DHAS_SX126X
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1
[env:heltec_wireless_stick_lite]
[env:heltec_ht-ct62]
board = heltec_wireless_stick_lite
board_build.mcu = esp32c3
build_flags =
-Werror -Wall
-DHELTEC_WSL
-DHELTEC_HTCT62
-DHAS_SX126X
-DELEGANTOTA_USE_ASYNC_WEBSERVER=1

View file

@ -58,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) || defined(HELTEC_WSL)
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_HTCT62)
pinMode(batteryPin, INPUT);
#endif
#ifdef HAS_INTERNAL_LED
@ -75,13 +75,71 @@ void setup() {
Config.check();
WIFI_Utils::setup();
LoRa_Utils::setup();
Utils::validateFreqs();
iGateBeaconPacket = GPS_Utils::generateBeacon();
iGateLoRaBeaconPacket = GPS_Utils::generateiGateLoRaBeacon();
#ifdef HELTEC_HTCT62
if (Config.lowPowerMode) {
gpio_wakeup_enable(GPIO_NUM_3, GPIO_INTR_HIGH_LEVEL);
esp_deep_sleep_enable_gpio_wakeup(GPIO_NUM_3, ESP_GPIO_WAKEUP_GPIO_HIGH);
long lastBeacon = 0;
LoRa_Utils::startReceive();
while (true) {
auto wakeup_reason = esp_sleep_get_wakeup_cause();
if (wakeup_reason == 7) { // packet received
Serial.println("Received packet");
String packet = LoRa_Utils::receivePacket();
Serial.println(packet);
if (Config.digi.mode == 2) { // If Digi enabled
DIGI_Utils::loop(packet); // Send received packet to Digi
}
if (packet.indexOf(Config.callsign + ":STOP{") != -1) {
Serial.println("Got STOP message, exiting from low power mode");
break;
};
}
long time = esp_timer_get_time() / 1000000;
if (lastBeacon == 0 || time - lastBeacon >= Config.beacon.interval * 60) {
Serial.println("Sending beacon");
LoRa_Utils::sendNewPacket("APRS", iGateLoRaBeaconPacket + Config.beacon.comment + " Batt=" + String(BATTERY_Utils::checkBattery(),2) + "V");
lastBeacon = time;
}
LoRa_Utils::startReceive();
Serial.println("Sleeping");
long sleep = (Config.beacon.interval * 60) - (time - lastBeacon);
Serial.flush();
esp_sleep_enable_timer_wakeup(sleep * 1000000);
esp_light_sleep_start();
Serial.println("Waked up");
}
Config.loramodule.rxActive = false;
}
#endif
WIFI_Utils::setup();
SYSLOG_Utils::setup();
BME_Utils::setup();
WEB_Utils::setup();
@ -96,7 +154,9 @@ void loop() {
return; // Don't process IGate and Digi during OTA update
}
BATTERY_Utils::checkIfShouldSleep();
if (Config.lowVoltageCutOff > 0) {
BATTERY_Utils::checkIfShouldSleep();
}
thirdLine = Utils::getLocalIP();

View file

@ -1,12 +1,6 @@
#include "battery_utils.h"
#include "configuration.h"
#include "pins_config.h"
//#include "lora_utils.h"
// Uncomment if you want to monitor voltage and sleep if voltage is too low (<3.15V)
//#define LOW_VOLTAGE_CUTOFF
float cutOffVoltage = 3.15;
extern Configuration Config;
extern uint32_t lastBatteryCheck;
@ -31,7 +25,7 @@ namespace BATTERY_Utils {
int sample;
int sampleSum = 0;
for (int i = 0; i < 100; i++) {
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_WSL)
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_HTCT62)
sample = analogRead(batteryPin);
#endif
#if defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
@ -65,24 +59,15 @@ namespace BATTERY_Utils {
}
void checkIfShouldSleep() {
#ifdef LOW_VOLTAGE_CUTOFF
if (lastBatteryCheck == 0 || millis() - lastBatteryCheck >= 15 * 60 * 1000) {
lastBatteryCheck = millis();
float voltage = checkBattery();
if (voltage < cutOffVoltage) {
/* Send message over APRS-IS or over LoRa???
APRS_IS_Utils::upload("battery is low = sleeping")
LoRa_Utils::sendNewMessage("battery is low = sleeping");
*/
if (voltage < Config.lowVoltageCutOff) {
ESP.deepSleep(1800000000); // 30 min sleep (60s = 60e6)
}
}
#endif
}
}

View file

@ -96,6 +96,9 @@ void Configuration::writeFile() {
data["ota"]["username"] = ota.username;
data["ota"]["password"] = ota.password;
data["other"]["lowPowerMode"] = lowPowerMode;
data["other"]["lowVoltageCutOff"] = lowVoltageCutOff;
serializeJson(data, configFile);
configFile.close();
@ -160,6 +163,9 @@ bool Configuration::readFile() {
tnc.enableSerial = data["tnc"]["enableSerial"].as<bool>();
tnc.acceptOwn = data["tnc"]["acceptOwn"].as<bool>();
lowPowerMode = data["other"]["lowPowerMode"].as<bool>();
lowVoltageCutOff = data["other"]["lowVoltageCutOff"].as<double>();
int stationMode = data["stationMode"].as<int>(); // deprecated but need to specify config version
if (stationMode == 0) {
@ -331,6 +337,9 @@ void Configuration::init() {
externalVoltageMeasurement = false;
externalVoltagePin = 34;
lowPowerMode = false;
lowVoltageCutOff = 0;
Serial.println("todo escrito");
}

View file

@ -114,6 +114,8 @@ public:
bool sendBatteryVoltage;
bool externalVoltageMeasurement;
int externalVoltagePin;
bool lowPowerMode;
double lowVoltageCutOff;
std::vector<WiFi_AP> wifiAPs;
WiFi_Auto_AP wifiAutoAP;
Beacon beacon; // new

View file

@ -61,6 +61,7 @@ namespace DIGI_Utils {
String loraPacket, Sender, AddresseeAndMessage, Addressee;
if (packet != "") {
if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("NOGATE") == -1)) {
Sender = packet.substring(3, packet.indexOf(">"));
if (Sender != Config.callsign) {
String sender = packet.substring(3, packet.indexOf(">"));
STATION_Utils::updateLastHeard(sender);

View file

@ -10,7 +10,7 @@
extern Configuration Config;
#if defined(HELTEC_V3) || defined(HELTEC_WS) || defined(TTGO_T_Beam_V1_2_SX1262) || defined(HELTEC_WSL)
#if defined(HELTEC_V3) || defined(HELTEC_WS) || defined(TTGO_T_Beam_V1_2_SX1262) || defined(HELTEC_HTCT62)
SX1262 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
bool transmissionFlag = true;
bool enableInterrupt = true;
@ -63,7 +63,11 @@ namespace LoRa_Utils {
Serial.println("Starting LoRa failed!");
while (true);
}
radio.setDio1Action(setFlag);
if (!Config.lowPowerMode) {
radio.setDio1Action(setFlag);
} else {
radio.setDIOMapping(1, RADIOLIB_SX126X_IRQ_RX_DONE);
}
radio.setSpreadingFactor(Config.loramodule.spreadingFactor);
float signalBandwidth = Config.loramodule.signalBandwidth/1000;
radio.setBandwidth(signalBandwidth);
@ -178,6 +182,12 @@ namespace LoRa_Utils {
return packet;
}
void startReceive() {
#ifdef HAS_SX126X
radio.startReceive();
#endif
}
String receivePacket() {
String loraPacket = "";
#ifdef HAS_SX127X
@ -205,7 +215,7 @@ namespace LoRa_Utils {
return loraPacket;
#endif
#ifdef HAS_SX126X
if (transmissionFlag) {
if (transmissionFlag || Config.lowPowerMode) {
transmissionFlag = false;
radio.startReceive();
int state = radio.readData(loraPacket);

View file

@ -13,6 +13,7 @@ namespace LoRa_Utils {
String receivePacket();
void changeFreqTx();
void changeFreqRx();
void startReceive();
}

View file

@ -64,7 +64,7 @@
#define RADIO_TXEN 13
#endif
#ifdef HELTEC_WSL
#ifdef HELTEC_HTCT62
#define RADIO_SCLK_PIN 10 // SX1262 SCK
#define RADIO_MISO_PIN 6 // SX1262 MISO
#define RADIO_MOSI_PIN 7 // SX1262 MOSI
@ -94,7 +94,7 @@
#define OLED_RST 21
#endif
#ifndef HELTEC_WSL
#ifndef HELTEC_HTCT62
#define HAS_DISPLAY
#endif
@ -104,7 +104,7 @@
#define HAS_INTERNAL_LED
#endif
#ifdef HELTEC_WSL
#ifdef HELTEC_HTCT62
#define batteryPin 1
#endif
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2)

View file

@ -115,7 +115,7 @@ namespace Utils {
secondaryBeaconPacket = iGateLoRaBeaconPacket + Config.beacon.comment;
}
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_WSL)
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_HTCT62)
if (Config.sendBatteryVoltage) {
beaconPacket += " Batt=" + String(BATTERY_Utils::checkBattery(),2) + "V";
secondaryBeaconPacket += " Batt=" + String(BATTERY_Utils::checkBattery(),2) + "V";

View file

@ -155,6 +155,9 @@ namespace WEB_Utils {
Config.externalVoltagePin = request->getParam("other.externalVoltagePin", true)->value().toInt();
}
Config.lowPowerMode = request->hasParam("other.lowPowerMode", true);
Config.lowVoltageCutOff = request->getParam("other.lowVoltageCutOff", true)->value().toDouble();
Config.writeFile();
AsyncWebServerResponse *response = request->beginResponse(302, "text/html", "");