Major improvements and smaller bugfixes

- feature: option to disable wifi. Saves abt 80mA current
  3 options: 2 alaways on; 1 off if no bluetooth client is connected in between
  60s after boot (watch red oled button; goes off as soon as a
  bt client connects in the boot phase). 0 disable (re-enabl by pressing
  beacon button)
- pseudo csma/cd. ppersist / slottime as we know it from standard
  packet-radio / -APRS
  In loaSend. TODO: better concept with a tx-queue. But this is rather complex,
  because the queue must not grow too large, else we re-send old packts..
- feature to encode altitude in compressed position instead of /A=...
  compressed position can encode course/speed, altitude (and others). Option to
  send course/speed to 0%, 100% or something in between.
  altitude check button is obsolete. Switch off by setting alt ratio to 0.
- cross-digipeating: just for sure, clear rx queue after going back to main
  freq.
- if we are not a digipeater and we have no serial-bt-client, we may let the
  loraChip sleep (axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF)) -> saves current
  (a bit)
- adjust_cpu_freq_to: change CPU frequency. May reduce cpu power consumption
  up to 20 %. Suggesting (and tested with) 80 MHz. USE WITH CARE! I.e.
  40 MHz or 20 MHz did not work with my device (boot phase never ended)
- options to start tncServer and gpsServer (if you don't need them, you
  may not like to expose these tcp ports to your LAN or HAMNET)
- changed preferences.getString(PREFxxxxx) to
  preferences.getString(PREFxxxxx, ""), because if variable is not set,
  the preferences library returns "the variable name itself" - wtf!.
  In the case of PREF_NTP_SERVER, we saw log messages that ntp server
  with fqdn "ntp_server" could not be resolved; it had no impact, because
  it did a failback to the compiled-in default.  Changed call for
  PREF_WIFI_PASSWORD, PREF_AP_PASSWORD, etc.. too.
- wifi-AP: is set to esp_wifi_set_max_tx_power(8) (for lesser power
  consumption of the devie). 8 dBm are too less fore some cases.
  -> New web config for setting max_tx_power in AP- and STA- modes.
- Fix: In mode wifi-client, it did not reconnect if association was lost.
- small improvement for comment-text ratelimiting

BG_RF95.cpp: BG_RF95::SignalDetected feature (needed for pseudo csma/cd)

Signed-off-by: Thomas Osterried <dl9sau@darc.de>
pull/4/head refs/heads/master-2022-08-07T180845
Thomas Osterried 2022-08-07 20:01:24 +02:00
rodzic bd42756395
commit e489b57205
6 zmienionych plików z 440 dodań i 85 usunięć

Wyświetl plik

@ -19,11 +19,23 @@
</div>
<article>
<form action="/save_wifi_cfg" method="post">
<div class="grid-container quarters">
<div id="wifi_en">
<label for="wifi_en">Enable Wifi</label>
<select id="wifi_en" name="wifi_en">
<option value="1">1: Wifi may off if bluetooth client is connected in between 60s on boot (recommended for portables, and for LORA32_21 devices)</option>
<option value="2">2: Wifi on (during hardware limitaion, bluetooth will be disabled on LORA32_21 devices)</option>
<option value="0">0: Wifi off (ideal for battery powered trackers - honored only if aprs-is disabled). Hack: Pressing beacon button sets value to 1</option>
</select>
</div>
</div>
<div class="grid-container quarters">
<div id="wifi_list">
<label for="wifi_ssid">Network</label>
<input type="button" value="Scan WiFi" id="scan_wifi_btn" onclick="scanWifi();">
</div>
</div>
<div class="grid-container quarters">
<div>
<label for="wifi_ssid">WiFi SSID</label>
<input class="u-full-width" type="text" name="wifi_ssid" placeholder="Your Wifi SSID" title="Your Wifi SSID" id="wifi_ssid">
@ -32,17 +44,53 @@
<label for="wifi_password">WiFi Password</label>
<input class="u-full-width" type="password" name="wifi_password" id="wifi_password" placeholder="Your WiFi Password" title="Your WiFi Password, 8 characters minimum">
</div>
</div>
<div class="grid-container quarters">
<div>
<label for="wifi_pwrSTA">TXPWR as STA</label>
<select id="wifi_pwrSTA" name="wifi_pwrSTA">
<option value="80">Max (20dBm, 100mW, suggested)</option>
<option value="8">Min (2dBm, 2mW)</option>
<option value="44">Low (11dBm, 12mW)</option>
<option value="60">Mid (15dBm, 32mW)</option>
<option value="72">High (18dBm, 63mW)</option>
</select>
</div>
</div>
<div class="grid-container quarters">
<div>
<label for="ap_password">AUTO AP Password</label>
<input class="u-full-width" type="password" name="ap_password" id="ap_password" placeholder="AUTO AP Password" title="AUTO AP Password, 8 characters minimum">
</div>
</div>
<div class="grid-container quarters">
<div>
<label for="wifi_pwrAP">TXPWR as AP</label>
<select id="wifi_pwrAP" name="wifi_pwrAP">
<option value="8">Min (2dBm, 2mW, suggested)</option>
<option value="44">Low (11dBm, 12mW)</option>
<option value="60">Mid (15dBm, 32mW)</option>
<option value="72">High (18dBm, 63mW)</option>
<option value="80">Max (20dBm, 100mW)</option>
</select>
</div>
</div>
<div class="grid-container quarters">
<div>
<label for="ntp_server">NTP Server</label>
<input type="text" name="ntp_server" id="ntp_server" placeholder="pool.ntp.org" title="NTP Server or IP Address. I.e. pool.ntp.org. If your igate is in the HAMNET, use ntp.hc.r1.ampr.org">
</div>
</div>
<div class="grid-container quarters">
<div>
<label for="tncsrvr_en">Enable TNC-Server</label>
<input name="tncsrvr_en" id="tncsrvr_en" type="checkbox" value="1" title="Enable TNC-Server (KISS over TCP) on port tcp 8001. If your device in open networks like HAMNET, enable it only when needed and consider firewalling.">
</div>
<div>
<label for="gpssrv_en">Enable GPS-Server</label>
<input name="gpssrv_en" id="gpssrv_en" type="checkbox" value="1" title="Enable GPS-Server (NMEA on port tcp 10110. If your device in open networks like HAMNET, enable it only when needed and consider firewalling.">
</div>
</div>
<div class="grid-container full">
<input class="button-primary" type="submit" value="Save">
</div>
@ -80,7 +128,7 @@
</div>
<div>
<label for="lora_rx_en">Enable LoRa receiver</label>
<input name="lora_rx_en" id="lora_rx_en" type="checkbox" value="1" title="Allow RX on LoRa. Disable this if you need to save power consumption.">
<input name="lora_rx_en" id="lora_rx_en" type="checkbox" value="1" title="Allow RX on LoRa. Disable this if you need to save power consumption; LoRa chip will be only powered on during TX. Only honored if lora_digipeating_mode == 0 and no bluetooth client is connected on boot">
</div>
<div>
<label for="txPower">TX power [dBm]</label>
@ -149,21 +197,25 @@
<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" title=" show altitude as frame part">
<label for="aprs_alt_r">Altitude ratio [%]</label>
<input name="aprs_alt_r" id="aprs_alt_r" type="number" min="0" max="100" title="Altitude ratio every n'th packet.. Use 100 for every packet, 0 for no altitude, or any number in between. Recommended: 10 (altitude every tenth's frame). If you use compression for saving airtime, you may choose 50 for ballons, where speed/dir and altitude are of equal interrest; if you choose 10, then 90 % of your transmissions encode speed/direction." placeholder="10">
</div>
<div>
<label for="aprs_ALTinC">Show Altitude in compressed position</label>
<input name="aprs_ALTinC" id="aprs_ALTinC" type="checkbox" value="1" title="Show altitude in compressed position format - safes airtime instead: of /A=...... in comment field. Speed/Course and Altiude are exclusive. If you need speed/course AND altitude on every transmission, set this off and configure altitude ratio to 100).">
</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_comm_rt">Ratelimit adding comment text</label>
<input name="aprs_comm_rt" id="aprs_comm_rt" type="checkbox" value="1" title="If enabled, comment text is sent only every tenth's transmission. Saves airtime.">
</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">
@ -418,10 +470,24 @@
<label for="led_enable">LED signaling</label>
<input name="led_enable" id="led_enable" type="checkbox" value="1" title="enable or disable LED (not implemented)" DISABLED>
</div>
</div>
<div class="grid-container quarters">
<div>
<label for="cpufreq">Adjust CPU frequency (MHz)</label>
<input name="cpufreq" id="cpufreq" type="number" min="0" max="250" title="Reduce CPU freq for power consumption (up to 20 % less). Use with extreme care! Tested with value 80. 0 means: no change to power-on-state." placeholder="0">
</div>
<div>
<label for="reboot_intrvl">Reboot every n hours</label>
<input name="reboot_intrvl" id="reboot_intrvl" type="number" min="0" max="1193" title="Do a periodical reboot every n hous. 0 = disable. Max 1193" placeholder="0">
</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 (not for T-BEAM 0.7)">
</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 quarters">
<div>
@ -432,14 +498,6 @@
<label for="sh_oledtime">Display timeout [s]</label>
<input name="sh_oledtime" id="sh_oledtime" type="number" min="0" max="60" title="Turn OFF OLED after X seconds. Set 0 to disable">
</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>
<label for="reboot_intrvl">Reboot every n hours</label>
<input name="reboot_intrvl" id="reboot_intrvl" type="number" min="0" max="1193" title="Do a periodical reboot every n hous. 0 = disable. Max 1193" placeholder="0">
</div>
</div>
<div class="grid-container full">
<div>
@ -566,8 +624,10 @@
<div>
<h6 class="u-full-width">TTGO LoRa32 V2.1 (aka T3 V1.6.1)</h6>
Hardware limitation: if bluetooth is enabled and BT-client is connected, WIFI (-> Web-Server) does not work anymore.<br/>
You'll see the red LED while booting turned on for 60s as indicatior for waiting for BT-clients.
Hack: firmware compiled with -e ttgo-lora32-v2.1 and bluetooth configuration variable is set to enabled, now listens on boot up to one minute for your bluetooth device to connect.<br/>
If a bluetooth device connects, it does not start the Web-Server. Else, it closes SerialBT port and starts the Web-Server.
If a bluetooth device connects, it does not start the Web-Server. Else, it closes SerialBT port and starts the Web-Server on LORA32_21 devices.<br>
See also: new feature for switching WIFI off (i.e. if you use the device as portable tracker), if you don't need it: Webserver eats abt 80mA..<br>
</div>
</article>
</section>

Wyświetl plik

@ -11,6 +11,17 @@ static const char *const PREF_WIFI_SSID = "wifi_ssid";
static const char *const PREF_WIFI_PASSWORD = "wifi_password";
static const char *const PREF_AP_PASSWORD = "ap_password";
static const char *const PREF_NTP_SERVER = "ntp_server";
static const char *const PREF_WIFI_ENABLE_INIT = "wifi_en_i";
static const char *const PREF_WIFI_ENABLE = "wifi_en";
static const char *const PREF_WIFI_TXPWR_MODE_AP_INIT = "wifi_pwrAP_i";
static const char *const PREF_WIFI_TXPWR_MODE_AP = "wifi_pwrAP";
static const char *const PREF_WIFI_TXPWR_MODE_STA_INIT = "wifi_pwrSTA_i";
static const char *const PREF_WIFI_TXPWR_MODE_STA = "wifi_pwrSTA";
static const char *const PREF_TNCSERVER_ENABLE_INIT = "tncsrvr_en_i";
static const char *const PREF_TNCSERVER_ENABLE = "tncsrvr_en";
static const char *const PREF_GPSSERVER_ENABLE_INIT = "gpssrv_en_i";
static const char *const PREF_GPSSERVER_ENABLE = "gpssrv_en";
// LoRa settings
static const char *const PREF_LORA_FREQ_PRESET_INIT = "lora_freq_i";
@ -56,8 +67,13 @@ static const char *const PREF_APRS_COMMENT = "aprs_comment";
static const char *const PREF_APRS_COMMENT_INIT = "aprs_comm_init";
static const char *const PREF_APRS_COMMENT_RATELIMIT_PRESET = "aprs_comm_rt";
static const char *const PREF_APRS_COMMENT_RATELIMIT_PRESET_INIT = "aprs_comm_rt_i";
static const char *const PREF_APRS_SHOW_ALTITUDE = "aprs_alt";
static const char *const PREF_APRS_SHOW_ALTITUDE_INIT = "aprs_alt_init";
static const char *const PREF_APRS_SHOW_ALTITUDE = "aprs_alt"; /* obsoleted. may be removed later. Use alt ratio 0 .. 100*/
static const char *const PREF_APRS_SHOW_ALTITUDE_INIT = "aprs_alt_init"; /* obsoleted. may be removed later. Use alt ratio 0 .. 100*/
static const char *const PREF_APRS_SHOW_ALTITUDE_INSIDE_COMPRESSED_POSITION = "aprs_ALTinC";
static const char *const PREF_APRS_SHOW_ALTITUDE_INSIDE_COMPRESSED_POSITION_INIT = "aprs_ALTinC_i";
static const char *const PREF_APRS_ALTITUDE_RATIO = "aprs_alt_r";
static const char *const PREF_APRS_ALTITUDE_RATIO_INIT = "aprs_alt_r_i";
static const char *const PREF_APRS_SHOW_BATTERY = "aprs_batt";
static const char *const PREF_APRS_SHOW_BATTERY_INIT = "aprs_batt_init";
static const char *const PREF_APRS_LATITUDE_PRESET = "aprs_lat_p";
@ -120,6 +136,9 @@ static const char *const PREF_DEV_REBOOT_INTERVAL = "reboot_intrvl";
static const char *const PREF_DEV_REBOOT_INTERVAL_INIT = "reboot_intrvl_i";
static const char *const PREF_DEV_SHOW_OLED_TIME = "sh_oledtime"; // set OLED timeout
static const char *const PREF_DEV_SHOW_OLED_TIME_INIT = "sh_oledtime_i";
static const char *const PREF_DEV_CPU_FREQ = "cpufreq";
static const char *const PREF_DEV_CPU_FREQ_INIT = "cpufreq_i";
// APRSIS settings
static const char *const PREF_APRSIS_EN_INIT = "aprsis_en_i";

Wyświetl plik

@ -455,3 +455,8 @@ void BG_RF95::setPreambleLength(uint16_t bytes)
spiWrite(BG_RF95_REG_20_PREAMBLE_MSB, bytes >> 8);
spiWrite(BG_RF95_REG_21_PREAMBLE_LSB, bytes & 0xff);
}
bool BG_RF95::SignalDetected(void)
{
return ((spiRead(BG_RF95_REG_18_MODEM_STAT) & 0x01) == 0x01);
}

Wyświetl plik

@ -694,6 +694,8 @@ virtual uint8_t lastSNR();
/// \return true if sleep mode was successfully entered.
virtual bool sleep();
virtual bool SignalDetected();
protected:
/// This is a low level function to handle the interrupts for one instance of BG_RF95.
/// Called automatically by isr*()

Wyświetl plik

@ -150,10 +150,13 @@ int tel_sequence;
String tel_path;
#ifdef SHOW_ALT
boolean showAltitude = true;
boolean showAltitude = true; /* obsolete. use altitude_ratio 0 .. 100 % */
uint8_t altitude_ratio = 100; // Recommended: 10%. May be 0 % speed (-> 100% altitude), 100 % speed (-> no altitude), or something in between
#else
boolean showAltitude = false;
boolean showAltitude = false; /* obsolete. use altitude_ratio 0 .. 100 % */
uint8_t altitude_ratio = 0; // Recommended 10%. May be 0 % speed (-> 100% altitude), 100 % speed (-> no altitude), or something in between
#endif
boolean showAltitudeInsideCompressedPosition = true;
#ifdef SHOW_BATT
boolean showBattery = true;
#else
@ -180,6 +183,16 @@ String tel_path;
#else
boolean enable_bluetooth = false;
#endif
#if defined(ENABLE_WIFI)
uint8_t enable_webserver = 2;
boolean webserverStarted = 0;
boolean tncServer_enabled = false;
boolean gpsServer_enabled = false;
// Mapping Table {Power, max_tx_power} = {{8, 2}, {20, 5}, {28, 7}, {34, 8}, {44, 11}, {52, 13}, {56, 14}, {60, 15}, {66, 16}, {72, 18}, {80,20}}.
// We'll use "min", "low", "mid", "high", "max" -> 2dBm (1.5mW) -> 8, 11dBm (12mW) -> 44, 15dBm (32mW) -> 60, 18dBm (63mW) ->72, 20dBm (100mW) ->80
int8_t wifi_txpwr_mode_AP = 8;
int8_t wifi_txpwr_mode_STA = 80;
#endif
#ifdef ENABLE_OLED
boolean enabled_oled = true;
#else
@ -325,6 +338,8 @@ uint32_t time_last_frame_via_kiss_received = 0L; // kiss client sends aprs-text-
boolean kiss_client_came_via_bluetooth = false;
#endif
uint16_t adjust_cpuFreq_to = 80;
// do not configure
boolean dont_send_own_position_packets = false; // dynamicaly set if kiss device sends position. Maybe there are other usecases (-> kiss-independent)
boolean gps_state_before_autochange = false; // remember gps state before autochange
@ -420,6 +435,9 @@ out_relay_path:
double Tspeed=0, Tcourse=0;
int i;
long Talt;
static uint8_t cnt = 0;
boolean time_to_add_alt = false;
Tlat=gps.location.lat();
Tlon=gps.location.lng();
Tcourse=gps.course.deg();
@ -429,6 +447,16 @@ out_relay_path:
aprs_lon = 900000000 + Tlon * 10000000 / 2;
aprs_lon = aprs_lon / 26 - aprs_lon / 2710 + aprs_lon / 15384615;
// altitude_ratio: 0%, 10%, 25%, 50%, 75%, 90%, 100%
if (gps.altitude.isValid() && altitude_ratio > 0) {
if (altitude_ratio <= 50)
time_to_add_alt = (cnt % (100 / altitude_ratio) == 0);
else if (altitude_ratio < 100)
time_to_add_alt = (cnt % (100 / (100-altitude_ratio)) != 0);
else
time_to_add_alt = true;
}
outString += aprsSymbolTable;
ax25_base91enc(helper_base91, 4, aprs_lat);
for (i = 0; i < 4; i++) {
@ -439,22 +467,39 @@ out_relay_path:
outString += helper_base91[i];
}
outString += aprsSymbol;
ax25_base91enc(helper_base91, 1, (uint32_t) Tcourse / 4);
outString += helper_base91[0];
ax25_base91enc(helper_base91, 1, (uint32_t) (log1p(Tspeed) / 0.07696));
outString += helper_base91[0];
outString += "H";
if (showAltitude){
if (showAltitudeInsideCompressedPosition && time_to_add_alt) {
Talt = gps.altitude.feet();
char buf[7];
outString += "/A=";
if (Talt > 999999) Talt=999999;
else if (Talt < -99999) Talt=-99999;
sprintf(buf, "%06ld", Talt);
outString += buf;
if (Talt < 0) Talt = 0;
else if (Talt > 15270967) Talt = 15270967; /* 1.002** (90*91+90-1) */
ax25_base91enc(helper_base91, 2, (uint32_t) (log1p(Talt) / 0.001998));
/* ^ math.log1p(1.002-1) */
outString += helper_base91[0];
outString += helper_base91[1];
outString += "X";
} else {
ax25_base91enc(helper_base91, 1, (uint32_t) Tcourse / 4);
outString += helper_base91[0];
if (Tspeed > 1018) Tspeed = 1018; /* 1.08**90 */
ax25_base91enc(helper_base91, 1, (uint32_t) (log1p(Tspeed) / 0.07696));
/* ^ math.log1p(1.08-1) */
outString += helper_base91[0];
outString += "H";
if (time_to_add_alt) {
Talt = gps.altitude.feet();
char buf[7];
outString += "/A=";
if (Talt > 999999) Talt=999999;
else if (Talt < -99999) Talt=-99999;
sprintf(buf, "%06ld", Talt);
outString += buf;
}
}
cnt++;
} else { //fixed position not compresed
outString += aprsLatPreset;
outString += aprsSymbolTable;
@ -465,8 +510,19 @@ out_relay_path:
if(show_cmt){
static uint8_t comments_added = 0;
static uint32_t time_comment_added = 0L;
if (!rate_limit_message_text || (time_comment_added + (gps_state ? sb_max_interval : fix_beacon_interval) < millis()))
if (!rate_limit_message_text) {
comments_added = 0;
} else {
uint32_t t_offset = (gps_state ? sb_max_interval : fix_beacon_interval);
// send comment text not under 10min, and at least every hour
if (t_offset < 600000)
t_offset = 600000;
else if (t_offset > 3600000)
t_offset = 3600000;
if ((time_comment_added + t_offset) < millis())
comments_added = 0;
}
if ((comments_added++ % 10) == 0) {
outString += aprsComment;
time_comment_added = millis();
@ -563,26 +619,66 @@ void sendpacket(boolean force_fixed){
void loraSend(byte lora_LTXPower, float lora_FREQ, ulong lora_SPEED, const String &message) {
if (!lora_tx_enabled)
return;
#ifdef ENABLE_LED_SIGNALING
digitalWrite(TXLED, LOW);
#endif
lastTX = millis();
#ifdef T_BEAM_V1_0
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); // LoRa
#endif
int messageSize = min(message.length(), sizeof(lora_TXBUFF) - 1);
message.toCharArray((char*)lora_TXBUFF, messageSize + 1, 0);
lora_set_speed(lora_SPEED);
rf95.setFrequency(lora_FREQ);
rf95.setTxPower(lora_LTXPower);
// kind of csma/cd. TODO: better approach: add to a tx-queue
// in SF12: preamble + lora header = 663.552 -> we wait 1300ms for check if lora-chip is in decoding
// See https://www.rfwireless-world.com/calculators/LoRaWAN-Airtime-calculator.html
// In detail: At our supported speed "names":
// SF7: 28.928ms
// SF8: 57.856ms
// SF9: 115.712ms 1200
// SF10: 231.424ms 610
// SF11: 331.776ms
// SF12: 663.552ms 300,240, 210, 180
uint32_t wait_for_signal = 700;
if (lora_speed == 610) wait_for_signal = 250;
else if (lora_speed == 1200) wait_for_signal = 125;
randomSeed(millis());
int n;
for (n = 0; n < 30; n++) {
delay(wait_for_signal);
if (rf95.SignalDetected()) {
continue;
}
delay(100);
if (!rf95.SignalDetected() && random(256) < 64) {
break;
}
}
#ifdef ENABLE_LED_SIGNALING
digitalWrite(TXLED, LOW);
#endif
lastTX = millis();
rf95.sendAPRS(lora_TXBUFF, messageSize);
rf95.waitPacketSent();
#ifdef ENABLE_LED_SIGNALING
digitalWrite(TXLED, HIGH);
#endif
// cross-digipeating may have altered our RX-frequency. Revert frequency change needed for this transmission.
if (lora_FREQ != lora_freq_rx_curr)
if (lora_FREQ != lora_freq_rx_curr) {
rf95.setFrequency(lora_freq_rx_curr);
// flush cache. just to be sure, so that no cross-digi-qrg packet comes in the input-buffer of the main qrg.
// With no buffer / length called, recvAPRS directly calls clearRxBuf()
rf95.recvAPRS(0, 0);
}
if (lora_SPEED != lora_speed_rx_curr)
lora_set_speed(lora_speed_rx_curr);
#ifdef T_BEAM_V1_0
// (if lora_digipeating_mode == 0 or not lora_rx_enabled) and no bt client is connected
if ((!lora_digipeating_mode || !lora_rx_enabled) && !SerialBT.hasClient())
axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF); // LoRa
#endif
}
void batt_read(){
@ -839,6 +935,37 @@ void setup(){
}
preferences.begin("cfg", false);
#ifdef ENABLE_WIFI
if (!preferences.getBool(PREF_WIFI_ENABLE_INIT)){
preferences.putBool(PREF_WIFI_ENABLE_INIT, true);
preferences.putInt(PREF_WIFI_ENABLE, enable_webserver);
}
enable_webserver = preferences.getInt(PREF_WIFI_ENABLE);
if (!preferences.getBool(PREF_TNCSERVER_ENABLE_INIT)){
preferences.putBool(PREF_TNCSERVER_ENABLE_INIT, true);
preferences.putBool(PREF_TNCSERVER_ENABLE, tncServer_enabled);
}
tncServer_enabled = preferences.getBool(PREF_TNCSERVER_ENABLE);
if (!preferences.getBool(PREF_GPSSERVER_ENABLE_INIT)){
preferences.putBool(PREF_GPSSERVER_ENABLE_INIT, true);
preferences.putBool(PREF_GPSSERVER_ENABLE, gpsServer_enabled);
}
gpsServer_enabled = preferences.getBool(PREF_GPSSERVER_ENABLE);
if (!preferences.getBool(PREF_WIFI_TXPWR_MODE_AP_INIT)){
preferences.putBool(PREF_WIFI_TXPWR_MODE_AP_INIT, true);
preferences.putInt(PREF_WIFI_TXPWR_MODE_AP, wifi_txpwr_mode_AP);
}
wifi_txpwr_mode_AP = preferences.getInt(PREF_WIFI_TXPWR_MODE_AP);
if (!preferences.getBool(PREF_WIFI_TXPWR_MODE_STA_INIT)){
preferences.putBool(PREF_WIFI_TXPWR_MODE_STA_INIT, true);
preferences.putInt(PREF_WIFI_TXPWR_MODE_STA, wifi_txpwr_mode_STA);
}
wifi_txpwr_mode_STA = preferences.getInt(PREF_WIFI_TXPWR_MODE_STA);
#endif
// LoRa transmission settings
@ -940,13 +1067,13 @@ void setup(){
// APRS station settings
aprsSymbolTable = preferences.getString(PREF_APRS_SYMBOL_TABLE);
aprsSymbolTable = preferences.getString(PREF_APRS_SYMBOL_TABLE, "");
if (aprsSymbolTable.isEmpty()){
preferences.putString(PREF_APRS_SYMBOL_TABLE, APRS_SYMBOL_TABLE);
aprsSymbolTable = preferences.getString(PREF_APRS_SYMBOL_TABLE);
}
aprsSymbol = preferences.getString(PREF_APRS_SYMBOL);
aprsSymbol = preferences.getString(PREF_APRS_SYMBOL, "");
if (aprsSymbol.isEmpty()){
preferences.putString(PREF_APRS_SYMBOL, APRS_SYMBOL);
aprsSymbol = preferences.getString(PREF_APRS_SYMBOL, APRS_SYMBOL);
@ -956,19 +1083,31 @@ void setup(){
preferences.putBool(PREF_APRS_COMMENT_INIT, true);
preferences.putString(PREF_APRS_COMMENT, MY_COMMENT);
}
aprsComment = preferences.getString(PREF_APRS_COMMENT);
aprsComment = preferences.getString(PREF_APRS_COMMENT, "");
if (!preferences.getBool(PREF_APRS_RELAY_PATH_INIT)){
preferences.putBool(PREF_APRS_RELAY_PATH_INIT, true);
preferences.putString(PREF_APRS_RELAY_PATH, DIGI_PATH);
}
relay_path = preferences.getString(PREF_APRS_RELAY_PATH);
relay_path = preferences.getString(PREF_APRS_RELAY_PATH, "");
if (!preferences.getBool(PREF_APRS_SHOW_ALTITUDE_INIT)){
preferences.putBool(PREF_APRS_SHOW_ALTITUDE_INIT, true);
preferences.putBool(PREF_APRS_SHOW_ALTITUDE, showAltitude);
}
showAltitude = preferences.getBool(PREF_APRS_SHOW_ALTITUDE);
if (!preferences.getBool(PREF_APRS_SHOW_ALTITUDE_INSIDE_COMPRESSED_POSITION_INIT)){
preferences.putBool(PREF_APRS_SHOW_ALTITUDE_INSIDE_COMPRESSED_POSITION_INIT, true);
preferences.putBool(PREF_APRS_SHOW_ALTITUDE_INSIDE_COMPRESSED_POSITION, showAltitudeInsideCompressedPosition);
}
showAltitudeInsideCompressedPosition = preferences.getBool(PREF_APRS_SHOW_ALTITUDE_INSIDE_COMPRESSED_POSITION);
if (!preferences.getBool(PREF_APRS_ALTITUDE_RATIO_INIT)){
preferences.putBool(PREF_APRS_ALTITUDE_RATIO_INIT, true);
// preferences.putInt(PREF_APRS_ALTITUDE_RATIO, altitude_ratio); // until SHOW_ALTITUDE is obsolete, commented out
preferences.putInt(PREF_APRS_ALTITUDE_RATIO, showAltitude ? 100 : 0);
}
altitude_ratio = preferences.getInt(PREF_APRS_ALTITUDE_RATIO);
if (!preferences.getBool(PREF_APRS_GPS_EN_INIT)){
preferences.putBool(PREF_APRS_GPS_EN_INIT, true);
@ -1023,27 +1162,27 @@ void setup(){
preferences.putBool(PREF_TNC_SELF_TELEMETRY_PATH_INIT, true);
preferences.putString(PREF_TNC_SELF_TELEMETRY_PATH, tel_path);
}
tel_path = preferences.getString(PREF_TNC_SELF_TELEMETRY_PATH);
tel_path = preferences.getString(PREF_TNC_SELF_TELEMETRY_PATH, "");
if (!preferences.getBool(PREF_APRS_LATITUDE_PRESET_INIT)){
preferences.putBool(PREF_APRS_LATITUDE_PRESET_INIT, true);
preferences.putString(PREF_APRS_LATITUDE_PRESET, LATITUDE_PRESET);
}
aprsLatPreset = preferences.getString(PREF_APRS_LATITUDE_PRESET);
aprsLatPreset = preferences.getString(PREF_APRS_LATITUDE_PRESET, "");
LatShownP = aprsLonPreset;
if (!preferences.getBool(PREF_APRS_LONGITUDE_PRESET_INIT)){
preferences.putBool(PREF_APRS_LONGITUDE_PRESET_INIT, true);
preferences.putString(PREF_APRS_LONGITUDE_PRESET, LONGITUDE_PRESET);
}
aprsLonPreset = preferences.getString(PREF_APRS_LONGITUDE_PRESET);
aprsLonPreset = preferences.getString(PREF_APRS_LONGITUDE_PRESET, "");
LongShownP = aprsLonPreset;
if (!preferences.getBool(PREF_APRS_SENDER_BLACKLIST_INIT)){
preferences.putBool(PREF_APRS_SENDER_BLACKLIST_INIT, true);
preferences.putString(PREF_APRS_SENDER_BLACKLIST, "");
}
{ String s = preferences.getString(PREF_APRS_SENDER_BLACKLIST);
{ String s = preferences.getString(PREF_APRS_SENDER_BLACKLIST, "");
s.toUpperCase(); s.trim(); s.replace(" ", ","); s.replace(",,", ",");
if (!s.isEmpty() && s != "," && s.length() < sizeof(blacklist_calls)-3) {
*blacklist_calls = ',';
@ -1172,6 +1311,12 @@ void setup(){
}
enabled_oled = preferences.getBool(PREF_DEV_OL_EN);
if (!preferences.getBool(PREF_DEV_CPU_FREQ_INIT)){
preferences.putBool(PREF_DEV_CPU_FREQ_INIT, true);
preferences.putInt(PREF_DEV_CPU_FREQ, adjust_cpuFreq_to);
}
adjust_cpuFreq_to = preferences.getInt(PREF_DEV_CPU_FREQ);
// APRSIS settings
#ifdef ENABLE_WIFI
@ -1185,7 +1330,7 @@ void setup(){
preferences.putBool(PREF_APRSIS_SERVER_NAME_INIT, true);
preferences.putString(PREF_APRSIS_SERVER_NAME, aprsis_host);
}
aprsis_host = preferences.getString(PREF_APRSIS_SERVER_NAME);
aprsis_host = preferences.getString(PREF_APRSIS_SERVER_NAME, "");
if (!preferences.getBool(PREF_APRSIS_SERVER_PORT_INIT)){
preferences.putBool(PREF_APRSIS_SERVER_PORT_INIT, true);
@ -1197,19 +1342,19 @@ void setup(){
preferences.putBool(PREF_APRSIS_FILTER_INIT, true);
preferences.putString(PREF_APRSIS_FILTER, aprsis_filter);
}
aprsis_filter = preferences.getString(PREF_APRSIS_FILTER);
aprsis_filter = preferences.getString(PREF_APRSIS_FILTER, "");
if (!preferences.getBool(PREF_APRSIS_CALLSIGN_INIT)){
preferences.putBool(PREF_APRSIS_CALLSIGN_INIT, true);
preferences.putString(PREF_APRSIS_CALLSIGN, aprsis_callsign);
}
aprsis_callsign = preferences.getString(PREF_APRSIS_CALLSIGN);
aprsis_callsign = preferences.getString(PREF_APRSIS_CALLSIGN, "");
if (!preferences.getBool(PREF_APRSIS_PASSWORD_INIT)){
preferences.putBool(PREF_APRSIS_PASSWORD_INIT, true);
preferences.putString(PREF_APRSIS_PASSWORD, aprsis_password);
}
aprsis_password = preferences.getString(PREF_APRSIS_PASSWORD);
aprsis_password = preferences.getString(PREF_APRSIS_PASSWORD, "");
if (!preferences.getBool(PREF_APRSIS_ALLOW_INET_TO_RF_INIT)){
preferences.putBool(PREF_APRSIS_ALLOW_INET_TO_RF_INIT, true);
@ -1276,14 +1421,18 @@ void setup(){
if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS)) {
}
axp.setLowTemp(0xFF); //SP6VWX Set low charging temperature
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); // LoRa
if (lora_digipeating_mode > 0 || lora_rx_enabled || SerialBT.hasClient())
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); // LoRa
else
axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF); // LoRa
if (gps_state){
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); // switch on GPS
} else {
axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF); // switch off GPS
}
axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON);
axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
axp.setPowerOutPut(AXP192_EXTEN, AXP202_OFF);
//axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON); // switch this on if you need it
axp.setDCDC1Voltage(3300);
// Enable ADC to measure battery current, USB voltage etc.
axp.adc1Enable(0xfe, true);
@ -1291,6 +1440,9 @@ void setup(){
axp.setChgLEDMode(AXP20X_LED_OFF);
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON); // oled do not turn off
#endif
// can reduce cpu power consumtion up to 20 %
if (adjust_cpuFreq_to > 0)
setCpuFrequencyMhz(adjust_cpuFreq_to);
if(!display.begin(SSD1306_SWITCHCAPVCC, SSD1306_ADDRESS)) {
for(;;); // Don't proceed, loop forever
@ -1319,7 +1471,7 @@ void setup(){
Tcall = prepareCallsign(String(CALLSIGN));
#ifdef ENABLE_PREFERENCES
Tcall = preferences.getString(PREF_APRS_CALLSIGN);
Tcall = preferences.getString(PREF_APRS_CALLSIGN, "");
if (Tcall.isEmpty()){
preferences.putString(PREF_APRS_CALLSIGN, String(CALLSIGN));
Tcall = preferences.getString(PREF_APRS_CALLSIGN);
@ -1367,14 +1519,33 @@ void setup(){
xTaskCreatePinnedToCore(taskTNC, "taskTNC", 10000, nullptr, 1, nullptr, xPortGetCoreID());
#endif
#if defined(KISS_PROTOCOL) && defined(ENABLE_BLUETOOTH)
if (enable_bluetooth){
// LORA32_21: bug in hardware. cannot run bluetooth and wifi concurrently.
// We wait for a bt-client connecting, up to 60s. If none connected,
// we start the webserver.
// TTGO: webserver cunsumes abt 80mA. User may not start the webserver
// if bt-client is connected. We'll also wait herefor clients.
// If enable_webserver on LORA32_21 is set to 2, user
// likes the webserver always to be started -> do not start bluetooth.
#if defined(ENABLE_WIFI)
#if defined(LORA32_21)
if (enable_bluetooth && enable_webserver < 2) {
#else
if (enable_bluetooth) {
#endif /* LORA32_21 */
#else
if (enable_bluetooth) {
#endif /* ENABLE_WIFI */
#ifdef BLUETOOTH_PIN
SerialBT.setPin(BLUETOOTH_PIN);
SerialBT.setPin(BLUETOOTH_PIN);
#endif
SerialBT.begin(String("TTGO LORA APRS ") + Tcall);
writedisplaytext("LoRa-APRS","","Init:","BT OK!","","");
#if defined(ENABLE_WIFI) && defined(LORA32_21)
SerialBT.begin(String("TTGO LORA APRS ") + Tcall);
writedisplaytext("LoRa-APRS","","Init:","BT OK!","","");
#if defined(ENABLE_WIFI)
if (enable_webserver == 1 && !aprsis_enabled) {
writedisplaytext("LoRa-APRS","","Init:","Waiting for BT-client","","");
// wait 60s until BT client connects
uint32_t t_end = millis() + 60000;
@ -1384,30 +1555,41 @@ void setup(){
delay(100);
}
if (!SerialBT.hasClient()) {
#if defined(LORA32_21)
writedisplaytext("LoRa-APRS","","Init:","Waiting for BT-client","Disabling BT!","");
SerialBT.end();
#endif
} else {
writedisplaytext("LoRa-APRS","","Init:","Waiting for BT-clients","BT-client connected","Will NOT start WiFi!");
}
delay(1500);
#endif /* ENABLE_WIFI && LORA32_21 */
}
#endif /* ENABLE_WIFI */
}
#endif /* KISS_PROTOCOL && ENABLE_BLUETOOTH */
#ifdef ENABLE_WIFI
#if defined(LORA32_21) && defined(ENABLE_BLUETOOTH)
if (!SerialBT.hasClient()) {
#endif
if (enable_webserver) {
#if defined(KISS_PROTOCOL) && defined(ENABLE_BLUETOOTH)
// if enabble_webserver == 2 or (enable_webserver == 1 && (no serial-bt-client is connected OR aprs-is-connecion configuried)
if (enable_webserver > 1 || aprsis_enabled || !SerialBT.hasClient()) {
#else
{
#endif /* KISS_PROTOCOL && ENABLE_BLUETOOTH */
webServerCfg = {.callsign = Tcall};
xTaskCreate(taskWebServer, "taskWebServer", 12000, (void*)(&webServerCfg), 1, nullptr);
webserverStarted = true;
writedisplaytext("LoRa-APRS","","Init:","WiFi task started"," =:-) ","");
#if defined(LORA32_21) && defined(ENABLE_BLUETOOTH)
#if defined(KISS_PROTOCOL) && defined(ENABLE_BLUETOOTH)
} else {
writedisplaytext("LoRa-APRS","","Init:","WiFi NOT started!"," =:-S ","");
}
#else
}
#endif /* KISS_PROTOCOL && ENABLE_BLUETOOTH */
delay(1500);
#endif
#endif /* ENABLE_WIFI */
}
writedisplaytext("LoRa-APRS","","Init:","FINISHED OK!"," =:-) ","");
writedisplaytext("","","","","","");
@ -2094,7 +2276,7 @@ void loop() {
time_delay = millis() + 1500;
if(digitalRead(BUTTON)==HIGH){
if (!tempOled && enabled_oled) {
enableOled(); // turn ON OLED temporary
enableOled(); // turn ON OLED temporary
} else {
if(gps_state == true && gps.location.isValid()){
writedisplaytext("((MAN TX))","","","","","");
@ -2104,6 +2286,25 @@ void loop() {
sendpacket(1);
}
}
// hack: re-enable webserevr, if was set to off.
#ifdef ENABLE_WIFI
if (!webserverStarted) {
enable_webserver = 1;
#ifdef ENABLE_PREFERENCES
preferences.putInt("PREF_WIFI_ENABLED", enable_webserver);
#endif
#if defined(LORA32_21) && defined(ENABLE_BLUETOOTH)
// lora32_21 hardware bug: btt and wifi are mutual exclusive
SerialBT.end();
delay(100);
#endif
webServerCfg = {.callsign = Tcall};
xTaskCreate(taskWebServer, "taskWebServer", 12000, (void*)(&webServerCfg), 1, nullptr);
webserverStarted = true;
writedisplaytext("LoRa-APRS","","Init:","WiFi task started"," =:-) ","");
delay(1500);
#endif
}
key_up = true;
}
}

Wyświetl plik

@ -27,6 +27,12 @@ extern String infoApName;
extern String infoApPass;
extern String infoApAddr;
extern int8_t wifi_txpwr_mode_AP;
extern int8_t wifi_txpwr_mode_STA;
extern bool tncServer_enabled;
extern bool gpsServer_enabled;
// For APRS-IS connection
extern String to_aprsis_data;
extern boolean aprsis_enabled;
@ -66,7 +72,6 @@ extern ulong lora_speed_cross_digi;
extern double lora_freq_cross_digi;
extern void loraSend(byte, float, ulong, const String &);
WebServer server(80);
#ifdef KISS_PROTOCOL
WiFiServer tncServer(NETWORK_TNC_PORT);
@ -101,7 +106,7 @@ String jsonEscape(String s){
}
String jsonLineFromPreferenceString(const char *preferenceName, bool last=false){
return String("\"") + preferenceName + "\":\"" + jsonEscape(preferences.getString(preferenceName)) + (last ? + R"(")" : + R"(",)");
return String("\"") + preferenceName + "\":\"" + jsonEscape(preferences.getString(preferenceName, "")) + (last ? + R"(")" : + R"(",)");
}
String jsonLineFromPreferenceBool(const char *preferenceName, bool last=false){
return String("\"") + preferenceName + "\":" + (preferences.getBool(preferenceName) ? "true" : "false") + (last ? + R"()" : + R"(,)");
@ -157,10 +162,12 @@ void handle_ScanWifi() {
}
void handle_SaveWifiCfg() {
if (!server.hasArg(PREF_WIFI_SSID) || !server.hasArg(PREF_WIFI_PASSWORD) || !server.hasArg(PREF_AP_PASSWORD)){
server.send(500, "text/plain", "Invalid request, make sure all fields are set");
}
// Mode STA:
if (!server.arg(PREF_WIFI_SSID).length()){
server.send(403, "text/plain", "Empty SSID");
} else {
@ -178,7 +185,16 @@ void handle_SaveWifiCfg() {
Serial.println("Updated WiFi PASS: " + server.arg(PREF_WIFI_PASSWORD));
}
}
if (server.hasArg(PREF_WIFI_TXPWR_MODE_STA)) {
// Web chooser min, low, mid, high, max
// We'll use "min", "low", "mid", "high", "max" -> 2dBm (1.5mW) -> 8, 11dBm (12mW) -> 44, 15dBm (32mW) -> 60, 18dBm (63mW) ->72, 20dBm (100mW) ->80
int8_t choosed = server.arg(PREF_WIFI_TXPWR_MODE_STA).toInt();
if (choosed < 0) choosed = 8;
else if (choosed > 84) choosed = 84;
preferences.putInt(PREF_WIFI_TXPWR_MODE_STA, choosed);
}
// Mode AP:
if (server.arg(PREF_AP_PASSWORD)!="*" && server.arg(PREF_AP_PASSWORD).length()<8){
server.send(403, "text/plain", "AP Password must be minimum 8 character");
} else {
@ -188,8 +204,22 @@ void handle_SaveWifiCfg() {
Serial.println("Updated AP PASS: " + server.arg(PREF_AP_PASSWORD));
}
}
if (server.hasArg(PREF_WIFI_TXPWR_MODE_AP)) {
// Web chooser min, low, mid, high, max
// We'll use "min", "low", "mid", "high", "max" -> 2dBm (1.5mW) -> 8, 11dBm (12mW) -> 44, 15dBm (32mW) -> 60, 18dBm (63mW) ->72, 20dBm (100mW) ->80
int8_t choosed = server.arg(PREF_WIFI_TXPWR_MODE_AP).toInt();
if (choosed < 0) choosed = 8;
else if (choosed > 84) choosed = 84;
preferences.putInt(PREF_WIFI_TXPWR_MODE_AP, choosed);
}
if (server.hasArg(PREF_WIFI_ENABLE))
preferences.putInt(PREF_WIFI_ENABLE, server.arg(PREF_WIFI_ENABLE).toInt());
preferences.putBool(PREF_TNCSERVER_ENABLE, server.hasArg(PREF_TNCSERVER_ENABLE));
preferences.putBool(PREF_GPSSERVER_ENABLE, server.hasArg(PREF_GPSSERVER_ENABLE));
String s = "";
if (server.arg(PREF_NTP_SERVER).length()) {
if (server.hasArg(PREF_NTP_SERVER) && server.arg(PREF_NTP_SERVER).length()) {
s = server.arg(PREF_NTP_SERVER);
s.trim();
}
@ -232,9 +262,14 @@ void handle_Restore() {
void handle_Cfg() {
String jsonData = "{";
jsonData += String("\"") + PREF_WIFI_PASSWORD + "\": \"" + jsonEscape((preferences.getString(PREF_WIFI_PASSWORD).isEmpty() ? String("") : "*")) + R"(",)";
jsonData += String("\"") + PREF_AP_PASSWORD + "\": \"" + jsonEscape((preferences.getString(PREF_AP_PASSWORD).isEmpty() ? String("") : "*")) + R"(",)";
jsonData += String("\"") + PREF_WIFI_PASSWORD + "\": \"" + jsonEscape((preferences.getString(PREF_WIFI_PASSWORD, "").isEmpty() ? String("") : "*")) + R"(",)";
jsonData += String("\"") + PREF_AP_PASSWORD + "\": \"" + jsonEscape((preferences.getString(PREF_AP_PASSWORD, "").isEmpty() ? String("") : "*")) + R"(",)";
jsonData += jsonLineFromPreferenceInt(PREF_WIFI_ENABLE);
jsonData += jsonLineFromPreferenceString(PREF_WIFI_SSID);
jsonData += jsonLineFromPreferenceInt(PREF_WIFI_TXPWR_MODE_AP);
jsonData += jsonLineFromPreferenceInt(PREF_WIFI_TXPWR_MODE_STA);
jsonData += jsonLineFromPreferenceBool(PREF_TNCSERVER_ENABLE);
jsonData += jsonLineFromPreferenceBool(PREF_GPSSERVER_ENABLE);
jsonData += jsonLineFromPreferenceString(PREF_NTP_SERVER);
jsonData += jsonLineFromPreferenceDouble(PREF_LORA_FREQ_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_LORA_SPEED_PRESET);
@ -270,7 +305,9 @@ void handle_Cfg() {
jsonData += jsonLineFromPreferenceInt(PREF_APRS_SB_TURN_TIME_PRESET);
jsonData += jsonLineFromPreferenceBool(PREF_APRS_SHOW_BATTERY);
jsonData += jsonLineFromPreferenceBool(PREF_APRS_FIXED_BEACON_PRESET);
jsonData += jsonLineFromPreferenceBool(PREF_APRS_SHOW_ALTITUDE);
//jsonData += jsonLineFromPreferenceBool(PREF_APRS_SHOW_ALTITUDE);
jsonData += jsonLineFromPreferenceBool(PREF_APRS_SHOW_ALTITUDE_INSIDE_COMPRESSED_POSITION);
jsonData += jsonLineFromPreferenceInt(PREF_APRS_ALTITUDE_RATIO);
jsonData += jsonLineFromPreferenceBool(PREF_APRS_GPS_EN);
jsonData += jsonLineFromPreferenceBool(PREF_ACCEPT_OWN_POSITION_REPORTS_VIA_KISS);
jsonData += jsonLineFromPreferenceBool(PREF_GPS_ALLOW_SLEEP_WHILE_KISS);
@ -287,6 +324,7 @@ void handle_Cfg() {
jsonData += jsonLineFromPreferenceInt(PREF_DEV_AUTO_SHUT_PRESET);
jsonData += jsonLineFromPreferenceInt(PREF_DEV_REBOOT_INTERVAL);
jsonData += jsonLineFromPreferenceInt(PREF_DEV_SHOW_OLED_TIME);
jsonData += jsonLineFromPreferenceInt(PREF_DEV_CPU_FREQ);
jsonData += jsonLineFromPreferenceBool(PREF_APRSIS_EN);
jsonData += jsonLineFromPreferenceString(PREF_APRSIS_SERVER_NAME);
jsonData += jsonLineFromPreferenceInt(PREF_APRSIS_SERVER_PORT);
@ -709,7 +747,11 @@ void handle_SaveAPRSCfg() {
preferences.putBool(PREF_APRS_SHOW_BATTERY, server.hasArg(PREF_APRS_SHOW_BATTERY));
preferences.putBool(PREF_ENABLE_TNC_SELF_TELEMETRY, server.hasArg(PREF_ENABLE_TNC_SELF_TELEMETRY));
preferences.putBool(PREF_APRS_SHOW_ALTITUDE, server.hasArg(PREF_APRS_SHOW_ALTITUDE));
//preferences.putBool(PREF_APRS_SHOW_ALTITUDE, server.hasArg(PREF_APRS_SHOW_ALTITUDE));
preferences.putBool(PREF_APRS_SHOW_ALTITUDE_INSIDE_COMPRESSED_POSITION, server.hasArg(PREF_APRS_SHOW_ALTITUDE_INSIDE_COMPRESSED_POSITION));
if (server.hasArg(PREF_APRS_ALTITUDE_RATIO)){
preferences.putInt(PREF_APRS_ALTITUDE_RATIO, server.arg(PREF_APRS_ALTITUDE_RATIO).toInt());
}
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_ACCEPT_OWN_POSITION_REPORTS_VIA_KISS, server.hasArg(PREF_ACCEPT_OWN_POSITION_REPORTS_VIA_KISS));
@ -739,6 +781,12 @@ void handle_saveDeviceCfg(){
if (server.hasArg(PREF_DEV_REBOOT_INTERVAL)){
preferences.putInt(PREF_DEV_REBOOT_INTERVAL, server.arg(PREF_DEV_REBOOT_INTERVAL).toInt());
}
if (server.hasArg(PREF_DEV_CPU_FREQ)){
uint8_t cpufreq = server.arg(PREF_DEV_CPU_FREQ).toInt();
if (cpufreq != 0 && cpufreq < 10)
cpufreq = 10;
preferences.putInt(PREF_DEV_CPU_FREQ, cpufreq);
}
server.sendHeader("Location", "/");
server.send(302,"text/html", "");
}
@ -794,23 +842,25 @@ void handle_saveDeviceCfg(){
});
server.onNotFound(handle_NotFound);
String wifi_password = preferences.getString(PREF_WIFI_PASSWORD);
String wifi_ssid = preferences.getString(PREF_WIFI_SSID);
if (preferences.getString(PREF_AP_PASSWORD).length() > 7) {
// 8 characters is requirements for WPA2
apPassword = preferences.getString(PREF_AP_PASSWORD);
} else {
String wifi_password = preferences.getString(PREF_WIFI_PASSWORD, "");
String wifi_ssid = preferences.getString(PREF_WIFI_SSID, "");
apPassword = preferences.getString(PREF_AP_PASSWORD, "");
// 8 characters is requirements for WPA2
if (apPassword.length() < 8) {
apPassword = defApPassword;
}
if (!wifi_ssid.length()){
WiFi.softAP(apSSID.c_str(), apPassword.c_str());
esp_wifi_set_max_tx_power(wifi_txpwr_mode_AP);
} else {
int retryWifi = 0;
WiFi.begin(wifi_ssid.c_str(), wifi_password.length() ? wifi_password.c_str() : nullptr);
Serial.println("Connecting to " + wifi_ssid);
// Set power to minimum (max 20)
// Set power: minimum 8 (2dBm) (max 80 (20dBm))
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html
esp_wifi_set_max_tx_power(8);
// Mapping Table {Power, max_tx_power} = {{8, 2}, {20, 5}, {28, 7}, {34, 8}, {44, 11}, {52, 13}, {56, 14}, {60, 15}, {66, 16}, {72, 18}, {80, 20}}.
// We'll use "min", "low", "mid", "high", "max" -> 2dBm (1.5mW) -> 8, 11dBm (12mW) -> 44, 15dBm (32mW) -> 60, 18dBm (63mW) ->72, 20dBm (100mW) ->80
esp_wifi_set_max_tx_power(wifi_txpwr_mode_STA);
while (WiFi.status() != WL_CONNECTED) {
Serial.print("Not connected: ");
Serial.println((int)WiFi.status());
@ -826,8 +876,7 @@ void handle_saveDeviceCfg(){
Serial.print(apSSID.c_str());
Serial.print(" Password: ");
Serial.println(apPassword.c_str());
// Set power to minimum (max 20)
esp_wifi_set_max_tx_power(8);
esp_wifi_set_max_tx_power(wifi_txpwr_mode_AP);
break;
}
}
@ -860,7 +909,7 @@ void handle_saveDeviceCfg(){
syslog.defaultPriority(LOG_KERN);
syslog_log(LOG_INFO, "Connected. IP: " + WiFi.localIP().toString());
#endif
String ntp_server = preferences.getString(PREF_NTP_SERVER);
String ntp_server = preferences.getString(PREF_NTP_SERVER, "");
if (ntp_server.isEmpty()) {
if (infoApAddr.startsWith("44."))
ntp_server = "ntp.hc.r1.ampr.org";
@ -882,9 +931,11 @@ void handle_saveDeviceCfg(){
server.begin();
#ifdef KISS_PROTOCOL
tncServer.begin();
if (tncServer_enabled)
tncServer.begin();
#endif
gpsServer.begin();
if (gpsServer_enabled)
gpsServer.begin();
if (MDNS.begin(webServerCfg->callsign.c_str())) {
MDNS.setInstanceName(webServerCfg->callsign + " TTGO LoRa APRS TNC " + TXFREQ + "MHz");
MDNS.addService("http", "tcp", 80);
@ -935,6 +986,23 @@ void handle_saveDeviceCfg(){
while (true){
esp_task_wdt_reset();
// Mode STA and connection lost? -> reconnect
if (WiFi.getMode() == 1 && WiFi.status() != WL_CONNECTED) {
static uint32_t last_connection_attempt = millis();
if (millis() - last_connection_attempt > 20000L) {
WiFi.disconnect();
esp_task_wdt_reset();
WiFi.reconnect();
esp_task_wdt_reset();
last_connection_attempt = millis();
}
if (WiFi.status() != WL_CONNECTED) {
// 500ms for reconnect should be enough, ant not too often (power consumption).. Or, if we did not try to reconnect, this value is also fine
delay(500);
continue;
}
}
server.handleClient();
if (xQueueReceive(webListReceivedQueue, &receivedPacketData, (1 / portTICK_PERIOD_MS)) == pdPASS) {
auto *receivedPacketToQueue = new tReceivedPacketData();