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
rodzic
bd42756395
commit
e489b57205
|
@ -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>
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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*()
|
||||
|
|
|
@ -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(){
|
||||
|
@ -840,6 +936,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
|
||||
|
||||
if (!preferences.getBool(PREF_LORA_FREQ_PRESET_INIT)){
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Ładowanie…
Reference in New Issue