pull/24/head
Łukasz Nidecki 2021-03-22 18:35:01 +01:00
commit 725794ac23
18 zmienionych plików z 465 dodań i 147 usunięć

Wyświetl plik

@ -20,24 +20,22 @@
<article>
<form action="/save_wifi_cfg" method="post">
<div class="grid-container quarters">
<div>
<div id="wifi_list">
</div>
<div id="wifi_list">
<label for="wifi_ssid">Network</label>
<input type="button" value="Scan WiFi" id="scan_wifi_btn" onclick="scanWifi();">
</div>
<div>
<label for="wifi_ssid">SSID</label>
<input class="u-full-width" type="text" name="wifi_ssid" placeholder="Your Wifi SSID"
id="wifi_ssid">
<input class="u-full-width" type="text" name="wifi_ssid" placeholder="Your Wifi SSID" id="wifi_ssid">
</div>
<div>
<label for="wifi_password">Password</label>
<input class="u-full-width" type="password" name="wifi_password" id="wifi_password">
</div>
<div>
<input class="button-primary" type="submit" value="Save">
</div>
</div>
<div class="grid-container full">
<input class="button-primary" type="submit" value="Save">
</div>
</form>
</article>
</section>
@ -50,64 +48,117 @@
<div class="grid-container quarters">
<div>
<label for="aprs_callsign">Callsign and SSID</label>
<input class="u-full-width" type="text" minlength="3" name="aprs_callsign"
placeholder="NOCALL-1" id="aprs_callsign">
<input class="u-full-width" type="text" minlength="3" name="aprs_callsign" placeholder="NOCALL-1" id="aprs_callsign" title="your callsign with SSID">
</div>
<div>
<label for="aprs_relay_path">Relay Path</label>
<input class="u-full-width" type="text" minlength="0" name="aprs_relay_path"
id="aprs_relay_path">
<input class="u-full-width" type="text" minlength="0" name="aprs_relay_path" id="aprs_relay_path" title="APRS path, use the shortest as possible, ECHO or WIDE1-1">
</div>
<div>
<label for="aprs_s_table">Symbol Table</label>
<input class="u-full-width" type="text" minlength="1" maxlength="1" name="aprs_s_table"
id="aprs_s_table">
<input class="u-full-width" type="text" minlength="1" maxlength="1" name="aprs_s_table" id="aprs_s_table" title="use primary / or secondary table \ ">
</div>
<div>
<label for="aprs_symbol">Symbol</label>
<input class="u-full-width" type="text" minlength="1" maxlength="1" name="aprs_symbol"
id="aprs_symbol">
</div>
<div>
<label for="aprs_comment">Comment</label>
<input class="u-full-width" type="text" minlength="0" maxlength="64" name="aprs_comment"
id="aprs_comment">
</div>
<div>
<label for="aprs_batt">Show Battery</label>
<input name="aprs_batt" id="aprs_batt" type="checkbox" value="1">
<input class="u-full-width" type="text" minlength="1" maxlength="1" name="aprs_symbol" id="aprs_symbol" title="select an icon, for example: [ - jogger, Y - jacht, > - car, b - bike ">
</div>
<div>
<label for="aprs_alt">Show Altitude</label>
<input name="aprs_alt" id="aprs_alt" type="checkbox" value="1">
<input name="aprs_alt" id="aprs_alt" type="checkbox" value="1" title=" show altitude as frame part">
</div>
<div>
<label for="show_cmt">Show Comment</label>
<input name="show_cmt" id="show_cmt" type="checkbox" value="1" title=" show comment text">
</div>
<div>
<label for="aprs_comment">Comment</label>
<input class="u-full-width" type="text" minlength="0" maxlength="64" name="aprs_comment" id="aprs_comment" title=" personal comment">
</div>
<div>
<label for="aprs_batt">Show Battery</label>
<input name="aprs_batt" id="aprs_batt" type="checkbox" value="1" title=" show battery voltage after personal comment">
</div>
</div>
<div class="grid-container quarters">
<div>
<label for="aprs_fixed_beac">Fixed Beacon (when&nbsp;no&nbsp;GPS)</label>
<input name="aprs_fixed_beac" id="aprs_fixed_beac" type="checkbox" value="1">
<label for="aprs_fixed_beac">Fixed Beacon</label>
<input name="aprs_fixed_beac" id="aprs_fixed_beac" type="checkbox" value="1" title="enable fixed beacon when GPS is disabled or no fix">
</div>
<div>
<label for="aprs_fb_interv">Fixed Beacon Interval (s)</label>
<input name="aprs_fb_interv" id="aprs_fb_interv" type="number" min="120">
<input name="aprs_fb_interv" id="aprs_fb_interv" type="number" min="120" title="time between sending a beacon if Fixed Beacon option is selected ">
</div>
<div>
<label for="aprs_lat_p">Latitude Preset</label>
<input class="u-full-width" type="text" minlength="0" name="aprs_lat_p" id="aprs_lat_p">
<input class="u-full-width" type="text" minlength="0" name="aprs_lat_p" id="aprs_lat_p" title="latitude for fixed bicon, APRS format for example: 5215.0N">
</div>
<div>
<label for="aprs_lon_p">Longitude Preset</label>
<input class="u-full-width" type="text" minlength="0" name="aprs_lon_p" id="aprs_lon_p">
<input class="u-full-width" type="text" minlength="0" name="aprs_lon_p" id="aprs_lon_p" title="longtitude for fixed bicon, APRS format for example 02050.59E">
</div>
</div>
<div class="grid-container quarters">
<div>
<label for="gps_enabled">GPS enabled</label>
<input name="gps_enabled" id="gps_enabled" type="checkbox" value="1" title="enable or disable GPS">
</div>
</div>
<div class="grid-container full">
<div>
<input class="button-primary u-full-width" type="submit" value="Save">
<input class="button-primary u-full-width" type="submit" value="Save" title="save settings, remember reboot tracker after save">
</div>
</div>
</form>
</article>
</section>
<section>
<article>
<form action="/save_device_cfg" method="post">
<div class="grid-container full">
<h2 class="u-full-width">Device Settings</h2>
</div>
<div class="grid-container quarters">
<div>
<label for="oled_enabled">Display dimmer enabled</label>
<input name="oled_enabled" id="oled_enabled" type="checkbox" value="1" title="enable or disable oled dimmer">
</div>
<div>
<label for="bt_enabled">Bluetooth enabled</label>
<input name="bt_enabled" id="bt_enabled" type="checkbox" value="1" title="enable or disable bluetooth">
</div>
<div>
<label for="led_enable">LED signaling</label>
<input name="led_enable" id="led_enable" type="checkbox" value="1" title="enable or disable LED" DISABLED>
</div>
<div>
<label for="shutdown_act">Auto power off</label>
<input name="shutdown_act" id="shutdown_act" type="checkbox" value="1" title="activate auto shutdown after usb plug off">
</div>
</div>
<div class="grid-container quarters">
<div>
<label for="sh_rxtime">Display show RX time (s)</label>
<input name="sh_rxtime" id="sh_rxtime" type="number" min="1" max="45" title="show RX packet for seconds">
</div>
<div>
</div>
<div>
</div>
<div>
<label for="shutdown_dt">Auto power off delay (s)</label>
<input name="shutdown_dt" id="shutdown_dt" type="number" min="3" max="3600" title="auto shutdown delay in seconds">
</div>
</div>
<div class="grid-container full">
<div>
<input class="button-primary u-full-width" type="submit" value="Save" title="save settings, remember reboot tracker after save">
</div>
</div>
</form>
</article>
</section>
<section>
<div class="grid-container full">
<h2 class="u-full-width">Actions</h2>
@ -146,7 +197,7 @@
</section>
</div>
<footer>
<center><b>Contributors in order of appearance:</b> OE1ACM, OE3CJB, SQ9MDD, SQ5RWU, DJ1AN</center>
<center><b>Contributors in order of appearance:</b> OE1ACM, OE3CJB, SQ9MDD, SQ5RWU, DJ1AN, M0IGA, SQ5WPR</center>
<center><b>Latest stable version:</b> <a href=https://github.com/SQ9MDD/TTGO-T-Beam-LoRa-APRS>https://github.com/SQ9MDD/TTGO-T-Beam-LoRa-APRS</a></center>
<center><b>Licensed under:</b> CC BY-NC-SA</center>
<center><!--VERSION--></center>

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 124 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 116 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 128 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 114 KiB

Wyświetl plik

@ -38,6 +38,20 @@ static const char *const PREF_APRS_FIXED_BEACON_PRESET = "aprs_fixed_beac";
static const char *const PREF_APRS_FIXED_BEACON_PRESET_INIT = "aprs_fix_b_init";
static const char *const PREF_APRS_FIXED_BEACON_INTERVAL_PRESET = "aprs_fb_interv";
static const char *const PREF_APRS_FIXED_BEACON_INTERVAL_PRESET_INIT = "aprs_fb_in_init";
static const char *const PREF_APRS_GPS_EN = "gps_enabled";
static const char *const PREF_APRS_GPS_EN_INIT = "gps_state_init";
static const char *const PREF_APRS_SHOW_CMT = "show_cmt";
static const char *const PREF_APRS_SHOW_CMT_INIT = "show_cmt_init";
static const char *const PREF_DEV_BT_EN = "bt_enabled";
static const char *const PREF_DEV_BT_EN_INIT = "bt_enabled_init";
static const char *const PREF_DEV_OL_EN = "oled_enabled";
static const char *const PREF_DEV_OL_EN_INIT = "ol_enabled_init";
static const char *const PREF_DEV_SHOW_RX_TIME = "sh_rxtime";
static const char *const PREF_DEV_SHOW_RX_TIME_INIT = "sh_rxtime_init";
static const char *const PREF_DEV_AUTO_SHUT = "shutdown_act";
static const char *const PREF_DEV_AUTO_SHUT_INIT = "shutdown_actini";
static const char *const PREF_DEV_AUTO_SHUT_PRESET = "shutdown_dt";
static const char *const PREF_DEV_AUTO_SHUT_PRESET_INIT = "shutdown_dtini";
typedef struct {
String callsign;

Wyświetl plik

@ -23,6 +23,8 @@ PROGMEM static const BG_RF95::ModemConfig MODEM_CONFIG_TABLE[] =
{ 0x48, 0x94, 0x00}, // Bw31_25Cr48Sf512
{ 0x78, 0xc4, 0x00}, // Bw125Cr48Sf4096
{ 0x72, 0xc7, 0x8}, // BG 125 cr45 sf12
{ 0x72, 0xb4, 0x00}, // Bw125Cr45Sf2048
{ 0x88, 0xc4, 0x00}, // Bw250Cr48Sf4096
};
BG_RF95::BG_RF95(uint8_t slaveSelectPin, uint8_t interruptPin, RHGenericSPI& spi)
@ -112,7 +114,7 @@ bool BG_RF95::init()
// setModemConfig(Bw125Cr48Sf4096); // slow and reliable?
setPreambleLength(8); // Default is 8
// An innocuous ISM frequency, same as RF22's
setFrequency(433.800);
setFrequency(433.850);
// Lowish power
setTxPower(20);

Wyświetl plik

@ -183,15 +183,15 @@
// BG_RF95_REG_1D_MODEM_CONFIG1 0x1d
#define BG_RF95_BW 0xc0
#define BG_RF95_BW_125KHZ 0x00
#define BG_RF95_BW_250KHZ 0x40
#define BG_RF95_BW_500KHZ 0x80
#define BG_RF95_BW_125KHZ 0x70
#define BG_RF95_BW_250KHZ 0x80
#define BG_RF95_BW_500KHZ 0x90
#define BG_RF95_BW_RESERVED 0xc0
#define BG_RF95_CODING_RATE 0x38
#define BG_RF95_CODING_RATE_4_5 0x00
#define BG_RF95_CODING_RATE_4_6 0x08
#define BG_RF95_CODING_RATE_4_7 0x10
#define BG_RF95_CODING_RATE_4_8 0x18
#define BG_RF95_CODING_RATE_4_5 0x02
#define BG_RF95_CODING_RATE_4_6 0x04
#define BG_RF95_CODING_RATE_4_7 0x06
#define BG_RF95_CODING_RATE_4_8 0x08
#define BG_RF95_IMPLICIT_HEADER_MODE_ON 0x04
#define BG_RF95_RX_PAYLOAD_CRC_ON 0x02
#define BG_RF95_LOW_DATA_RATE_OPTIMIZE 0x01
@ -547,6 +547,8 @@ public:
Bw31_25Cr48Sf512, ///< Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range
Bw125Cr48Sf4096, ///< Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. Slow+long range
Bw125Cr45Sf4096, ///< APRS
Bw125Cr45Sf2048, ///<Bw = 125 kHz Cr = 4/5, Sf= 2048 chips/symbol, CRC on.
Bw250Cr48Sf4096, ///< Bw = 250 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on.
} ModemConfigChoice;
/// Constructor. You can have multiple instances, but each instance must have its own

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -9,9 +9,8 @@
; https://docs.platformio.org/page/projectconf.html
[env]
platform = espressif32 @ 3.0.0
platform = espressif32 @ 3.1.1
framework = arduino
monitor_speed = 115200
build_flags = -Wl,--gc-sections,--relax
board_build.partitions = partitions.csv
@ -29,17 +28,32 @@ lib_deps =
Adafruit GFX Library
Adafruit Unified Sensor
AXP202X_Library
SparkFun u-blox Arduino Library
[env:ttgo-t-beam-v1.0]
board = ttgo-t-beam
build_flags = ${env.build_flags} -DT_BEAM_V1_0
build_flags = ${env.build_flags} -D T_BEAM_V1_0
[env:ttgo-t-beam-v0.7]
board = ttgo-t-beam
build_flags = ${env.build_flags} -DT_BEAM_V0_7
build_flags = ${env.build_flags} -D T_BEAM_V0_7
[env:ttgo-lora32-v2.1]
board = ttgo-lora32-v21
build_flags = ${env.build_flags} -D LORA32_21
[env:ttgo-lora32-v2]
board = ttgo-lora32-v1
board = ttgo-lora32-v2
build_flags = ${env.build_flags} -D LORA32_2
[env:ttgo-lora32-v1]
board = ttgo-lora32-v1
board = ttgo-lora32-v1
build_flags = ${env.build_flags} -D LORA32_1
[env:Heltec-WiFi-v1]
board = heltec_wifi_kit_32
build_flags = ${env.build_flags} -D HELTEC_V1
[env:Heltec-WiFi-v2]
board = heltec_wifi_kit_32_v2
build_flags = ${env.build_flags} -D HELTEC_V2

Wyświetl plik

@ -22,41 +22,64 @@
#include <gfxfont.h>
#include <axp20x.h>
#include "taskGPS.h"
#include "version.h"
#ifdef KISS_PROTOCOL
#include "taskTNC.h"
#endif
#ifdef ENABLE_WIFI
#include "taskWebServer.h"
#endif
#include "version.h"
// I2C LINES
#define I2C_SDA 21
#define I2C_SCL 22
// DISPLAY address
#define SSD1306_ADDRESS 0x3C
// LED for signalling
// IO config
#ifdef T_BEAM_V1_0
const byte TXLED = 4; //pin number for LED on TX Tracker
#else
const byte TXLED = 14; //pin number for LED on TX Tracker
#endif
// Button of TTGO T-Beam
#ifdef T_BEAM_V1_0
#define BUTTON 38 //pin number for Button on TTGO T-Beam
#else
#define BUTTON 39 //pin number for Button on TTGO T-Beam
#define I2C_SDA 21
#define I2C_SCL 22
#define BUTTON 38 //pin number for Button on TTGO T-Beam
#define BUZZER 15 // enter your buzzer pin gpio
const byte TXLED = 4; //pin number for LED on TX Tracker
#endif
#ifdef T_BEAM_V0_7
#define I2C_SDA 21
#define I2C_SCL 22
#define BUTTON 39 //pin number for Button on TTGO T-Beam
#define BUZZER 15 // enter your buzzer pin gpio
const byte TXLED = 4; //pin number for LED on TX Tracker
#elif LORA32_21
#define I2C_SDA 4
#define I2C_SCL 15
#define BUTTON 2 //pin number for BUTTO
#define BUZZER 13 // enter your buzzer pin gpio
const byte TXLED = 4; //pin number for LED on TX Tracker
#elif LORA32_2
#define I2C_SDA 21
#define I2C_SCL 22
#define BUTTON 2 //pin number for BUTTO
#define BUZZER 13 // enter your buzzer pin gpio
const byte TXLED = 4; //pin number for LED on TX Tracker
#elif LORA32_1
#define I2C_SDA 21
#define I2C_SCL 22
#define BUTTON 2 //pin number for BUTTO
#define BUZZER 13 // enter your buzzer pin gpio
const byte TXLED = 4; //pin number for LED on TX Tracker
#elif HELTEC_V1
#define I2C_SDA 4
#define I2C_SCL 15
#define BUTTON 2 //pin number for BUTTO
#define BUZZER 13 // enter your buzzer pin gpio
const byte TXLED = 4; //pin number for LED on TX Tracker
#elif HELTEC_V2
#define I2C_SDA 4
#define I2C_SCL 15
#define BUTTON 2 //pin number for BUTTO
#define BUZZER 13 // enter your buzzer pin gpio
const byte TXLED = 4; //pin number for LED on TX Tracker
#endif
// Pins for LoRa module
const byte lora_PReset = 23; //pin where LoRa device reset line is connected
const byte lora_PNSS = 18; //pin number where the NSS line for the LoRa device is connected.
// Variables for APRS packaging
String Tcall; //your Call Sign for normal position reports
String Tcall; //your Call Sign for normal position reports
String aprsSymbolTable = APRS_SYMBOL_TABLE;
String aprsSymbol = APRS_SYMBOL;
String relay_path;
@ -67,6 +90,8 @@ boolean gps_state = true;
boolean key_up = true;
boolean t_lock = false;
boolean fixed_beacon_enabled = false;
boolean show_cmt = true;
#ifdef SHOW_ALT
boolean showAltitude = true;
#else
@ -77,6 +102,16 @@ boolean fixed_beacon_enabled = false;
#else
boolean showBattery = false;
#endif
#ifdef ENABLE_BLUETOOTH
boolean enable_bluetooth = true;
#else
boolean enable_bluetooth = false;
#endif
#ifdef ENABLE_OLED
boolean enabled_oled = true;
#else
boolean enabled_oled = false;
#endif
// Variables and Constants
String loraReceivedFrameString = ""; //data on buff is copied to this string
@ -107,6 +142,7 @@ byte lora_TXPacketL; //length of packet to send, includes source, destin
unsigned long lastTX = 0L;
float BattVolts;
float InpVolts;
// variables for smart beaconing
float average_speed[5] = {0,0,0,0,0}, average_speed_final=0, max_speed=30, min_speed=0;
@ -120,6 +156,12 @@ ulong next_fixed_beacon = 0;
ulong fix_beacon_interval = FIX_BEACON_INTERVAL;
ulong showRXTime = SHOW_RX_TIME;
ulong time_delay = 0;
ulong shutdown_delay = 0;
ulong shutdown_delay_time = 10000;
ulong shutdown_countdown_timer = 0;
boolean shutdown_active =true;
boolean shutdown_countdown_timer_enable = false;
boolean shutdown_usb_status_bef = false;
#define ANGLE 60 // angle to send packet at smart beaconing
#define ANGLE_AVGS 3 // angle averaging - x times
float average_course[ANGLE_AVGS];
@ -130,7 +172,6 @@ uint8_t txPower = TXdbmW;
tWebServerCfg webServerCfg;
#endif
static const adc_atten_t atten = ADC_ATTEN_DB_6;
static const adc_unit_t unit = ADC_UNIT_1;
#ifdef T_BEAM_V1_0
@ -141,7 +182,7 @@ static const adc_unit_t unit = ADC_UNIT_1;
uint8_t loraReceivedLength = sizeof(lora_RXBUFF);
// Singleton instance of the radio driver
BG_RF95 rf95(18, 26); // TTGO T-Beam has NSS @ Pin 18 and Interrupt IO @ Pin26
BG_RF95 rf95(18, 26); // TTGO T-Beam has NSS @ Pin 18 and Interrupt IO @ Pin26
// initialize OLED display
#define OLED_RESET 16 // not used
@ -177,11 +218,11 @@ void prepareAPRSFrame(){
Tcourse=gps.course.deg();
Tspeed=gps.speed.knots();
if(Tlat<0) { Ns = "S"; } else { Ns = "N"; }
if(Tlon<0) { Ew = "W"; } else { Ew = "E"; }
if(Tlat < 0) { Tlat= -Tlat; }
//if(Tlat<0) { Ns = "S"; } else { Ns = "N"; }
//if(Tlon<0) { Ew = "W"; } else { Ew = "E"; }
//if(Tlat < 0) { Tlat= -Tlat; }
if(Tlon < 0) { Tlon= -Tlon; }
//if(Tlon < 0) { Tlon= -Tlon; }
aprs_lat = 900000000 - Tlat * 10000000;
aprs_lat = aprs_lat / 26 - aprs_lat / 2710 + aprs_lat / 15384615;
aprs_lon = 900000000 + Tlon * 10000000 / 2;
@ -191,9 +232,9 @@ void prepareAPRSFrame(){
outString += Tcall;
if (relay_path) {
outString += ">APLM0," + relay_path + ":!";
outString += ">APLS01," + relay_path + ":!";
} else {
outString += ">APLM0:!";
outString += ">APLS01:!";
}
if(gps_state && gps.location.isValid()) {
@ -227,8 +268,10 @@ void prepareAPRSFrame(){
outString += aprsLonPreset;
outString += aprsSymbol;
}
outString += aprsComment;
if(show_cmt){
outString += aprsComment;
}
if (showBattery) {
outString += " Batt=";
outString += String(BattVolts, 2);
@ -242,7 +285,28 @@ void prepareAPRSFrame(){
#endif
}
#ifdef BUZZER
/**
* Buzzer sound playback
* @param melody - must be an array. Consisting of an even number of values. frequency and duration
* @param array_size - number of elements in the array
*/
void buzzer(int* melody, int array_size){
for(int i=0; i<array_size; i+=2){
ledcWriteTone(0, *melody);
melody++;
delay(*melody);
melody++;
}
ledcWriteTone(0,0); // turn off buzzer
}
#endif
void sendpacket(){
#ifdef BUZZER
int melody[] = {1000, 50, 800, 100};
buzzer(melody, sizeof(melody)/sizeof(int));
#endif
batt_read();
prepareAPRSFrame();
loraSend(txPower, TXFREQ, outString); //send the packet, data is in TXbuff from lora_TXStart to lora_TXEnd
@ -255,7 +319,9 @@ void sendpacket(){
* @param message
*/
void loraSend(byte lora_LTXPower, float lora_FREQ, const String &message) {
digitalWrite(TXLED, LOW);
#ifdef ENABLE_LED_SIGNALING
digitalWrite(TXLED, LOW);
#endif
lastTX = millis();
int messageSize = min(message.length(), sizeof(lora_TXBUFF) - 1);
@ -265,12 +331,15 @@ void loraSend(byte lora_LTXPower, float lora_FREQ, const String &message) {
rf95.setTxPower(lora_LTXPower);
rf95.sendAPRS(lora_TXBUFF, messageSize);
rf95.waitPacketSent();
digitalWrite(TXLED, HIGH);
#ifdef ENABLE_LED_SIGNALING
digitalWrite(TXLED, HIGH);
#endif
}
void batt_read(){
#ifdef T_BEAM_V1_0
BattVolts = axp.getBattVoltage()/1000;
InpVolts = axp.getVbusVoltage()/1000;
#else
BattVolts = analogRead(35)*7.221/4096;
#endif
@ -280,7 +349,9 @@ void writedisplaytext(String HeaderTxt, String Line1, String Line2, String Line3
batt_read();
if (BattVolts < 3.5 && BattVolts > 3.2){
#ifdef T_BEAM_V1_0
# ifdef ENABLE_LED_SIGNALING
axp.setChgLEDMode(AXP20X_LED_BLINK_4HZ);
#endif
#endif
}
display.clearDisplay();
@ -299,6 +370,13 @@ void writedisplaytext(String HeaderTxt, String Line1, String Line2, String Line3
display.println(Line4);
display.setCursor(0,56);
display.println(Line5);
if (enabled_oled){
//axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON); // enable oled
display.dim(true);
}else{
//axp.setPowerOutPut(AXP192_DCDC1, AXP202_OFF); // disable oled
display.dim(false);
}
display.display();
time_to_refresh = millis() + showRXTime;
}
@ -307,9 +385,18 @@ void writedisplaytext(String HeaderTxt, String Line1, String Line2, String Line3
String getSatAndBatInfo() {
String line5;
if(gps_state == true){
line5 = "SAT: " + String(gps.satellites.value()) + " BAT: " + String(BattVolts, 1) + "V";
if(InpVolts > 4){
line5 = "SAT: " + String(gps.satellites.value()) + " BAT: " + String(BattVolts, 1) + "V *";
}else{
line5 = "SAT: " + String(gps.satellites.value()) + " BAT: " + String(BattVolts, 1) + "V";
}
}else{
line5 = "SAT: X BAT: " + String(BattVolts, 1) + "V";
if(InpVolts > 4){
line5 = "SAT: X BAT: " + String(BattVolts, 1) + "V *";
}else{
line5 = "SAT: X BAT: " + String(BattVolts, 1) + "V";
}
}
#if defined(ENABLE_BLUETOOTH) && defined(KISS_PROTOCOL)
if (SerialBT.hasClient()){
@ -363,7 +450,7 @@ void sendTelemetryFrame() {
String telemetryEquations = String(":") + Tcall + ":EQNS.0,5.1,3000,0,10,0,0,10,0,0,28,3000,0,10,0";
String telemetryData = String("T#MIC") + String(b_volt) + ","+ String(b_in_c) + ","+ String(b_out_c) + ","+ String(ac_volt) + ","+ String(ac_c) + ",00000000";
String telemetryBase = "";
telemetryBase += Tcall + ">APLM0" + ":";
telemetryBase += Tcall + ">APLS01" + ":";
sendToTNC(telemetryBase + telemetryParamsNames);
sendToTNC(telemetryBase + telemetryUnitNames);
sendToTNC(telemetryBase + telemetryEquations);
@ -375,6 +462,12 @@ void sendTelemetryFrame() {
// + SETUP --------------------------------------------------------------+//
void setup(){
#ifdef BUZZER
ledcSetup(0,1E5,12);
ledcAttachPin(BUZZER,0);
ledcWriteTone(0,0); // turn off buzzer on start
#endif
#ifdef DIGI_PATH
relay_path = DIGI_PATH;
#else
@ -422,6 +515,12 @@ void setup(){
}
showAltitude = preferences.getBool(PREF_APRS_SHOW_ALTITUDE);
if (!preferences.getBool(PREF_APRS_GPS_EN_INIT)){
preferences.putBool(PREF_APRS_GPS_EN_INIT, true);
preferences.putBool(PREF_APRS_GPS_EN, gps_state);
}
gps_state = preferences.getBool(PREF_APRS_GPS_EN);
if (!preferences.getBool(PREF_APRS_SHOW_BATTERY_INIT)){
preferences.putBool(PREF_APRS_SHOW_BATTERY_INIT, true);
preferences.putBool(PREF_APRS_SHOW_BATTERY, showBattery);
@ -446,18 +545,55 @@ void setup(){
}
fixed_beacon_enabled = preferences.getBool(PREF_APRS_FIXED_BEACON_PRESET);
if (!preferences.getBool(PREF_APRS_FIXED_BEACON_INTERVAL_PRESET_INIT)){
preferences.putBool(PREF_APRS_FIXED_BEACON_INTERVAL_PRESET_INIT, true);
preferences.putInt(PREF_APRS_FIXED_BEACON_INTERVAL_PRESET, fix_beacon_interval/1000);
}
fix_beacon_interval = preferences.getInt(PREF_APRS_FIXED_BEACON_INTERVAL_PRESET) * 1000;
if (!preferences.getBool(PREF_DEV_SHOW_RX_TIME_INIT)){
preferences.putBool(PREF_DEV_SHOW_RX_TIME_INIT, true);
preferences.putInt(PREF_DEV_SHOW_RX_TIME, showRXTime/1000);
}
showRXTime = preferences.getInt(PREF_DEV_SHOW_RX_TIME) * 1000;
if (!preferences.getBool(PREF_DEV_AUTO_SHUT_PRESET_INIT)){
preferences.putBool(PREF_DEV_AUTO_SHUT_PRESET_INIT, true);
preferences.putInt(PREF_DEV_AUTO_SHUT_PRESET, shutdown_delay_time/1000);
}
shutdown_delay_time = preferences.getInt(PREF_DEV_AUTO_SHUT_PRESET) * 1000;
if (!preferences.getBool(PREF_DEV_AUTO_SHUT_INIT)){
preferences.putBool(PREF_DEV_AUTO_SHUT_INIT, true);
preferences.putBool(PREF_DEV_AUTO_SHUT, shutdown_active);
}
shutdown_active = preferences.getBool(PREF_DEV_AUTO_SHUT);
if (clear_preferences){
delay(1000);
if(digitalRead(BUTTON)==LOW){
clear_preferences = 2;
}
}
if (!preferences.getBool(PREF_APRS_SHOW_CMT_INIT)){
preferences.putBool(PREF_APRS_SHOW_CMT_INIT, true);
preferences.putBool(PREF_APRS_SHOW_CMT, show_cmt);
}
show_cmt = preferences.getBool(PREF_APRS_SHOW_CMT);
if (!preferences.getBool(PREF_DEV_BT_EN_INIT)){
preferences.putBool(PREF_DEV_BT_EN_INIT, true);
preferences.putBool(PREF_DEV_BT_EN, enable_bluetooth);
}
enable_bluetooth = preferences.getBool(PREF_DEV_BT_EN);
if (!preferences.getBool(PREF_DEV_OL_EN_INIT)){
preferences.putBool(PREF_DEV_OL_EN_INIT, true);
preferences.putBool(PREF_DEV_OL_EN,enabled_oled);
}
enabled_oled = preferences.getBool(PREF_DEV_OL_EN);
#endif
for (int i=0;i<ANGLE_AVGS;i++) { // set average_course to "0"
@ -465,7 +601,13 @@ void setup(){
}
pinMode(TXLED, OUTPUT);
pinMode(BUTTON, INPUT);
#ifdef T_BEAM_V1_0
pinMode(BUTTON, INPUT);
#elif T_BEAM_V0_7
pinMode(BUTTON, INPUT);
#else
pinMode(BUTTON, INPUT_PULLUP);
#endif
digitalWrite(TXLED, LOW); // turn blue LED off
Serial.begin(115200);
Wire.begin(I2C_SDA, I2C_SCL);
@ -473,35 +615,39 @@ void setup(){
#ifdef T_BEAM_V1_0
if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS)) {
}
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON);
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); // LoRa
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); // switch on GPS
axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON);
axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON);
axp.setDCDC1Voltage(3300);
// Enable ADC to measure battery current, USB voltage etc.
axp.adc1Enable(0xfe, true);
axp.adc2Enable(0x80, true);
axp.setChgLEDMode(AXP20X_LED_OFF);
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON); // oled do not turn off
#endif
if(!display.begin(SSD1306_SWITCHCAPVCC, SSD1306_ADDRESS)) {
for(;;); // Don't proceed, loop forever
}
#ifdef ENABLE_PREFERENCES
if (clear_preferences == 2){
writedisplaytext("LoRa-APRS","","","Factory reset","","");
delay(1000);
if(digitalRead(BUTTON)==LOW){
clear_preferences = 3;
preferences.clear();
preferences.end();
writedisplaytext("LoRa-APRS","","Factory reset","Done!","","");
delay(2000);
ESP.restart();
} else {
writedisplaytext("LoRa-APRS","","Factory reset","Cancel","","");
delay(2000);
}
//#ifdef T_BEAM_V1_0
if(digitalRead(BUTTON)==LOW){
clear_preferences = 3;
preferences.clear();
preferences.end();
writedisplaytext("LoRa-APRS","","Factory reset","Done!","","");
delay(2000);
ESP.restart();
} else {
writedisplaytext("LoRa-APRS","","Factory reset","Cancel","","");
delay(2000);
}
//#endif
}
#endif
writedisplaytext("LoRa-APRS","","Init:","Display OK!","","");
@ -541,16 +687,21 @@ void setup(){
xTaskCreatePinnedToCore(taskTNC, "taskTNC", 10000, nullptr, 1, nullptr, xPortGetCoreID());
#endif
#if defined(ENABLE_BLUETOOTH) && defined(KISS_PROTOCOL)
#ifdef BLUETOOTH_PIN
SerialBT.setPin(BLUETOOTH_PIN);
#endif
SerialBT.begin(String("TTGO LORA APRS ") + Tcall);
writedisplaytext("LoRa-APRS","","Init:","BT OK!","","");
#if defined(KISS_PROTOCOL)
if (enable_bluetooth){
#ifdef BLUETOOTH_PIN
SerialBT.setPin(BLUETOOTH_PIN);
#endif
#ifdef ENABLE_BLUETOOTH
SerialBT.begin(String("TTGO LORA APRS ") + Tcall);
writedisplaytext("LoRa-APRS","","Init:","BT OK!","","");
#endif
}
#endif
#ifdef ENABLE_WIFI
webServerCfg = {.callsign = Tcall};
xTaskCreate(taskWebServer, "taskWebServer", 40000, (void*)(&webServerCfg), 1, nullptr);
xTaskCreate(taskWebServer, "taskWebServer", 42000, (void*)(&webServerCfg), 1, nullptr);
writedisplaytext("LoRa-APRS","","Init:","WiFi task started"," =:-) ","");
#endif
@ -559,9 +710,6 @@ void setup(){
time_to_refresh = millis() + showRXTime;
displayInvalidGPS();
digitalWrite(TXLED, HIGH);
#ifdef T_BEAM_V1_0
axp.setChgLEDMode(AXP20X_LED_OFF);
#endif
}
// +---------------------------------------------------------------------+//
@ -597,6 +745,8 @@ void loop() {
#endif
writedisplaytext("((GPSOFF))","","","","","");
next_fixed_beacon = millis() + fix_beacon_interval;
preferences.putBool(PREF_APRS_GPS_EN_INIT, false);
preferences.putBool(PREF_APRS_GPS_EN, false);
}else{
gps_state = true;
@ -604,6 +754,8 @@ void loop() {
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON);
#endif
writedisplaytext("((GPS ON))","","","","",""); // GPS ON
preferences.putBool(PREF_APRS_GPS_EN_INIT, true);
preferences.putBool(PREF_APRS_GPS_EN, true);
}
}
@ -620,6 +772,29 @@ void loop() {
}
}
#ifdef T_BEAM_V1_0
if(shutdown_active){
if(InpVolts> 4){
shutdown_usb_status_bef = true;
shutdown_countdown_timer_enable = false;
}
if(InpVolts < 4 && shutdown_usb_status_bef == true){
shutdown_usb_status_bef = false;
shutdown_countdown_timer_enable = true;
shutdown_countdown_timer = millis() + shutdown_delay_time;
}
if(shutdown_countdown_timer_enable){
if(millis() >= shutdown_countdown_timer){
axp.shutdown();
}
}
}
#endif
#ifdef KISS_PROTOCOL
String *TNC2DataFrame = nullptr;
if (tncToSendQueue) {
@ -634,7 +809,13 @@ void loop() {
if (rf95.waitAvailableTimeout(100)) {
#ifdef T_BEAM_V1_0
axp.setChgLEDMode(AXP20X_LED_LOW_LEVEL);
#ifdef ENABLE_LED_SIGNALING
axp.setChgLEDMode(AXP20X_LED_LOW_LEVEL);
#endif
#endif
#ifdef BUZZER
int melody[] = {300, 50, 500, 100};
buzzer(melody, sizeof(melody)/sizeof(int));
#endif
#ifdef SHOW_RX_PACKET // only show RX packets when activitated in config
loraReceivedLength = sizeof(lora_RXBUFF); // reset max length before receiving!
@ -652,7 +833,9 @@ void loop() {
}
#endif
#ifdef T_BEAM_V1_0
axp.setChgLEDMode(AXP20X_LED_OFF);
#ifdef ENABLE_LED_SIGNALING
axp.setChgLEDMode(AXP20X_LED_OFF);
#endif
#endif
}

Wyświetl plik

@ -1,35 +1,44 @@
// Tracker for LoRA APRS
// from OE1ACM and OE3CJB redesigned by SQ9MDD
// KISS ans Bluetooth by SQ5RWU
// TTGO T-Beam v1.0 only
//
// licensed under CC BY-NC-SA
// USER DATA - USE THESE LINES TO MODIFY YOUR PREFERENCES
#define KISS_PROTOCOL // If enabled send and receive data in SIMPLE KISS format to serial port
#define CALLSIGN "NOCALL-0" // enter your callsign here - less then 6 letter callsigns please add "spaces" so total length is 6 (without SSID)
#define DIGI_PATH "WIDE1-1" // one hope please (WIDE1-1)
#define FIXED_BEACON_EN // allows cyclic sending of a bicon when GPS is turned off
#define LATIDUDE_PRESET "0000.00N" // please in APRS notation: DDMM.mmN or DDMM.mmS (used for manual or fixed beacon sending)
#define LONGITUDE_PRESET "00000.00E" // please in APRS notation: DDDMM.mmE or DDDMM.mmW (used for manual or fixed beacon sending)
#define APRS_SYMBOL_TABLE "/" // set primary or secondary symbols table
#define APRS_SYMBOL "[" // other symbols are: "[" => RUNNER, "b" => BICYCLE, "<" => MOTORCYCLE, "R" => Recreation Vehicle
#define MY_COMMENT "Lora Tracker" // add your coment here - if empty then no comment is sent max 64 bytes
//#define SHOW_ALT // send Altitude in frame
#define SHOW_BATT // send battery voltage at the end of comment (we need beggining for QSY message format)
#define SHOW_RX_PACKET // uncomment to show received LoRa APS packets for the time given below
#define SHOW_RX_TIME 10000 // show RX packet for milliseconds (5000 = 5secs)
#define TXFREQ 433.775 // Set transmit frequency in MHz
#define TXdbmW 20 // Set transmit power in dBm 17-50mW, 18-63mW, 19-80mW, 20-100mW
#define ENABLE_BLUETOOTH // bluetooth KISS interface enable
//#define BLUETOOTH_PIN "0000" // bluetooth pairing pin
//#define ENABLE_TNC_SELF_TELEMETRY //
//#define LOCAL_KISS_ECHO // echoing KISS frame back
//#define T_BEAM_V1_0 // if enabled t-beam v1.0 disabled t-beam V.0.7
//#define KISS_DEBUG //
#define ENABLE_WIFI // enable WiFi conection
#define NETWORK_TNC_PORT 8001 // Set KISS TCP Port
//#define ENABLE_WIFI_CLIENT_DEBUG //
#define MAX_TIME_TO_NEXT_TX 360000L // TRANSMIT INTERVAL set here MAXIMUM time in ms(!) for smart beaconing - minimum time is always 1 min = 60 secs = 60000L !!!
#define FIX_BEACON_INTERVAL 1800000L // Fixed beacon interwal (when GPS is disabled and FIXED_BEACON_EN is enabled) 30min default
#define TNC_SELF_TELEMETRY_INTERVAL (5 * 60 * 1000) //
// Please do not edit this file. !!!!!!!
// Configuration shuld be done via www. Default WiFi pasword for AP is: xxxxxxxxxx
#define KISS_PROTOCOL // If enabled send and receive data in SIMPLE KISS format to serial, bluetooth and tcp port
#define CALLSIGN "N0CALL-0" // this option is available via WWW // enter your callsign here - less then 6 letter callsigns please add "spaces" so total length is 6 (without SSID)
#define DIGI_PATH "ECHO" // this option is available via WWW // one hope, please use simple ECHO alias
#define FIXED_BEACON_EN // this option is available via WWW // allows cyclic sending of a bicon when GPS is turned off
#define LATIDUDE_PRESET "0000.00N" // this option is available via WWW // please in APRS notation: DDMM.mmN or DDMM.mmS (used for manual or fixed beacon sending)
#define LONGITUDE_PRESET "00000.00E" // this option is available via WWW // please in APRS notation: DDDMM.mmE or DDDMM.mmW (used for manual or fixed beacon sending)
#define APRS_SYMBOL_TABLE "/" // this option is available via WWW // set primary or secondary symbols table
#define APRS_SYMBOL "[" // this option is available via WWW // other symbols are: "[" => RUNNER, "b" => BICYCLE, "<" => MOTORCYCLE, "R" => Recreation Vehicle
#define MY_COMMENT "Lora Tracker" // this option is available via WWW // add your coment here - if empty then no comment is sent max 64 bytes
#define SHOW_ALT // this option is available via WWW // send Altitude in frame
#define SHOW_BATT // this option is available via WWW // send battery voltage at the end of comment (we need beggining for QSY message format)
#define SHOW_RX_PACKET // this option is available via WWW // uncomment to show received LoRa APS packets for the time given below
#define SHOW_RX_TIME 10000 // this option is available via WWW // show RX packet for milliseconds (5000 = 5secs)
#define TXFREQ 433.775 // Set transmit frequency in MHz
#define TXdbmW 20 // Set transmit power in dBm 17-50mW, 18-63mW, 19-80mW, 20-100mW
#define ENABLE_OLED // this option is available via WWW // enable oled
#define ENABLE_LED_SIGNALING // enable red and blue led signalling
//#define ENABLE_TNC_SELF_TELEMETRY //
// #define LOCAL_KISS_ECHO // echoing KISS frame back
//#define KISS_DEBUG //
#define NETWORK_TNC_PORT 8001 // Set KISS TCP Port
//#define ENABLE_WIFI_CLIENT_DEBUG //
#define MAX_TIME_TO_NEXT_TX 360000L // TRANSMIT INTERVAL set here MAXIMUM time in ms(!) for smart beaconing - minimum time is always 1 min = 60 secs = 60000L !!!
#define FIX_BEACON_INTERVAL 1800000L // Fixed beacon interwal (when GPS is disabled and FIXED_BEACON_EN is enabled) 30min default
//#define TNC_SELF_TELEMETRY_INTERVAL (5 * 60 * 1000) //
#ifdef T_BEAM_V1_0
#define ENABLE_WIFI // enable WiFi conection do not turn off
#define ENABLE_BLUETOOTH // if enabled here this option is available via WWW // bluetooth KISS interface enabl
//#define BLUETOOTH_PIN "0000" // bluetooth pairing pin
#elif T_BEAM_V0_7
#define ENABLE_WIFI // enable WiFi conection do not turn off
#define ENABLE_BLUETOOTH // if enabled here this option is available via WWW // bluetooth KISS interface enabl
//#define BLUETOOTH_PIN "0000" // bluetooth pairing pin
#else
#define ENABLE_WIFI // enable WiFi conection
//#define ENABLE_BLUETOOTH // Lora32 board WiFi or Bluetooth
//#define BLUETOOTH_PIN "0000" // bluetooth pairing pin
#endif

Wyświetl plik

@ -1,11 +1,14 @@
#include <taskGPS.h>
#include "TTGO_T-Beam_LoRa_APRS_config.h"
#include <SparkFun_Ublox_Arduino_Library.h>
SFE_UBLOX_GPS myGPS;
// Pins for GPS
#ifdef T_BEAM_V1_0
static const int RXPin = 12, TXPin = 34;
static const int RXPin = 12, TXPin = 34;
#else
static const int RXPin = 15, TXPin = 12;
static const int RXPin = 15, TXPin = 12;
#endif
static const uint32_t GPSBaud = 9600; //GPS
HardwareSerial gpsSerial(1); // TTGO has HW serial
@ -15,7 +18,24 @@ bool gpsInitialized = false;
void taskGPS(void *parameter) {
if (!gpsInitialized){
gpsSerial.begin(GPSBaud, SERIAL_8N1, TXPin, RXPin); //Startup HW serial for GPS
// set GPS parameters on restart
// Thanks Peter (https://github.com/peterus)
// https://github.com/lora-aprs/TTGO-T-Beam_GPS-reset
if(myGPS.begin(gpsSerial)){
myGPS.setUART1Output(COM_TYPE_NMEA); //Set the UART port to output NMEA only
//myGPS.saveConfiguration(); //Save the current settings to flash and BBR
myGPS.disableNMEAMessage(UBX_NMEA_GLL, COM_PORT_UART1);
myGPS.disableNMEAMessage(UBX_NMEA_GSA, COM_PORT_UART1);
myGPS.disableNMEAMessage(UBX_NMEA_GSV, COM_PORT_UART1);
myGPS.disableNMEAMessage(UBX_NMEA_VTG, COM_PORT_UART1);
myGPS.disableNMEAMessage(UBX_NMEA_RMC, COM_PORT_UART1);
myGPS.enableNMEAMessage(UBX_NMEA_GGA, COM_PORT_UART1);
//myGPS.saveConfiguration(); //Save the current settings to flash and BBR
delay(1000);
}
}
for (;;) {
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());

Wyświetl plik

@ -118,6 +118,13 @@ void handle_Cfg() {
jsonData += jsonLineFromPreferenceBool(PREF_APRS_SHOW_BATTERY);
jsonData += jsonLineFromPreferenceBool(PREF_APRS_FIXED_BEACON_PRESET);
jsonData += jsonLineFromPreferenceBool(PREF_APRS_SHOW_ALTITUDE);
jsonData += jsonLineFromPreferenceBool(PREF_APRS_GPS_EN);
jsonData += jsonLineFromPreferenceBool(PREF_DEV_OL_EN);
jsonData += jsonLineFromPreferenceBool(PREF_APRS_SHOW_CMT);
jsonData += jsonLineFromPreferenceBool(PREF_DEV_BT_EN);
jsonData += jsonLineFromPreferenceInt(PREF_DEV_SHOW_RX_TIME);
jsonData += jsonLineFromPreferenceBool(PREF_DEV_AUTO_SHUT);
jsonData += jsonLineFromPreferenceInt(PREF_DEV_AUTO_SHUT_PRESET);
jsonData += jsonLineFromString("FreeHeap", String(ESP.getFreeHeap()).c_str());
jsonData += jsonLineFromString("HeapSize", String(ESP.getHeapSize()).c_str());
jsonData += jsonLineFromString("FreeSketchSpace", String(ESP.getFreeSketchSpace()).c_str(), true);
@ -151,14 +158,29 @@ void handle_SaveAPRSCfg() {
if (server.hasArg(PREF_APRS_LONGITUDE_PRESET)){
preferences.putString(PREF_APRS_LONGITUDE_PRESET, server.arg(PREF_APRS_LONGITUDE_PRESET));
}
preferences.putBool(PREF_APRS_SHOW_BATTERY, server.hasArg(PREF_APRS_SHOW_BATTERY));
preferences.putBool(PREF_APRS_SHOW_ALTITUDE, server.hasArg(PREF_APRS_SHOW_ALTITUDE));
preferences.putBool(PREF_APRS_FIXED_BEACON_PRESET, server.hasArg(PREF_APRS_FIXED_BEACON_PRESET));
preferences.putBool(PREF_APRS_GPS_EN, server.hasArg(PREF_APRS_GPS_EN));
preferences.putBool(PREF_APRS_SHOW_CMT, server.hasArg(PREF_APRS_SHOW_CMT));
server.sendHeader("Location", "/");
server.send(302,"text/html", "");
}
void handle_saveDeviceCfg(){
preferences.putBool(PREF_DEV_BT_EN, server.hasArg(PREF_DEV_BT_EN));
preferences.putBool(PREF_DEV_OL_EN, server.hasArg(PREF_DEV_OL_EN));
if (server.hasArg(PREF_DEV_SHOW_RX_TIME)){
preferences.putInt(PREF_DEV_SHOW_RX_TIME, server.arg(PREF_DEV_SHOW_RX_TIME).toInt());
}
preferences.putBool(PREF_DEV_AUTO_SHUT, server.hasArg(PREF_DEV_AUTO_SHUT));
if (server.hasArg(PREF_DEV_AUTO_SHUT_PRESET)){
preferences.putInt(PREF_DEV_AUTO_SHUT_PRESET, server.arg(PREF_DEV_AUTO_SHUT_PRESET).toInt());
}
server.sendHeader("Location", "/");
server.send(302,"text/html", "");
}
[[noreturn]] void taskWebServer(void *parameter) {
@ -174,6 +196,7 @@ void handle_SaveAPRSCfg() {
server.on("/reboot", handle_Reboot);
server.on("/cfg", handle_Cfg);
server.on("/save_aprs_cfg", handle_SaveAPRSCfg);
server.on("/save_device_cfg", handle_saveDeviceCfg);
server.on("/restore", handle_Restore);
server.on("/update", HTTP_POST, []() {
server.sendHeader("Connection", "close");