Squashed commit of the following:

commit 925f066093
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sun Jan 23 23:30:59 2022 +0000

    sticking to 3.3.2 for now, as 3.4 causes some issues

commit f08bb2a032
Merge: 9140b52 d2e8631
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Fri Jan 21 13:15:26 2022 +0000

    Merge remote-tracking branch 'refs/remotes/origin/devel' into devel

commit 9140b52b43
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Fri Jan 21 13:15:07 2022 +0000

    reset DFM id after 30 minutes or >.25 lat/lon change

commit f7dc810f94
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Fri Jan 21 11:59:39 2022 +0000

    RS41: send real type if available

commit d2e8631696
Author: Luke Prior <22492406+LukePrior@users.noreply.github.com>
Date:   Tue Jan 11 23:05:55 2022 +1100

    Remove RS92-NGP Support Note (#266)

commit 8d4ddd2fa4
Author: Luclu7 <luclu7@luclu7.fr>
Date:   Sat Dec 11 01:24:01 2021 +0100

    simply typo (#249)

commit 8ddf8fa595
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Mon Nov 1 17:31:27 2021 +0100

    sh import last interval as double (for <1h)

commit e4df63e264
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Mon Nov 1 14:22:49 2021 +0100

    fix sh import

commit 07859d7f70
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 30 23:37:44 2021 +0200

    remove updated Setup.mp, better instructions are now in the wiki

commit f7b87b6ba5
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 30 23:27:28 2021 +0200

    scan display for ILI934x

commit cf612659e1
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 30 23:27:07 2021 +0200

    don't charge the battery using the battery :)

commit af32d576d6
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 30 18:13:07 2021 +0200

    back to normal beacon frequency

commit 4279875358
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 30 17:45:52 2021 +0200

    simplification

commit baec8fb8ea
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 30 17:36:48 2021 +0200

    some better APRS for wettersonde.net support

commit 327bbca6e6
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 30 17:14:42 2021 +0200

    some APRS for wettersonde.net support

commit beea3a7047
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 30 13:50:32 2021 +0200

    test

commit 8a0c37e792
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 30 12:02:51 2021 +0200

    version update

commit 87ea465123
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 30 12:02:29 2021 +0200

    unused code lines removal

commit 0556b5ab1d
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 30 11:59:33 2021 +0200

    arduino ide autoformat

commit a3b24a885d
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 30 11:58:40 2021 +0200

    bugfix

commit c932c90910
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 30 11:57:18 2021 +0200

    remove no longer used idformat config

commit 949ac6f75f
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 30 11:51:12 2021 +0200

    ax25 aprs beacon; irq-less pmu button for m5stack

commit 7eb4291408
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 30 11:26:19 2021 +0200

    make use of tx_frequency (issue #238)

commit c90381791d
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sun Oct 24 21:09:16 2021 +0200

    typo fix

commit ad96dd6023
Author: Luke Prior <22492406+LukePrior@users.noreply.github.com>
Date:   Sun Oct 24 08:32:33 2021 +1100

    Support dark mode fully in live map (#225)

    * Update style.css

    * dark mode map

    Co-authored-by: Uskompuf <22492406+Uskompuf@users.noreply.github.com>

commit 391135ba9d
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 23 23:27:56 2021 +0200

    update screens5.txt

commit b5cbe1b676
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 16 16:52:46 2021 +0200

    fix #224

commit ff5f4bfa24
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Wed Oct 13 19:20:34 2021 +0200

    no sh location report without enabling sh reporting

commit 4e773944b1
Author: Luke Prior <22492406+LukePrior@users.noreply.github.com>
Date:   Mon Oct 11 07:00:34 2021 +1100

    Few more changes (#217)

commit e6a764b650
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sun Oct 10 21:39:21 2021 +0200

    correct launchsite display on oled

commit b4c0179ee6
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sun Oct 10 12:02:07 2021 +0200

    fix correct M20 id (missing terminator)

commit 97b3abc38f
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 9 10:11:03 2021 +0200

    version update for dark mode enhancements

commit 6661da7f72
Merge: 4036214 04b95ef
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Sat Oct 9 10:10:43 2021 +0200

    Merge branch 'LukePrior-patch-7' into devel

commit 04b95effba
Author: Luke Prior <22492406+LukePrior@users.noreply.github.com>
Date:   Sat Oct 9 19:07:15 2021 +1100

    CSS Dark Mode Improvements

commit 4036214ecd
Merge: 1dc548d 1a148b6
Author: Hansi, dl9rdz <dl9rdz@darc.de>
Date:   Thu Oct 7 21:53:07 2021 +0200

    Merge branch 'master' into devel
pull/280/head
Hansi, dl9rdz 2022-01-23 23:33:36 +00:00
rodzic 1a148b6791
commit c03683efa2
23 zmienionych plików z 529 dodań i 622 usunięć

Wyświetl plik

@ -23,7 +23,7 @@ for details on supported boards, and additional setup instructions.
Manufacturer | Model | Position | Temperature | Humidity | Pressure
-------------|-------|----------|-------------|----------|----------
Vaisala | RS92-SGP/NGP | :heavy_check_mark: | :heavy_check_mark: | :x: | :x:
Vaisala | RS92-SGP | :heavy_check_mark: | :heavy_check_mark: | :x: | :x:
Vaisala | RS41-SG/SGP/SGM | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: (for -SGP)
Graw | DFM06/09/17 | :heavy_check_mark: | :heavy_check_mark: | :x: | :x:
Meteomodem | M10 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | Not Sent
@ -45,7 +45,7 @@ course be considered for inclusion :-).
You can download the latest binary automated build for the development and testing branches [here](http://rdzsonde.mooo.com/download.html), the binary includes everything including configuration files so any existing settings will be reset.
To update an existing installatiom to the latest development or master version you can use the [OTA](https://github.com/dl9rdz/rdz_ttgo_sonde/wiki/Other-features#over-the-air-updates) update feature.
To update an existing installation to the latest development or master version you can use the [OTA](https://github.com/dl9rdz/rdz_ttgo_sonde/wiki/Other-features#over-the-air-updates) update feature.
The downloaded .bin file can be flashed to your ESP32 board using [esptool](https://github.com/espressif/esptool) or [ESP32 Download Tool](https://www.espressif.com/en/support/download/other-tools)

Wyświetl plik

@ -43,7 +43,8 @@ AsyncWebServer server(80);
AXP20X_Class axp;
#define PMU_IRQ 35
SemaphoreHandle_t axpSemaphore;
bool pmu_irq = false;
// 0: cleared; 1: set; 2: do not check, also query state of axp via i2c on each loop
uint8_t pmu_irq = 0;
const char *updateHost = "rdzsonde.mooo.com";
int updatePort = 80;
@ -75,7 +76,12 @@ const char *dfmSubtypeStrSH[16] = { NULL, NULL, NULL, NULL, NULL, NULL,
"DFM17", // 0x0D
NULL, NULL
};
// Times in ms, i.e. station: 10 minutes, mobile: 20 seconds
#define APRS_STATION_UPDATE_TIME (10*60*1000)
#define APRS_MOBILE_STATION_UPDATE_TIME (20*1000)
unsigned long time_last_aprs_update = -APRS_STATION_UPDATE_TIME;
#if FEATURE_SONDEHUB
#define SONDEHUB_STATION_UPDATE_TIME (60*60*1000) // 60 min
#define SONDEHUB_MOBILE_STATION_UPDATE_TIME (30*1000) // 30 sec
@ -83,18 +89,19 @@ WiFiClient shclient; // Sondehub v2
int shImportInterval = 0;
char shImport = 0;
unsigned long time_last_update = 0;
#endif
/* SH_LOC_OFF: never send position information to SondeHub
SH_LOC_FIXED: send fixed position (if specified in config) to sondehub
SH_LOC_CHASE: always activate chase mode and send GPS position (if available)
SH_LOC_AUTO: if there is no valid GPS position, or GPS position < MIN_LOC_AUTO_DIST away from known fixed position: use FIXED mode
otherwise, i.e. if there is a valid GPS position and (either no fixed position in config, or GPS position is far away from fixed position), use CHASE mode.
*/
// same constants used for SondeHub and APRS
enum { SH_LOC_OFF, SH_LOC_FIXED, SH_LOC_CHASE, SH_LOC_AUTO };
/* auto mode is chase if valid GPS position and (no fixed location entered OR valid GPS position and distance in lat/lon deg to fixed location > threshold) */
#define MIN_LOC_AUTO_DIST 200 /* meter */
#define SH_LOC_AUTO_IS_CHASE ( gpsPos.valid && ( (isnan(sonde.config.rxlat) || isnan(sonde.config.rxlon) ) || \
calcLatLonDist( gpsPos.lat, gpsPos.lon, sonde.config.rxlat, sonde.config.rxlon ) > MIN_LOC_AUTO_DIST ) )
#endif
extern float calcLatLonDist(float lat1, float lon1, float lat2, float lon2);
// KISS over TCP for communicating with APRSdroid
@ -317,25 +324,6 @@ const char *createQRGForm() {
strcat(ptr, "</script>\n");
strcat(ptr, "<div id=\"divTable\"></div>");
strcat(ptr, "<script> qrgTable() </script>\n");
#if 0
strcat(ptr, "<table><tr><th>ID</th><th>Active</th><th>Freq</th><th>Launchsite</th><th>Mode</th></tr>");
for (int i = 0; i < sonde.config.maxsonde; i++) {
//String s = sondeTypeSelect(i >= sonde.nSonde ? 2 : sonde.sondeList[i].type);
String site = sonde.sondeList[i].launchsite;
sprintf(ptr + strlen(ptr), "<tr><td>%d</td><td><input name=\"A%d\" type=\"checkbox\" %s/></td>"
"<td><input name=\"F%d\" type=\"text\" width=12 value=\"%3.3f\"></td>"
"<td><input name=\"S%d\" type=\"text\" value=\"%s\"></td>"
//"<td><select name=\"T%d\">%s</select></td>",
"<td><input class='stype' name='T%d' value='%c'>",
i + 1,
i + 1, (i < sonde.nSonde && sonde.sondeList[i].active) ? "checked" : "",
i + 1, i >= sonde.nSonde ? 400.000 : sonde.sondeList[i].freq,
i + 1, i >= sonde.nSonde ? " " : sonde.sondeList[i].launchsite,
i + 1, i >= sonde.nSonde ? 2 : sondeTypeChar[sonde.sondeList[i].type] );
//i + 1, s.c_str());
}
strcat(ptr, "</table>");
#endif
//</div><div class=\"footer\"><input type=\"submit\" class=\"update\" value=\"Update\"/>");
HTMLSAVEBUTTON(ptr);
HTMLBODYEND(ptr);
@ -611,110 +599,6 @@ void setupConfigData() {
}
#if 0
struct st_configitems config_list[] = {
/* General config settings */
{"", "Software configuration", -5, NULL},
{"wifi", "Wifi mode (0-Off/1-Client/2-Access Point/3-Debug)", 0, &sonde.config.wifi},
{"debug", "Debug mode (0/1)", 0, &sonde.config.debug},
{"maxsonde", "Maxsonde (max # QRG entries)", 0, &sonde.config.maxsonde},
{"screenfile", "Screen config (0=automatic; 1-5=predefined; other=custom)", 0, &sonde.config.screenfile},
{"display", "Display screens (scan,default,...)", -6, sonde.config.display},
/* Spectrum display settings */
{"spectrum", "Show spectrum (-1=no, 0=forever, >0=seconds)", 0, &sonde.config.spectrum},
{"startfreq", "Startfreq (MHz)", 0, &sonde.config.startfreq},
{"channelbw", "Bandwidth (kHz)", 0, &sonde.config.channelbw},
{"marker", "Spectrum MHz marker", 0, &sonde.config.marker},
{"noisefloor", "Spectrum noisefloor", 0, &sonde.config.noisefloor},
/* decoder settings */
{"", "Receiver configuration", -5, NULL},
{"freqofs", "RX frequency offset (Hz)", 0, &sonde.config.freqofs},
{"rs41.agcbw", "RS41 AGC bandwidth", 0, &sonde.config.rs41.agcbw},
{"rs41.rxbw", "RS41 RX bandwidth", 0, &sonde.config.rs41.rxbw},
{"rs92.rxbw", "RS92 RX (and AGC) bandwidth", 0, &sonde.config.rs92.rxbw},
{"rs92.alt2d", "RS92 2D fix default altitude", 0, &sonde.config.rs92.alt2d},
{"dfm.agcbw", "DFM AGC bandwidth", 0, &sonde.config.dfm.agcbw},
{"dfm.rxbw", "DFM RX bandwidth", 0, &sonde.config.dfm.rxbw},
{"m10m20.agcbw", "M10/M20 AGC bandwidth", 0, &sonde.config.m10m20.agcbw},
{"m10m20.rxbw", "M10/M20 RX bandwidth", 0, &sonde.config.m10m20.rxbw},
{"mp3h.agcbw", "MP3H AGC bandwidth", 0, &sonde.config.mp3h.agcbw},
{"mp3h.rxbw", "MP3H RX bandwidth", 0, &sonde.config.mp3h.rxbw},
{"ephftp", "FTP for eph (RS92)", 39, &sonde.config.ephftp},
{"", "Data feed configuration", -5, NULL},
/* APRS settings */
{"call", "Call", 8, sonde.config.call},
{"passcode", "Passcode", 0, &sonde.config.passcode},
/* KISS tnc settings */
{"kisstnc.active", "KISS TNC (port 14590) (needs reboot)", 0, &sonde.config.kisstnc.active},
{"kisstnc.idformat", "KISS TNC ID Format", -2, &sonde.config.kisstnc.idformat},
/* AXUDP settings */
{"axudp.active", "AXUDP active", -3, &sonde.config.udpfeed.active},
{"axudp.host", "AXUDP Host", 63, sonde.config.udpfeed.host},
{"axudp.port", "AXUDP Port", 0, &sonde.config.udpfeed.port},
{"axudp.idformat", "DFM ID Format", -2, &sonde.config.udpfeed.idformat},
{"axudp.highrate", "Rate limit", 0, &sonde.config.udpfeed.highrate},
/* APRS TCP settings, current not used */
{"tcp.active", "APRS TCP active", -3, &sonde.config.tcpfeed.active},
{"tcp.host", "ARPS TCP Host", 63, sonde.config.tcpfeed.host},
{"tcp.port", "APRS TCP Port", 0, &sonde.config.tcpfeed.port},
{"tcp.idformat", "DFM ID Format", -2, &sonde.config.tcpfeed.idformat},
{"tcp.highrate", "Rate limit", 0, &sonde.config.tcpfeed.highrate},
#if FEATURE_MQTT
/* MQTT */
{"mqtt.active", "MQTT Active (needs reboot)", 0, &sonde.config.mqtt.active},
{"mqtt.id", "MQTT client ID", 63, &sonde.config.mqtt.id},
{"mqtt.host", "MQTT server hostname", 63, &sonde.config.mqtt.host},
{"mqtt.port", "MQTT Port", 0, &sonde.config.mqtt.port},
{"mqtt.username", "MQTT Username", 63, &sonde.config.mqtt.username},
{"mqtt.password", "MQTT Password", 63, &sonde.config.mqtt.password},
{"mqtt.prefix", "MQTT Prefix", 63, &sonde.config.mqtt.prefix},
#endif
/* Hardware dependeing settings */
{"", "Hardware configuration (requires reboot)", -5, NULL},
{"disptype", "Display type (0=OLED/SSD1306, 1=ILI9225, 2=OLED/SH1106, 3=ILI9341, 4=ILI9342)", 0, &sonde.config.disptype},
{"norx_timeout", "No-RX-Timeout in seconds (-1=disabled)", 0, &sonde.config.norx_timeout},
{"oled_sda", "OLED SDA/TFT SDA", 0, &sonde.config.oled_sda},
{"oled_scl", "OLED SCL/TFT CLK", 0, &sonde.config.oled_scl},
{"oled_rst", "OLED RST/TFT RST (needs reboot)", 0, &sonde.config.oled_rst},
{"tft_rs", "TFT RS", 0, &sonde.config.tft_rs},
{"tft_cs", "TFT CS", 0, &sonde.config.tft_cs},
{"tft_orient", "TFT orientation (0/1/2/3), OLED flip: 3", 0, &sonde.config.tft_orient},
{"tft_spifreq", "TFT SPI speed", 0, &sonde.config.tft_spifreq},
{"button_pin", "Button input port", -4, &sonde.config.button_pin},
{"button2_pin", "Button 2 input port", -4, &sonde.config.button2_pin},
{"button2_axp", "Use AXP192 PWR as Button 2", 0, &sonde.config.button2_axp},
{"touch_thresh", "Touch button threshold<br>(0 for calib mode)", 0, &sonde.config.touch_thresh},
{"power_pout", "Power control port", 0, &sonde.config.power_pout},
{"led_pout", "LED output port", 0, &sonde.config.led_pout},
{"gps_rxd", "GPS RXD pin (-1 to disable)", 0, &sonde.config.gps_rxd},
{"gps_txd", "GPS TXD pin (not really needed)", 0, &sonde.config.gps_txd},
{"batt_adc", "Battery measurement pin", 0, &sonde.config.batt_adc},
#if 1
{"sx1278_ss", "SX1278 SS", 0, &sonde.config.sx1278_ss},
{"sx1278_miso", "SX1278 MISO", 0, &sonde.config.sx1278_miso},
{"sx1278_mosi", "SX1278 MOSI", 0, &sonde.config.sx1278_mosi},
{"sx1278_sck", "SX1278 SCK", 0, &sonde.config.sx1278_sck},
#endif
{"mdnsname", "mDNS name", 14, &sonde.config.mdnsname},
#if FEATURE_SONDEHUB
/* SondeHub settings */
{"", "SondeHub settings", -5, NULL},
{"sondehub.active", "SondeHub reporting (0=disabled, 1=active)", 0, &sonde.config.sondehub.active},
{"sondehub.chase", "SondeHub location reporting (0=off, 1=fixed, 2=chase/GPS, 3=auto)", 0, &sonde.config.sondehub.chase},
{"sondehub.host", "SondeHub host (DO NOT CHANGE)", 63, &sonde.config.sondehub.host},
{"sondehub.callsign", "Callsign", 63, &sonde.config.sondehub.callsign},
{"sondehub.lat", "Latitude (optional, required to show station on SondeHub Tracker)", -7, &sonde.config.sondehub.lat},
{"sondehub.lon", "Longitude (optional, required to show station on SondeHub Tracker)", -7, &sonde.config.sondehub.lon},
{"sondehub.alt", "Altitude (optional, visible on SondeHub tracker)", 19, &sonde.config.sondehub.alt},
{"sondehub.antenna", "Antenna (optional, visisble on SondeHub tracker)", 63, &sonde.config.sondehub.antenna},
{"sondehub.email", "SondeHub email (optional, only used to contact in case of upload errors)", 63, &sonde.config.sondehub.email},
{"sondehub.fimport", "SondeHub freq import (interval/maxdist/maxage [min/km/min])", 18, &sonde.config.sondehub.fimport},
};
#endif
#else
struct st_configitems config_list[] = {
/* General config settings */
{"wifi", 0, &sonde.config.wifi},
@ -745,22 +629,23 @@ struct st_configitems config_list[] = {
{"mp3h.rxbw", 0, &sonde.config.mp3h.rxbw},
{"ephftp", 39, &sonde.config.ephftp},
/* APRS settings */
{"call", 8, sonde.config.call},
{"call", 9, sonde.config.call},
{"passcode", 0, &sonde.config.passcode},
/* KISS tnc settings */
{"kisstnc.active", 0, &sonde.config.kisstnc.active},
{"kisstnc.idformat", -2, &sonde.config.kisstnc.idformat},
/* AXUDP settings */
{"axudp.active", -3, &sonde.config.udpfeed.active},
{"axudp.host", 63, sonde.config.udpfeed.host},
{"axudp.port", 0, &sonde.config.udpfeed.port},
{"axudp.idformat", -2, &sonde.config.udpfeed.idformat},
{"axudp.highrate", 0, &sonde.config.udpfeed.highrate},
/* APRS TCP settings, current not used */
{"tcp.active", -3, &sonde.config.tcpfeed.active},
{"tcp.host", 63, sonde.config.tcpfeed.host},
{"tcp.port", 0, &sonde.config.tcpfeed.port},
{"tcp.idformat", -2, &sonde.config.tcpfeed.idformat},
{"tcp.chase", 0, &sonde.config.chase},
{"tcp.comment", 30, sonde.config.comment},
{"tcp.objcall", 9, sonde.config.objcall},
{"tcp.beaconsym", 4, sonde.config.beaconsym},
{"tcp.highrate", 0, &sonde.config.tcpfeed.highrate},
#if FEATURE_CHASEMAPPER
/* Chasemapper settings */
@ -817,75 +702,12 @@ struct st_configitems config_list[] = {
{"sondehub.fiactive", 0, &sonde.config.sondehub.fiactive},
{"sondehub.fiinterval", 0, &sonde.config.sondehub.fiinterval},
{"sondehub.fimaxdist", 0, &sonde.config.sondehub.fimaxdist},
{"sondehub.fimaxage", 0, &sonde.config.sondehub.fimaxage},
{"sondehub.fimaxage", -7, &sonde.config.sondehub.fimaxage},
#endif
};
#endif
const int N_CONFIG = (sizeof(config_list) / sizeof(struct st_configitems));
#if 0
// old code, no longer needed (in js now)
void addConfigStringEntry(char *ptr, int idx, const char *label, int len, char *field) {
sprintf(ptr + strlen(ptr), "<tr><td>%s</td><td><input name=\"CFG%d\" type=\"text\" value=\"%s\"/></td></tr>\n",
label, idx, field);
}
void addConfigNumEntry(char *ptr, int idx, const char *label, int *value) {
sprintf(ptr + strlen(ptr), "<tr><td>%s</td><td><input name=\"CFG%d\" type=\"text\" value=\"%d\"/></td></tr>\n",
label, idx, *value);
}
void addConfigDblEntry(char *ptr, int idx, const char *label, double * value) {
sprintf(ptr + strlen(ptr), "<tr><td>%s</td><td><input name=\"CFG%d\" type=\"text\" value=\"%f\"/></td></tr>\n",
label, idx, *value);
}
void addConfigButtonEntry(char *ptr, int idx, const char *label, int *value) {
int v = *value, ck = 0;
if (v == 255) v = -1;
if (v != -1) {
if (v & 128) ck = 1;
v = v & 127;
}
sprintf(ptr + strlen(ptr), "<tr><td>%s</td><td><input name=\"CFG%d\" type=\"text\" size=\"3\" value=\"%d\"/>",
label, idx, v);
sprintf(ptr + strlen(ptr), "<input type=\"checkbox\" name=\"TO%d\"%s> Touch </td></tr>\n", idx, ck ? " checked" : "");
}
void addConfigTypeEntry(char *ptr, int idx, const char *label, int *value) {
// TODO
}
void addConfigOnOffEntry(char *ptr, int idx, const char *label, int *value) {
// TODO
}
void addConfigSeparatorEntry(char *ptr) {
strcat(ptr, "<tr><td colspan=\"2\" class=\"divider\"><hr /></td></tr>\n");
}
void addConfigHeading(char *ptr, const char *label) {
strcat(ptr, "<tr><th colspan=\"2\">");
strcat(ptr, label);
strcat(ptr, "</th></tr>\n");
}
void addConfigInt8List(char *ptr, int idx, const char *label, int8_t *list) {
sprintf(ptr + strlen(ptr), "<tr><td>%s using /screens%d.txt", label, Display::getScreenIndex(sonde.config.screenfile));
for (int i = 0; i < disp.nLayouts; i++) {
sprintf(ptr + strlen(ptr), "<br>%d=%s", i, disp.layouts[i].label);
}
sprintf(ptr + strlen(ptr), "</td><td><input name=\"CFG%d\" type=\"text\" value=\"", idx);
if (*list == -1) {
strcat(ptr, "0");
}
else {
sprintf(ptr + strlen(ptr), "%d", list[0]);
list++;
}
while (*list != -1) {
sprintf(ptr + strlen(ptr), ",%d", *list);
list++;
}
strcat(ptr, "\"/></td></tr>\n");
}
#endif
const char *createConfigForm() {
char *ptr = message;
strcpy(ptr, HTMLHEAD); strcat(ptr, "</head>");
@ -932,43 +754,6 @@ const char *createConfigForm() {
strcat(ptr, "\");\n");
}
strcat(ptr, "configTable();\n </script>");
#if 0
strcat(ptr, "<table><tr><th>Option</th><th>Value</th></tr>");
for (int i = 0; i < N_CONFIG; i++) {
Serial.printf("%d: %s -- %d\n", i, config_list[i].label, strlen(ptr));
switch (config_list[i].type) {
case -5: // Heading
addConfigHeading(ptr, config_list[i].label);
break;
case -6: // List of int8 values
addConfigInt8List(ptr, i, config_list[i].label, (int8_t *)config_list[i].data);
break;
case -3: // on/off
addConfigOnOffEntry(ptr, i, config_list[i].label, (int *)config_list[i].data);
break;
case -2: // DFM format
addConfigTypeEntry(ptr, i, config_list[i].label, (int *)config_list[i].data);
break;
case -1:
addConfigSeparatorEntry(ptr);
break;
case 0:
addConfigNumEntry(ptr, i, config_list[i].label, (int *)config_list[i].data);
break;
case -4:
addConfigButtonEntry(ptr, i, config_list[i].label, (int *)config_list[i].data);
break;
case -7: /* double for lat/lon */
addConfigDblEntry(ptr, i, config_list[i].label, (double *)config_list[i].data);
break;
default:
addConfigStringEntry(ptr, i, config_list[i].label, config_list[i].type, (char *)config_list[i].data);
break;
}
}
strcat(ptr, "</table>");
//</div><div class=\"footer\"><input type=\"submit\" class=\"update\" value=\"Update\"/>");
#endif
HTMLSAVEBUTTON(ptr);
HTMLBODYEND(ptr);
Serial.printf("Config form: size=%d bytes\n", strlen(message));
@ -998,12 +783,6 @@ const char *handleConfigPost(AsyncWebServerRequest * request) {
String strlabel = request->getParam(i)->name();
const char *label = strlabel.c_str();
if (label[strlen(label) - 1] == '#') continue;
#if 0
if (strncmp(label, "CFG", 3) != 0) continue;
int idx = atoi(label + 3);
Serial.printf("idx is %d\n", idx);
if (config_list[idx].type == -1) continue; // skip separator entries, should not happen
#endif
AsyncWebParameter *value = request->getParam(label, true);
if (!value) continue;
String strvalue = value->value();
@ -1016,19 +795,6 @@ const char *handleConfigPost(AsyncWebServerRequest * request) {
strvalue = String(i);
}
}
#if 0
if (config_list[idx].type == -4) { // input button port with "touch" checkbox
char tmp[10];
snprintf(tmp, 10, "TO%d", idx);
AsyncWebParameter *touch = request->getParam(tmp, true);
if (touch) {
int i = atoi(strvalue.c_str());
if (i != -1 && i != 255) i += 128;
strvalue = String(i);
}
}
Serial.printf("Processing %s=%s\n", config_list[idx].name, strvalue.c_str());
#endif
Serial.printf("Processing %s=%s\n", label, strvalue.c_str());
//int wlen = f.printf("%s=%s\n", config_list[idx].name, strvalue.c_str());
int wlen = f.printf("%s=%s\n", label, strvalue.c_str());
@ -1370,21 +1136,6 @@ const char *sendGPX(AsyncWebServerRequest * request) {
return message;
}
#if 0
// no longer supported
// tcp socket / json for android app is used now
void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len) {
if (type == WS_EVT_CONNECT) {
Serial.println("Websocket client connection received");
client->text("Hello from ESP32 Server");
//globalClient = client;
} else if (type == WS_EVT_DISCONNECT) {
Serial.println("Client disconnected");
globalClient = NULL;
}
}
#endif
const char* PARAM_MESSAGE = "message";
void SetupAsyncServer() {
@ -1757,21 +1508,21 @@ void initGPS() {
if (testfile && !testfile.isDirectory()) {
testfile.close();
Serial.println("GPS resetting baud to 9k6...");
/* TODO: debug:
* Sometimes I have seen the Serial2.begin to cause a reset
* Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
* Backtrace: 0x40081d2f:0x3ffc11b0 0x40087969:0x3ffc11e0 0x4000bfed:0x3ffb1db0 0x4008b7dd:0x3ffb1dc0 0x4017afee:0x3ffb1de0 0x4017b04b:0x3ffb1e20 0x4010722b:0x3ffb1e50 0x40107303:0x3ffb1e70 0x4010782d:0x3ffb1e90 0x40103814:0x3ffb1ed0 0x400d8772:0x3ffb1f10 0x400d9057:0x3ffb1f60 0x40107aca:0x3ffb1fb0 0x4008a63e:0x3ffb1fd0
* #0 0x40081d2f:0x3ffc11b0 in _uart_isr at /Users/hansi/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:464
* #1 0x40087969:0x3ffc11e0 in _xt_lowint1 at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/xtensa_vectors.S:1154
* #2 0x4000bfed:0x3ffb1db0 in ?? ??:0
* #3 0x4008b7dd:0x3ffb1dc0 in vTaskExitCritical at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c:3507
* #4 0x4017afee:0x3ffb1de0 in esp_intr_alloc_intrstatus at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/intr_alloc.c:784
* #5 0x4017b04b:0x3ffb1e20 in esp_intr_alloc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/intr_alloc.c:784
* #6 0x4010722b:0x3ffb1e50 in uartEnableInterrupt at /Users/hansi/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:464
* #7 0x40107303:0x3ffb1e70 in uartAttachRx at /Users/hansi/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:464
* #8 0x4010782d:0x3ffb1e90 in uartBegin at /Users/hansi/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:464
* #9 0x40103814:0x3ffb1ed0 in HardwareSerial::begin(unsigned long, unsigned int, signed char, signed char, bool, unsigned long) at /Users/hansi/.platformio/packages/framework-arduinoespressif32/cores/esp32/HardwareSerial.cpp:190
*/
/* TODO: debug:
Sometimes I have seen the Serial2.begin to cause a reset
Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
Backtrace: 0x40081d2f:0x3ffc11b0 0x40087969:0x3ffc11e0 0x4000bfed:0x3ffb1db0 0x4008b7dd:0x3ffb1dc0 0x4017afee:0x3ffb1de0 0x4017b04b:0x3ffb1e20 0x4010722b:0x3ffb1e50 0x40107303:0x3ffb1e70 0x4010782d:0x3ffb1e90 0x40103814:0x3ffb1ed0 0x400d8772:0x3ffb1f10 0x400d9057:0x3ffb1f60 0x40107aca:0x3ffb1fb0 0x4008a63e:0x3ffb1fd0
#0 0x40081d2f:0x3ffc11b0 in _uart_isr at /Users/hansi/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:464
#1 0x40087969:0x3ffc11e0 in _xt_lowint1 at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/xtensa_vectors.S:1154
#2 0x4000bfed:0x3ffb1db0 in ?? ??:0
#3 0x4008b7dd:0x3ffb1dc0 in vTaskExitCritical at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c:3507
#4 0x4017afee:0x3ffb1de0 in esp_intr_alloc_intrstatus at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/intr_alloc.c:784
#5 0x4017b04b:0x3ffb1e20 in esp_intr_alloc at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/intr_alloc.c:784
#6 0x4010722b:0x3ffb1e50 in uartEnableInterrupt at /Users/hansi/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:464
#7 0x40107303:0x3ffb1e70 in uartAttachRx at /Users/hansi/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:464
#8 0x4010782d:0x3ffb1e90 in uartBegin at /Users/hansi/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:464
#9 0x40103814:0x3ffb1ed0 in HardwareSerial::begin(unsigned long, unsigned int, signed char, signed char, bool, unsigned long) at /Users/hansi/.platformio/packages/framework-arduinoespressif32/cores/esp32/HardwareSerial.cpp:190
*/
Serial2.begin(115200, SERIAL_8N1, sonde.config.gps_rxd, sonde.config.gps_txd);
Serial2.write(ubx_set9k6, sizeof(ubx_set9k6));
delay(200);
@ -1927,7 +1678,7 @@ void IRAM_ATTR buttonISR() {
button1.numberKeyPresses += 1;
button1.keydownTime = now;
} else { //Button up
if(!b1wasdown) return;
if (!b1wasdown) return;
b1wasdown = false;
unsigned long now = my_millis();
if (button1.doublepress == -1) return; // key was never pressed before, ignore button up
@ -2008,13 +1759,15 @@ void handlePMUirq() {
button2.pressed = KP_MID;
button2.keydownTime = my_millis();
}
pmu_irq = false;
if (pmu_irq != 2) {
pmu_irq = 0;
}
axp.clearIRQ();
xSemaphoreGive( axpSemaphore );
}
} else {
Serial.println("handlePMIirq() called. THIS SHOULD NOT HAPPEN w/o button2_axp set");
pmu_irq = false; // prevent main loop blocking
pmu_irq = 0; // prevent main loop blocking
}
}
@ -2171,22 +1924,54 @@ void setup()
// Display backlight on M5 Core2
axp.setPowerOutPut(AXP192_DCDC3, AXP202_ON);
axp.setDCDC3Voltage(3300);
// SetBusPowerMode(0):
// #define AXP192_GPIO0_CTL (0x90)
// #define AXP192_GPIO0_VOL (0x91)
// #define AXP202_LDO234_DC23_CTL (0x12)
// The axp class lacks a functino to set GPIO0 VDO to 3.3V (as is done by original M5Stack software)
// so do this manually (default value 2.8V did not have the expected effect :))
// data = Read8bit(0x91);
// write1Byte(0x91, (data & 0X0F) | 0XF0);
uint8_t reg;
Wire.beginTransmission((uint8_t)AXP192_SLAVE_ADDRESS);
Wire.write(AXP192_GPIO0_VOL);
Wire.endTransmission();
Wire.requestFrom(AXP192_SLAVE_ADDRESS, 1);
reg = Wire.read();
reg = (reg&0x0F) | 0xF0;
Wire.beginTransmission((uint8_t)AXP192_SLAVE_ADDRESS);
Wire.write(AXP192_GPIO0_VOL);
Wire.write(reg);
Wire.endTransmission();
// data = Read8bit(0x90);
// Write1Byte(0x90, (data & 0XF8) | 0X02)
axp.setGPIOMode(AXP_GPIO_0, AXP_IO_LDO_MODE); // disable AXP supply from VBUS
pmu_irq = 2; // IRQ pin is not connected on Core2
// data = Read8bit(0x12); //read reg 0x12
// Write1Byte(0x12, data | 0x40); // enable 3,3V => 5V booster
// this is done below anyway: axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
axp.adc1Enable(AXP202_ACIN_VOL_ADC1, 1);
axp.adc1Enable(AXP202_ACIN_CUR_ADC1, 1);
} else {
// GPS on T-Beam, buzzer on M5 Core2
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON);
axp.adc1Enable(AXP202_VBUS_VOL_ADC1, 1);
axp.adc1Enable(AXP202_VBUS_CUR_ADC1, 1);
}
axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON);
axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON);
axp.setDCDC1Voltage(3300);
axp.adc1Enable(AXP202_VBUS_VOL_ADC1, 1);
axp.adc1Enable(AXP202_VBUS_CUR_ADC1, 1);
axp.adc1Enable(AXP202_BATT_CUR_ADC1, 1);
if (sonde.config.button2_axp) {
pinMode(PMU_IRQ, INPUT_PULLUP);
attachInterrupt(PMU_IRQ, [] {
pmu_irq = true;
}, FALLING);
if (sonde.config.button2_axp ) {
if (pmu_irq != 2) {
pinMode(PMU_IRQ, INPUT_PULLUP);
attachInterrupt(PMU_IRQ, [] {
pmu_irq = 1;
}, FALLING);
}
//axp.enableIRQ(AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ | AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ, 1);
axp.enableIRQ( AXP202_PEK_LONGPRESS_IRQ | AXP202_PEK_SHORTPRESS_IRQ, 1 );
axp.clearIRQ();
@ -2545,7 +2330,7 @@ void loopDecoder() {
// first check if ID and position lat+lonis ok
if (s->d.validID && ((s->d.validPos & 0x03) == 0x03)) {
char *str = aprs_senddata(s, sonde.config.call, sonde.config.udpfeed.symbol);
char *str = aprs_senddata(s, sonde.config.call, sonde.config.objcall, sonde.config.udpfeed.symbol);
if (connected) {
char raw[201];
int rawlen = aprsstr_mon2raw(str, raw, APRS_MAXLEN);
@ -2569,6 +2354,7 @@ void loopDecoder() {
}
else if ( tcpclient.connected() ) {
unsigned long now = millis();
Serial.printf("aprs: now-last = %ld\n", (now-lasttcp));
if ( (now - lasttcp) > sonde.config.tcpfeed.highrate * 1000L ) {
strcat(str, "\r\n");
Serial.print(str);
@ -2601,6 +2387,10 @@ void loopDecoder() {
sondehub_finish_data(&shclient, s, &sonde.config.sondehub);
#endif
}
// Send own position periodically
if (sonde.config.tcpfeed.active) {
aprs_station_update();
}
// always send data, even if not valid....
if (rdzclient.connected()) {
Serial.println("Sending position via TCP as rdzJSON");
@ -2620,12 +2410,12 @@ void loopDecoder() {
*gps = 0;
}
//maintain backwords compatibility
float lat = isnan(s->d.lat)?0:s->d.lat;
float lon = isnan(s->d.lon)?0:s->d.lon;
float alt = isnan(s->d.alt)?-1:s->d.alt;
float vs = isnan(s->d.vs)?0:s->d.vs;
float hs = isnan(s->d.hs)?0:s->d.hs;
float dir = isnan(s->d.dir)?0:s->d.dir;
float lat = isnan(s->d.lat) ? 0 : s->d.lat;
float lon = isnan(s->d.lon) ? 0 : s->d.lon;
float alt = isnan(s->d.alt) ? -1 : s->d.alt;
float vs = isnan(s->d.vs) ? 0 : s->d.vs;
float hs = isnan(s->d.hs) ? 0 : s->d.hs;
float dir = isnan(s->d.dir) ? 0 : s->d.dir;
//
int len = snprintf(raw, 1024, "{"
@ -3445,6 +3235,47 @@ void loop() {
}
void aprs_station_update() {
int chase = sonde.config.chase;
// automatically decided if CHASE or FIXED mode is used (for config AUTO)
if (chase == SH_LOC_AUTO) {
if (SH_LOC_AUTO_IS_CHASE) chase = SH_LOC_CHASE; else chase = SH_LOC_FIXED;
}
unsigned long time_now = millis();
unsigned long time_delta = time_now - time_last_aprs_update;
unsigned long update_time = (chase == SH_LOC_CHASE) ? APRS_MOBILE_STATION_UPDATE_TIME : APRS_STATION_UPDATE_TIME;
Serial.printf("aprs_station_update: delta: %ld, update in %ld\n", time_delta, update_time);
if (time_delta < update_time) return;
Serial.println("Update is due!!");
float lat, lon;
if (chase == SH_LOC_FIXED) {
// fixed location
lat = sonde.config.rxlat;
lon = sonde.config.rxlon;
if (isnan(lat) || isnan(lon)) return;
} else {
if (gpsPos.valid && gpsPos.lat != 0 && gpsPos.lon != 0) {
lat = gpsPos.lat;
lon = gpsPos.lon;
} else {
return;
}
}
Serial.printf("Really updating!! (objcall is %s)", sonde.config.objcall);
char *bcn = aprs_send_beacon(sonde.config.call, lat, lon, sonde.config.beaconsym + ((chase==SH_LOC_CHASE)?2:0), sonde.config.comment);
if ( tcpclient.disconnected()) {
tcpclient.connect(sonde.config.tcpfeed.host, sonde.config.tcpfeed.port);
}
if ( tcpclient.connected() ) {
strcat(bcn, "\r\n");
Serial.println("****BEACON****");
Serial.print(bcn);
tcpclient.write(bcn, strlen(bcn));
time_last_aprs_update = time_now;
}
}
#if FEATURE_SONDEHUB
// Sondehub v2 DB related codes
/*
@ -3555,7 +3386,7 @@ void sondehub_station_update(WiFiClient * client, struct st_sondehub * conf) {
// At least, do this safely. See Notes-on-Using-WiFiClient.txt for details
// If any of the client->print failed before (remote end closed connection),
// then calling client->read will cause a LoadProhibited exception
if(client->connected()) {
if (client->connected()) {
String response = client->readString();
Serial.println(response);
Serial.println("Response done...");
@ -3641,9 +3472,11 @@ void sondehub_reply_handler(WiFiClient * client) {
// also handle periodic station updates here...
// interval check moved to sondehub_station_update to avoid having to calculate distance in auto mode twice
if (shState == SH_CONN_IDLE || shState == SH_DISCONNECTED ) {
// (do not set station update while a telemetry report is being sent
sondehub_station_update(&shclient, &sonde.config.sondehub);
if (sonde.config.sondehub.active) {
if (shState == SH_CONN_IDLE || shState == SH_DISCONNECTED ) {
// (do not set station update while a telemetry report is being sent
sondehub_station_update(&shclient, &sonde.config.sondehub);
}
}
}

Wyświetl plik

@ -35,17 +35,18 @@ var cfgs = [
[ "call", "Call"],
[ "passcode", "Passcode"],
[ "kisstnc.active", "KISS TNC (port 14590) (needs reboot)"],
[ "kisstnc.idformat", "KISS TNC ID format"],
[ "axudp.active", "AXUDP active"],
[ "axudp.host", "AXUDP host"],
[ "axudp.port", "AXUDP port"],
[ "axudp.idformat", "DFM ID format"],
[ "axudp.highrate", "Rate limit"],
[ "tcp.active", "APRS TCP active"],
[ "tcp.host", "ARPS TCP host"],
[ "tcp.host", "APRS TCP host"],
[ "tcp.port", "APRS TCP port"],
[ "tcp.idformat", "DFM ID format"],
[ "tcp.highrate", "Rate limit"],
[ "tcp.objcall", "APRS object call"],
[ "tcp.beaconsym", "APRS tracker symbol"],
[ "tcp.chase", "APRS location reporting (0=off, 1=fixed, 2=chase/GPS, 3=auto)"],
[ "tcp.comment", "APRS location comment"],
[ "", "MQTT data feed configuration", "https://github.com/dl9rdz/rdz_ttgo_sonde/wiki/MQTT-configuration"],
[ "mqtt.active", "MQTT active (needs reboot)"],
[ "mqtt.id", "MQTT client ID"],

Wyświetl plik

@ -97,17 +97,19 @@ axudp.host=192.168.42.20
axudp.port=9002
axudp.symbol=/O
axudp.highrate=1
axudp.idformat=0
#-------------------------------#
# maybe some time in the future
# connect to some aprs server
#-------------------------------#
# currently simply not implemented, no need to put anything here anyway
tcp.active=0
tcp.host=radiosondy.info
tcp.port=14590
tcp.symbol=/O
tcp.highrate=20
tcp.idformat=0
# send beacon (possibly with different call or SSID)
tcp.chase=0
tcp.objcall=
tcp.beaconsym=/`/(
tcp.comment=
#-------------------------------#
# mqtt settings
#-------------------------------#

Wyświetl plik

@ -14,11 +14,20 @@ $(document).ready(function(){
L.control.scale().addTo(map);
L.control.attribution({prefix:false}).addTo(map);
var osm = L.tileLayer('https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png', {
attribution: '<div><a href="https://leafletjs.com/">Leaflet</a> &middot; Map: <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a></div>',
minZoom: 1,
maxZoom: 19
});
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
var osm = L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
minZoom: 1,
maxZoom: 19
});
} else {
var osm = L.tileLayer('https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png', {
attribution: '<div><a href="https://leafletjs.com/">Leaflet</a> &middot; Map: <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a></div>',
minZoom: 1,
maxZoom: 19
});
}
var esri = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution: '<div><a href="https://leafletjs.com/">Leaflet</a> &middot; Map: <a href="https://www.esri.com/">Esri</a> &middot; Earthstar Geographics</div>',
minZoom: 1,

Wyświetl plik

@ -14,10 +14,4 @@
405.900 4 + Bergen_2
405.100 4 + Meppen_2
405.300 4 - Essen
403.330 9 - TrUebPl
403.450 9 - TrUebPl
403.470 9 - TrUebPl
403.850 9 - TrUebPl
403.870 9 - TrUebPl
403.890 9 - TrUebPl
# end

Wyświetl plik

@ -115,7 +115,7 @@ timeaction=#,D,+
0,5=S#:
0,9=T
3,0=F MHz
5,0=S
5,0,16=S
7,5=n
############

Wyświetl plik

@ -111,217 +111,220 @@
###########
@ScannerTFT-D
timer=-1,0,0
key1action=D,#,F,W
key2action=#,#,#,#
key1action=F,#,#,W
key2action=>,#,#,#
timeaction=#,D,+
scale=11,10
fonts=0,2
color=B0B0B0
0,0=Xsuche..
color=6C757D
3,0=xStartort
color=B0B0B0
4,0=S
color=6C757D
3,15=xFreq. Platz
color=B0B0B0
4,15,23=S#
color=6C757D
6,0=xTyp
color=B0B0B0
7,0,5=T
color=6C757D
6,15=xFrequenz
color=B0B0B0
7,15=F
color=6C757D
28,0=Scanner
color=FFFFFF
0,0.3=XSuche...
color=79CDCD
3,0.3=xFreq. Platz
color=FFFFFF
4,0.3,3=S#
color=79CDCD,0
6,0.3=xStartort
color=FFFFFF
7,0.3,20=S
color=79CDCD,0
9,0.3=xTyp
color=FFFFFF
10,0.33,5=T
color=79CDCD
9,15=xFrequenz
color=FFFFFF
10,15=F
color=79CDCD
28,0.3=xScanner
28,9=n
28,21=bVV
############
@MainTFT-D
timer=-1,-1,-1
key1action=>,0,F,W
key1action=0,#,F,W
key2action=+,#,#,#
timeaction=#,#,0
scale=11,10
fonts=0,2
color=6C757D
0,0=xSerial
0,6=t
color=B0B0B0
1,0=Is
color=6C757D
color=79CDCD
0,0.3=xSerial
0,6,10=t
color=FFFFFF
1,0.3=Is
color=79CDCD
0,14=xFreq.
0,17.5=s
color=B0B0B0
color=FFFFFF
1,14=F
color=6C757D
3,0=xLatitude
color=B0B0B0
4,0,10=L
color=6C757D
color=79CDCD
3,0.3=xLatitude
color=FFFFFF
4,0.3,10=L
color=79CDCD
3,14=xLongitude
color=B0B0B0
color=FFFFFF
4,14,23=O
color=6C757D
6,0=xHoriz. Geschw.
color=B0B0B0
7,0,10=Hkkm/h
color=6C757D
color=79CDCD
6,0.3=xHoriz. Geschw.
color=FFFFFF
7,0.3,10=Hkkm/h
color=79CDCD
6,14=xVert. Geschw.
color=B0B0B0
7,13.5,23=Vm/s
color=6C757D
color=FFFFFF
7,14,23=Vm/s
color=79CDCD
9.5,14=xHoehe Sonde
color=ffff00
10.5,13.5,23=A
10.7,14,23=A
color=ffff00,000033
9,1=g0CCS,45,ffff00,000044,4,55ff55,4,eeaa00
color=bbbbbb,000000
color=6C757D
color=79CDCD
12.5,14=xHoehe RX
color=ffff00
13.5,14=GH
color=6C757D
15.5,14=xEntfernung
13.5,14,23=GH
color=79CDCD
15.5,14=xTimer
color=ffff00
16.5,14,23=GD
color=6C757D
19,0=xTimer
color=B0B0B0
20,0,10=Kc4
color=6C757D
16.5,14,23=Kc4
fonts=0,8
color=FFFFFF
18.7,0,-12.3=GD
fonts=0,2
color=79CDCD
19,14=xRSSI
color=B0B0B0
color=FFFFFF
20,14,23=R
color=6C757D
22,0=xLufttemperatur
color=B0B0B0
23,0,10=Mt°C
color=6C757D
color=79CDCD
22,0.3=xLufttemperatur
color=FFFFFF
23,0.3,10=Mt°C
color=79CDCD
22,14=xLuftfeuchtigkeit
color=B0B0B0
color=FFFFFF
23,14,23=Mh%rH
color=6C757D
25,0=xLuftdruck
color=B0B0B0
26,0,10=MphPa
color=6C757D
color=79CDCD
25,0.3=xLuftdruck
color=FFFFFF
26,0.3,10=MphPa
color=79CDCD
25,14=xZellenspannung
color=B0B0B0
color=FFFFFF
26,14,23=MbV
color=6C757D
28,0=Q
color=FFFFFF
28,0.3=Q
color=79CDCD
28,13=c
28,21=bVV
###########
@ScannerTFT-E
timer=-1,0,0
key1action=D,#,F,W
key2action=#,#,#,#
key1action=F,#,#,W
key2action=>,#,#,#
timeaction=#,D,+
scale=11,10
fonts=0,2
color=B0B0B0
0,0=XScan...
color=6C757D
3,0=xLaunchsize
color=B0B0B0
4,0=S
color=6C757D
3,15=xFreq.index
color=B0B0B0
4,15,23=S#
color=6C757D
6,0=xType
color=B0B0B0
7,0,5=T
color=6C757D
color=FFFFFF
0,0.3=XScan...
color=79CDCD
3,0.3=xFreq. index
color=FFFFFF
4,0.3,3=S#
color=79CDCD,0
6,0.3=xLaunchsize
color=FFFFFF
7,0.3,20=S
color=79CDCD,0
9,0.3=xType
color=FFFFFF
10,0.33,5=T
color=79CDCD
6,15=xFrequency
color=B0B0B0
color=FFFFFF
7,15=F
color=6C757D
28,0=Scanner
color=79CDCD
28,0.3=xScanner
28,9=n
28,21=bVV
############
@MainTFT
timer=-1,-1,-1
key1action=>,0,F,W
key1action=0,#,F,W
key2action=+,#,#,#
timeaction=#,#,0
scale=11,10
fonts=0,2
color=6C757D
0,0=xSerial
0,6=t
color=B0B0B0
1,0=Is
color=6C757D
color=79CDCD
0,0.3=xSerial
0,6,10=t
color=FFFFFF
1,0.3=Is
color=79CDCD
0,14=xFreq.
0,17.5=s
color=B0B0B0
color=FFFFFF
1,14=F
color=6C757D
3,0=xLatitude
color=B0B0B0
4,0,10=L
color=6C757D
color=79CDCD
3,0.3=xLatitude
color=FFFFFF
4,0.3,10=L
color=79CDCD
3,14=xLongitude
color=B0B0B0
color=FFFFFF
4,14,23=O
color=6C757D
6,0=xHor.Velocity
color=B0B0B0
7,0,10=Hkkm/h
color=6C757D
color=79CDCD
6,0.3=xHor.Velocity
color=FFFFFF
7,0.3,10=Hkkm/h
color=79CDCD
6,14=xVert.Velocity
color=B0B0B0
7,13.5,23=Vm/s
color=6C757D
color=FFFFFF
7,14,23=Vm/s
color=79CDCD
9.5,14=xAltitude
color=ffff00
10.5,13.5,23=A
10.7,14,23=A
color=ffff00,000033
9,1=g0CCS,45,ffff00,000044,4,55ff55,4,eeaa00
color=bbbbbb,000000
color=6C757D
color=79CDCD
12.5,14=xRX Altitude
color=ffff00
13.5,14=GH
color=6C757D
15.5,14=xDistance
13.5,14,23=GH
color=79CDCD
15.5,14=xTimer
color=ffff00
16.5,14,23=GD
color=6C757D
19,0=xTimer
color=B0B0B0
20,0,10=Kc4
color=6C757D
16.5,14,23=Kc4
fonts=0,8
color=FFFFFF
18.7,0,-12.3=GD
fonts=0,2
color=79CDCD
19,14=xRSSI
color=B0B0B0
color=FFFFFF
20,14,23=R
color=6C757D
22,0=xTemperature
color=B0B0B0
23,0,10=Mt°C
color=6C757D
color=79CDCD
22,0.3=xTemperature
color=FFFFFF
23,0.3,10=Mt°C
color=79CDCD
22,14=xHumidity
color=B0B0B0
color=FFFFFF
23,14,23=Mh%rH
color=6C757D
25,0=xPressure
color=B0B0B0
26,0,10=MphPa
color=6C757D
color=79CDCD
25,0.3=xPressure
color=FFFFFF
26,0.3,10=MphPa
color=79CDCD
25,14=xSonde Battery
color=B0B0B0
color=FFFFFF
26,14,23=MbV
color=6C757D
28,0=Q
color=FFFFFF
28,0.3=Q
color=79CDCD
28,13=c
28,21=bVV

Wyświetl plik

@ -72,7 +72,6 @@ td#sfreq {
display: none;
flex: 1;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none;
flex-direction: column;
overflow: auto;
@ -340,11 +339,11 @@ p{
@media (prefers-color-scheme: dark) {
body {
background-color: #333;
}
}
h2{
color: white;
}
table, th, td, .save, .topnav a.active {
table, th, td, .save, a.active {
color: white;
border: 1px solid grey;
border-collapse: collapse;
@ -354,4 +353,28 @@ p{
color: white;
background-color: #333;
}
}
a:link, a:visited {
color: #D3D3D3;
}
.topnav, td#sfreq {
background-color: grey;
}
.topnav a:visited {
color: white;
}
.ctlbtn {
color: white;
background-color: grey;
}
.leaflet-center {
color: white;
background-color: grey;
}
.leaflet-bar a {
background-color: grey !important;
}
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
color: white !important;
background: grey !important;
}
}

Wyświetl plik

@ -14,6 +14,7 @@
#define DFM_FRAMELEN 33
#define MAXIDAGE 1800
/*
* observed DAT patterns for DFM-9:
@ -217,6 +218,12 @@ const char* typestr[16]={
"", ""
};
void DFM::killid() {
SondeData *sd = &(sonde.si()->d);
sd->validID = false;
memset((void *)&dfmstate, 0, sizeof(dfmstate));
}
#define DFMIDTHRESHOLD 2
/* inspired by oe5dxl's finddnmae in sondeudp.c of dxlaprs */
void DFM::finddfname(uint8_t *b)
@ -432,6 +439,9 @@ void DFM::decodeDAT(uint8_t *dat)
int tt = (y-1970)*365 + (y-1969)/4; // days since 1970
if(m<=12) { tt += MON[m]; if((y%4)==0 && m>2) tt++; }
tt = (tt+d-1)*(60*60*24) + h*3600 + mi*60;
// If we get a time stamp much different to the previously received one, kill the ID.
// most likely, we have a new sonde now, so wait for the new ID.
if(tt-dfmstate.datesec > MAXIDAGE) killid();
dfmstate.datesec = tt;
dfmstate.good |= 0x100;
}
@ -486,7 +496,9 @@ void DFM::decodeDAT(uint8_t *dat)
vh = ((uint16_t)dat[4]<<8) + dat[5];
Serial.print("GPS-lat: "); Serial.print(lat*0.0000001);
Serial.print(", hor-V: "); Serial.print(vh*0.01);
si->lat = lat*0.0000001;
lat = lat*0.0000001;
if( lat!=0 && si->lat!=0 && abs(lat-si->lat)>.25 ) killid();
si->lat = lat;
si->hs = vh*0.01;
if(lat!=0 || vh!=0) si->validPos |= 0x11; else si->validPos &= ~0x11;
}
@ -496,7 +508,9 @@ void DFM::decodeDAT(uint8_t *dat)
float lon, dir;
lon = (int32_t)(((uint32_t)dat[0]<<24) + ((uint32_t)dat[1]<<16) + ((uint32_t)dat[2]<<8) + (uint32_t)dat[3]);
dir = ((uint16_t)dat[4]<<8) + dat[5];
si->lon = lon*0.0000001;
lon = lon*0.0000001;
if( lon!=0 && si->lon!=0 && abs(lon-si->lon)>.25 ) killid();
si->lon = lon;
si->dir = dir*0.01;
Serial.print("GPS-lon: "); Serial.print(si->lon);
Serial.print(", dir: "); Serial.print(si->dir);

Wyświetl plik

@ -37,8 +37,7 @@ private:
void bitsToBytes(uint8_t *bits, uint8_t *bytes, int len);
int processDFMdata(uint8_t dt);
int decodeFrameDFM(uint8_t *data);
int receiveOld();
int receiveNew();
void killid();
#define B 8

Wyświetl plik

@ -305,6 +305,17 @@ void U8x8Display::getDispSize(uint8_t *height, uint8_t *width, uint8_t *lineskip
void U8x8Display::drawString(uint16_t x, uint16_t y, const char *s, int16_t width, uint16_t fg, uint16_t bg) {
char buf[50];
utf2latin15(s, buf, 50);
if(width!=WIDTH_AUTO && width>0) {
for(int l = strlen(buf); l<width; l++) {
buf[l] = ' ';
}
buf[width] = 0;
}
if(width<0) {
int l = strlen(buf);
memset(buf, ' ', width-l);
utf2latin15(s, buf+l, 50-l);
}
u8x8->drawString(x, y, buf);
}
@ -1333,7 +1344,7 @@ void Display::drawSite(DispEntry *de) {
case '#':
// currentSonde is index in array starting with 0;
// but we draw "1" for the first entry and so on...
snprintf(buf, 3, "%2d", sonde.currentSonde+1);
snprintf(buf, 3, "%d ", sonde.currentSonde+1);
buf[2]=0;
break;
case 't':
@ -1355,8 +1366,13 @@ void Display::drawSite(DispEntry *de) {
buf[5]=0;
break;
case 0: case 'l': default: // launch site
drawString(de, sonde.si()->launchsite);
return;
// TODO: This is a workaround to be compatible with older screens1.txt
// This does not work correctly with non-ascii utf8 characters.
// For this reason, this workaround will likely be removed in the future
// Instead, all screens?.txt should always indicate the max. length of the displayed string.
snprintf(buf, 17, "%-16s", sonde.si()->launchsite);
//drawString(de, sonde.si()->launchsite);
//return;
}
if(de->extra[0]) strcat(buf, de->extra+1);
drawString(de, buf);
@ -1677,11 +1693,19 @@ void Display::drawBatt(DispEntry *de) {
snprintf(buf, 30, "%.2f%s", val, de->extra+1);
break;
case 'U':
val = axp.getVbusVoltage();
if(sonde.config.type == TYPE_M5_CORE2) {
val = axp.getAcinVoltage();
} else {
val = axp.getVbusVoltage();
}
snprintf(buf, 30, "%.2f%s", val/1000, de->extra+1);
break;
case 'I':
val = axp.getVbusCurrent();
if(sonde.config.type == TYPE_M5_CORE2) {
val = axp.getAcinCurrent();
} else {
val = axp.getVbusCurrent();
}
snprintf(buf, 30, "%.2f%s", val, de->extra+1);
break;
case 'T':

Wyświetl plik

@ -575,6 +575,7 @@ int M10M20::decodeframeM20(uint8_t *data) {
ids[6] = (char)((id/100)%10+48);
ids[7] = (char)((id/10)%10+48);
ids[8] = (char)(id%10+48);
ids[9] = 0;
strncpy(si->id, ids, 10);
// Serial: AAB-C-DDEEE
char *ser = si->ser;

Wyświetl plik

@ -20,12 +20,13 @@ struct scancfg {
int NCHAN; // number of channels to scan, PLOT_W * SMPL_PIX
int SMOOTH;
int ADDWAIT;
int VSCALE;
};
//struct scancfg scanLCD={ 121, 7, 120/6, 120/6/4, 6000.0/120.0/20.0, 20, 120*20, 1 };
struct scancfg scanLCD={ 121, 7, 120/6, 120/6/4, 6000.0/120.0/10.0, 10, 120*10, 2, 40 };
struct scancfg scanTFT={ 210, 16, 210/6, 210/6/5, 6000.0/210.0/10.0, 10, 210*10, 1, 0 };
struct scancfg scan9341={ 210, 16, 210/6, 210/6/5, 6000.0/210.0/10.0, 10, 210*10, 1, 0 };
struct scancfg scanLCD={ 121, 7, 120/6, 120/6/4, 6000.0/120.0/10.0, 10, 120*10, 2, 40, 1 };
struct scancfg scanTFT={ 210, 16, 210/6, 210/6/5, 6000.0/210.0/10.0, 10, 210*10, 1, 0, 1 };
struct scancfg scan934x={ 300, 22, 300/6, 300/6/5, 6000.0/300.0/7.0, 7, 300*5, 1, 10, 2 };
struct scancfg &scanconfig = scanTFT;
@ -35,9 +36,12 @@ struct scancfg &scanconfig = scanTFT;
// max of 120*5 and 210*3
//#define MAXN 210*10
#define MAXN 120*20
// max of 120 and 210 (ceil(210/8)*8))
#define MAXDISP 216
//#define MAXN 120*20
#define MAXN 300*10
// max of 120 and 210 (ceil(210/8)*8)) -- now ceil(300/8)*8
//#define MAXDISP 216
#define MAXDISP 304
int scanresult[MAXN];
int scandisp[MAXDISP];
@ -50,7 +54,7 @@ double peakf=0;
const byte tilepatterns[9]={0,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF};
void Scanner::fillTiles(uint8_t *row, int value) {
for(int y=0; y<scanconfig.PLOT_H8; y++) {
int nbits = value - 8*(scanconfig.PLOT_H8-1-y);
int nbits = scanconfig.VSCALE*value - 8*(scanconfig.PLOT_H8-1-y);
if(nbits<0) { row[8*y]=0; continue; }
if(nbits>=8) { row[8*y]=255; continue; }
row[8*y] = tilepatterns[nbits];
@ -66,8 +70,8 @@ void Scanner::fillTiles(uint8_t *row, int value) {
*/
///// unused???? uint8_t tiles[16] = { 0x0f,0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,0xf0, 1, 3, 7, 15, 31, 63, 127, 255};
// type 0: lcd, 1: tft, 2: lcd(sh1106)
#define ISTFT (sonde.config.disptype==1 || sonde.config.disptype==3)
// type 0: lcd, 1: tft(ILI9225), 2: lcd(sh1106) 3:TFT(ili9341), 4: TFT(ili9342)
#define ISTFT (sonde.config.disptype!=0 && sonde.config.disptype!=2)
void Scanner::plotResult()
{
int yofs = 0;
@ -77,9 +81,9 @@ void Scanner::plotResult()
if (sonde.config.marker != 0) {
itoa((sonde.config.startfreq), buf, 10);
disp.rdis->drawString(0, 1, buf);
disp.rdis->drawString(95, 1, "MHz");
disp.rdis->drawString(scanconfig.PLOT_W/2-10, 1, "MHz");
itoa((sonde.config.startfreq + 6), buf, 10);
disp.rdis->drawString(195, 1, buf);
disp.rdis->drawString(scanconfig.PLOT_W-15, 1, buf);
}
}
else {
@ -120,8 +124,10 @@ void Scanner::scan()
{
if(!ISTFT) { // LCD small
scanconfig = scanLCD;
} else {
} else if (sonde.config.disptype==1) {
scanconfig = scanTFT;
} else {
scanconfig = scan934x;
}
// Configure
STARTF = (sonde.config.startfreq * 1000000);

Wyświetl plik

@ -48,7 +48,8 @@ void ShFreqImport::setLabel(int idx, char *id, float lat, float lon) {
void ShFreqImport::usekeyvalue() {
if(strcmp(keyword,"lat")==0) lat = atof(value);
if(strcmp(keyword,"lon")==0) lon = atof(value);
if(strcmp(keyword,"frequency")==0) freq = atof(value);
if(strcmp(keyword,"frequency")==0) { if(isnan(freq)) freq = atof(value); } // prefer tx_frequency if available
if(strcmp(keyword,"tx_frequency")==0) freq = atof(value);
if(strcmp(keyword,"type")==0) strcpy(type, value);
}
@ -123,13 +124,12 @@ int ShFreqImport::handleChar(char c) {
// wait for initial '{'
if(c=='{') {
Serial.println("{ found");
lat = NAN; lon = NAN; freq = NAN; *type = 0;
importState++;
}
break;
case BEFOREID:
// what for first '"' in { "A1234567" : { ... } }; or detect end
if(c=='"') { idpos = 0; importState++; }
if(c=='"') { idpos = 0; lat = NAN; lon = NAN; freq = NAN; *type = 0; importState++; }
if(c=='}') {
importState = ENDREACHED;
cleanup();
@ -156,7 +156,7 @@ int ShFreqImport::handleChar(char c) {
if(c==':') {
valuepos = 0;
quotes = 0;
if(strcmp(keyword,"lat")==0 || strcmp(keyword, "lon")==0 || strcmp(keyword, "frequency")==0 )
if(strcmp(keyword,"lat")==0 || strcmp(keyword, "lon")==0 || strcmp(keyword, "frequency")==0 || strcmp(keyword, "tx_frequency")==0)
importState = BEFORENUMVAL;
else {
if (strcmp(keyword, "type")==0)

Wyświetl plik

@ -23,8 +23,8 @@ const char *RXstr[]={"RX_OK", "RX_TIMEOUT", "RX_ERROR", "RX_UNKNOWN"};
// Dependency to enum SondeType
const char *sondeTypeStr[NSondeTypes] = { "DFM ", "RS41", "RS92", "Mxx ", "M10 ", "M20 ", "MP3H" };
const char *sondeTypeLongStr[NSondeTypes] = { "DFM (all)", "RS41", "RS92", "M10/M20", "M10 ", "M20 ", "MP3-H1" };
const char sondeTypeChar[NSondeTypes] = { 'D', '4', 'R', 'M', '2', '3' };
const char *manufacturer_string[]={"Graw", "Vaisala", "Vaisala", "Meteomodem", "Meteomodem", "Meteo-Radiy"};
const char sondeTypeChar[NSondeTypes] = { 'D', '4', 'R', 'M', 'M', '2', '3' };
const char *manufacturer_string[]={"Graw", "Vaisala", "Vaisala", "Meteomodem", "Meteomodem", "Meteomodem", "Meteo-Radiy"};
int fingerprintValue[]={ 17, 31, 64, 4, 55, 48, 23, 128+23, 119, 128+119, -1 };
const char *fingerprintText[]={
@ -43,7 +43,7 @@ const char *fingerprintText[]={
/* global variables from RX_FSK.ino */
int getKeyPressEvent();
int handlePMUirq();
extern bool pmu_irq;
extern uint8_t pmu_irq;
extern SX1278FSK sx1278;
/* Task model:
@ -247,14 +247,12 @@ void Sonde::defaultConfig() {
strcpy(config.udpfeed.symbol, "/O");
config.udpfeed.port = 9002;
config.udpfeed.highrate = 1;
config.udpfeed.idformat = ID_DFMGRAW;
config.tcpfeed.active = 0;
config.tcpfeed.type = 1;
strcpy(config.tcpfeed.host, "radiosondy.info");
strcpy(config.tcpfeed.symbol, "/O");
config.tcpfeed.port = 12345;
config.tcpfeed.highrate = 10;
config.tcpfeed.idformat = ID_DFMDXL;
config.kisstnc.active = 0;
strcpy(config.ephftp,"igs.bkg.bund.de/IGS/BRDC/");
@ -542,10 +540,10 @@ uint16_t Sonde::waitRXcomplete() {
uint16_t res=0;
uint32_t t0 = millis();
rxloop:
while( !pmu_irq && rxtask.receiveResult==0xFFFF && millis()-t0 < 3000) { delay(50); }
while( (pmu_irq!=1) && rxtask.receiveResult==0xFFFF && millis()-t0 < 3000) { delay(50); }
if( pmu_irq ) {
handlePMUirq();
goto rxloop;
if(pmu_irq!=2) goto rxloop;
}
if( rxtask.receiveResult == RX_UPDATERSSI ) {
rxtask.receiveResult = 0xFFFF;

Wyświetl plik

@ -182,8 +182,6 @@ struct st_mp3hconfig {
};
enum IDTYPE { ID_DFMDXL, ID_DFMGRAW, ID_DFMAUTO };
struct st_feedinfo {
bool active;
int type; // 0:UDP(axudp), 1:TCP(aprs.fi)
@ -193,14 +191,12 @@ struct st_feedinfo {
int lowrate;
int highrate;
int lowlimit;
int idformat; // 0: dxl 1: real 2: auto
};
// maybe extend for external Bluetooth interface?
// internal bluetooth consumes too much memory
struct st_kisstnc {
bool active;
int idformat;
};
struct st_mqtt {
@ -229,7 +225,7 @@ struct st_sondehub {
int fiactive;
int fiinterval;
int fimaxdist;
int fimaxage;
double fimaxage;
};
// to be extended
@ -287,6 +283,10 @@ typedef struct st_rdzconfig {
// for now, one feed for each type is enough, but might get extended to more?
char call[10]; // APRS callsign
int passcode; // APRS passcode
int chase;
char objcall[10]; // APRS object call (for wettersonde.net)
char beaconsym[5]; // APRS beacon symbol
char comment[32];
struct st_feedinfo udpfeed; // target for AXUDP messages
struct st_feedinfo tcpfeed; // target for APRS-IS TCP connections
struct st_kisstnc kisstnc; // target for KISS TNC (via TCP, mainly for APRSdroid)

Wyświetl plik

@ -18,6 +18,7 @@
#include "aprs.h"
extern const char *version_name;
extern const char *version_id;
#if 0
int openudp(const char *ip, int port, struct sockaddr_in *si) {
int fd;
@ -258,15 +259,51 @@ static uint32_t dao91(double x)
char b[251];
//char raw[201];
const char *destcall="APRRDZ";
char *aprs_senddata(SondeInfo *si, const char *usercall, const char *sym) {
SondeData *s = &(si->d);
*b=0;
char *aprs_send_beacon(const char *usercall, float lat, float lon, const char *sym, const char *comment) {
*b = 0;
aprsstr_append(b, usercall);
aprsstr_append(b, ">");
const char *destcall="APRRDZ";
aprsstr_append(b, destcall);
#if 0
aprsstr_append(b, ":/"); // / is report with timestamp
int i = strlen(b);
int sec = 0; // TODO: NOW!!!
snprintf(b+i, APRS_MAXLEN, "%02d%02d%02dh", sec/(60*60), (sec%(60*60))/60, sec%60);
#else
// report without timestamp
aprsstr_append(b, ":!"); // ! is report w/p timestamp
#endif
// lat
int i = strlen(b);
int lati = abs((int)lat);
int latm = (fabs(lat)-lati)*6000;
snprintf(b+i, APRS_MAXLEN-i, "%02d%02d.%02d%c%c", lati, latm/100, latm%100, lat<0?'S':'N', sym[0]);
// lon
i = strlen(b);
int loni = abs((int)lon);
int lonm = (fabs(lon)-loni)*6000;
snprintf(b+i, APRS_MAXLEN-i, "%03d%02d.%02d%c%c", loni, lonm/100, lonm%100, lon<0?'W':'E', sym[1]);
// maybe add alt
// maybe add DAO?
i = strlen(b);
snprintf(b+i, APRS_MAXLEN-i, "%s", comment);
i = strlen(b);
snprintf(b+i, APRS_MAXLEN-i, " %s-%s", version_name, version_id);
//sprintf(b + strlen(b), "%s", version_name);
return b;
}
char *aprs_senddata(SondeInfo *si, const char *usercall, const char *objcall, const char *sym) {
SondeData *s = &(si->d);
*b=0;
aprsstr_append(b, *objcall ? objcall : usercall);
aprsstr_append(b, ">");
// const char *destcall="APRARX,SONDEGATE,TCPIP,qAR,oh3bsg";
aprsstr_append(b, destcall);
// if(*objcall) { aprsstr_append(b, ","); aprsstr_append(b, usercall); }
// uncompressed
aprsstr_append(b, ":;");
char tmp[10];
@ -310,7 +347,14 @@ char *aprs_senddata(SondeInfo *si, const char *usercall, const char *sym) {
if( !isnan(s->relativeHumidity) ) {
sprintf(b+strlen(b), "h=%.1f%% ", s->relativeHumidity);
}
sprintf(b+strlen(b), "%.3fMHz Type=%s ", si->freq, sondeTypeStr[sonde.realType(si)]);
char type[12];
if ( si->type == STYPE_RS41 && RS41::getSubtype(type, 11, si) == 0 ) {
// type was copied to type
} else {
strncpy(type, sondeTypeStr[sonde.realType(si)], 11); type[11]=0;
}
sprintf(b+strlen(b), "%.3fMHz Type=%s ", si->freq, type /* sondeTypeStr[sonde.realType(si)] */ );
if( s->countKT != 0xffff && s->vframe - s->crefKT < 51 ) {
sprintf(b+strlen(b), "TxOff=%dh%dm ", s->countKT/3600, (s->countKT-s->countKT/3600*3600)/60);
}

Wyświetl plik

@ -2,13 +2,15 @@
#ifndef _aprs_h
#define _aprs_h
#include "Sonde.h"
#include "RS41.h"
#define APRS_MAXLEN 201
void aprs_gencrctab(void);
int aprsstr_mon2raw(const char *mon, char raw[], int raw_len);
int aprsstr_mon2kiss(const char *mon, char raw[], int raw_len);
char *aprs_senddata(SondeInfo *s, const char *usercall, const char *sym);
char *aprs_send_beacon(const char *call, float lat, float lon, const char *sym, const char *comment);
char *aprs_senddata(SondeInfo *s, const char *usercall, const char *objcall, const char *sym);
#endif

Wyświetl plik

@ -85,6 +85,15 @@ static EPHEM_t *te;
#define fread(buffer, siz, els, file) (file.read((uint8_t *)buffer, (siz)*(els))/siz)
#define fgetc(file) (char)file.read()
int readDbl(File *fp, double *dbl) {
uint8_t buf[20];
int l = fp->read(buf, 19);
if(l!=19) return -1;
if (buf[15] == 'D') buf[15] = 'E';
buf[19] = 0;
sscanf((char *)buf, "%lf", dbl);
return 0;
}
EPHEM_t *read_RNXpephs(const char *file) {
int l, i;
@ -137,56 +146,84 @@ EPHEM_t *read_RNXpephs(const char *file) {
strncpy(ephem.epoch+2, str, 15);
ephem.epoch[16] = '\0';
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.af0 = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.af1 = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.af2 = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.af0 = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.af1 = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.af2 = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.af0 = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.af1 = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.af2 = dbl;
while ((c=fgetc(fp)) != '\n') { if (c == EOF) break; }
l = fread(buf, 3, 1, fp); if (l != 1) break; buf[ 3] = 0;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); //ephem.iode = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.crs = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.delta_n = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.M0 = dbl;
if(readDbl(&fp, &dbl)<0) break; //ephem.iode = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.crs = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.delta_n = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.M0 = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); //ephem.iode = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.crs = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.delta_n = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.M0 = dbl;
while ((c=fgetc(fp)) != '\n') { if (c == EOF) break; }
l = fread(buf, 3, 1, fp); if (l != 1) break; buf[ 3] = 0;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.cuc = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.e = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.cus = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.sqrta = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.cuc = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.e = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.cus = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.sqrta = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.cuc = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.e = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.cus = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.sqrta = dbl;
while ((c=fgetc(fp)) != '\n') { if (c == EOF) break; }
l = fread(buf, 3, 1, fp); if (l != 1) break; buf[ 3] = 0;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.toe = dbl;
ephem.toc = ephem.toe;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.cic = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.Omega0 = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.cis = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.toe = dbl; ephem.toc = ephem.toe;
if(readDbl(&fp, &dbl)<0) break; ephem.cic = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.Omega0 = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.cis = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.toe = dbl;
// ephem.toc = ephem.toe;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.cic = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.Omega0 = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.cis = dbl;
while ((c=fgetc(fp)) != '\n') { if (c == EOF) break; }
l = fread(buf, 3, 1, fp); if (l != 1) break; buf[ 3] = 0;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.i0 = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.crc = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.w = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.OmegaDot = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.i0 = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.crc = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.w = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.OmegaDot = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.i0 = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.crc = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.w = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.OmegaDot = dbl;
while ((c=fgetc(fp)) != '\n') { if (c == EOF) break; }
l = fread(buf, 3, 1, fp); if (l != 1) break; buf[ 3] = 0;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.idot = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); //ephem.codeL2 = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.gpsweek = (int)dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); //ephem.iodc = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.idot = dbl;
if(readDbl(&fp, &dbl)<0) break; //ephem.codeL2 = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.gpsweek = (int)dbl;
if(readDbl(&fp, &dbl)<0) break; //ephem.iodc = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.idot = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); //ephem.codeL2 = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.gpsweek = (int)dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); //ephem.iodc = dbl;
while ((c=fgetc(fp)) != '\n') { if (c == EOF) break; }
l = fread(buf, 3, 1, fp); if (l != 1) break; buf[ 3] = 0;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); //ephem.sva = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.health = (uint8_t)(dbl+0.1);
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.tgd = dbl;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); //ephem.iodc = dbl;
if(readDbl(&fp, &dbl)<0) break; //ephem.sva = dbl;
if(readDbl(&fp, &dbl)<0) break; ephem.health = (uint8_t)(dbl+0.1);
if(readDbl(&fp, &dbl)<0) break; ephem.tgd = dbl;
if(readDbl(&fp, &dbl)<0) break; //ephem.iodc = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); //ephem.sva = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.health = (uint8_t)(dbl+0.1);
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); ephem.tgd = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); //ephem.iodc = dbl;
while ((c=fgetc(fp)) != '\n') { if (c == EOF) break; }
l = fread(buf, 3, 1, fp); if (l != 1) break; buf[ 3] = 0;
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); //ephem.ttom = dbl;
if(readDbl(&fp, &dbl)<0) break; //ephem.ttom = dbl;
//l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); //ephem.ttom = dbl;
String l = fp.readStringUntil('\n');
/* // die letzten beiden Felder (spare) sind manchmal leer (statt 0.00); manchmal fehlt sogar das drittletzte Feld
l = fread(buf, 19, 1, fp); if (l != 1) break; if (buf[15] == 'D') buf[15] = 'E'; buf[19] = 0; sscanf(buf, "%lf", &dbl); //ephem.fit = dbl;

Wyświetl plik

@ -1,4 +1,4 @@
const char *version_name = "rdzTTGOsonde";
const char *version_id = "master_v0.9.0";
const char *version_id = "master_v0.9.1";
const int SPIFFS_MAJOR=2;
const int SPIFFS_MINOR=16;

Wyświetl plik

@ -1,83 +0,0 @@
# Prerequisites
## Arduini IDE
Get the latest Arduino IDE software from arduino.cc/en/Main/Software
## ESP32 support
File -> Preferences (or Arduino -> Preferences on MacOS)
go to "Additional Board Manager URLs"
Add *https://dl.espressif.com/dl/package_esp32_index.json* and press oK
Tool -> Boad -> Boards Manager
search for "esp32"
Install "esp32 by Espressif Systems"
## ESP32 Flash Filesystem Upload support
Get the zip file of the latest release from
https://github.com/me-no-dev/arduino-esp32fs-plugin/releases/
Unzip the content to the tools folder of your Arduino IDE (~/Documents/Arduino/tools on MacOS,
similar on other OS) and restart IDE
## Additional libraries
Select Tools -> Manage Libraries...
Install "U8g2"
Install "MicroNMEA"
(Install "TFT_22_ILI9225" -- currently not needed, due to some issues with the official library, there is a modified version in the rdz_ttgo_sonde source tree)
## Additional libraries, part 2
From https://github.com/me-no-dev/ESPAsyncWebServer select "Download ZIP", extract to the libraries
folder of your Arduino IDE (~/Documents/Arduino/libraries on MacOS), rename main folder to ESPAsyncWebServer
(remove the "-master")
From https://github.com/me-no-dev/AsyncTCP select "Download ZIP", extract to the libraries folder
of your Arduino IDE, and rename main folder to AsyncTCP
From https://github.com/lewisxhe/AXP202X_Library select "Download ZIP", extract to the libraries
folder of your Arduino IDE, and rename main folder to AXP202X_Library-1.0
From https://github.com/dx168b/async-mqtt-client select "Download ZIP", extract to the libraries
folder of your Arduino IDE, and rename main folder to async-mqtt-client
## Additional libraries, part 3
Copy the SX1278FSK, SondeLib and fonts folders from libraries of this project to your Arduino IDE's libraries
folders, or, alternatively, create symbolic links (MacOS/Linux):
```
cd ~/Documents/Arduino/libraries
ln -s <whereyouclonedthegit>/rdz_ttgo_sonde/libraries/SondeLib/ .
ln -s <whereyouclonedthegit>/rdz_ttgo_sonde/libraries/SX1278FSK/ .
ln -s <whereyouclonedthegit>/rdz_ttgo_sonde/libraries/fonts/ .
```
Restart the Arduino IDE
(symbolic links are the preferred way, otherwise you have to copy the the libraries again after
each update)
## Final steps
In the IDE Tools -> Board: ->
Select "TTGO LoRa32-OLED v1" (or something that fits your board.
The binary images are currently built with the "T-Beam" board selection)
Compile and Upload code
Upload data to SPIFFS with Tools -> ESP32 Sketch Data Upload

Wyświetl plik

@ -25,7 +25,7 @@ lib_deps_external =
https://github.com/dx168b/async-mqtt-client
[env:ttgo-lora32]
platform = https://github.com/platformio/platform-espressif32.git
platform = https://github.com/platformio/platform-espressif32.git#v3.3.2
board = ttgo-lora32-v1
framework = arduino
monitor_speed = 115200