From a7f6d6bb7bba0d1b4fccacbdb15e13211d2b67b5 Mon Sep 17 00:00:00 2001 From: "Hansi, dl9rdz" Date: Fri, 24 Sep 2021 10:31:58 +0200 Subject: [PATCH 1/8] meteo in aprs frames --- RX_FSK/RX_FSK.ino | 1 - RX_FSK/src/aprs.cpp | 30 +++++++++++++++++++++--------- RX_FSK/version.h | 2 +- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/RX_FSK/RX_FSK.ino b/RX_FSK/RX_FSK.ino index 68f2bd7..f264594 100644 --- a/RX_FSK/RX_FSK.ino +++ b/RX_FSK/RX_FSK.ino @@ -2530,7 +2530,6 @@ void loopDecoder() { } if(sonde.config.tcpfeed.active) { static unsigned long lasttcp = 0; - static bool loginok = false; if( tcpclient.disconnected()) { tcpclient.connect(sonde.config.tcpfeed.host, sonde.config.tcpfeed.port); } diff --git a/RX_FSK/src/aprs.cpp b/RX_FSK/src/aprs.cpp index 913a1a5..6c0f95a 100644 --- a/RX_FSK/src/aprs.cpp +++ b/RX_FSK/src/aprs.cpp @@ -17,6 +17,7 @@ #include #include "aprs.h" +extern const char *version_name; #if 0 int openudp(const char *ip, int port, struct sockaddr_in *si) { int fd; @@ -255,11 +256,10 @@ static uint32_t dao91(double x) } /* end dao91() */ -char b[201]; +char b[251]; //char raw[201]; char *aprs_senddata(SondeInfo *si, const char *usercall, const char *sym) { -// float lat, float lon, float alt, float speed, float dir, float climb, const char *type, const char *objname, const char *usercall, const char *sym, const char *comm) SondeData *s = &(si->d); *b=0; aprsstr_append(b, usercall); @@ -288,7 +288,7 @@ char *aprs_senddata(SondeInfo *si, const char *usercall, const char *sym) { snprintf(b+i, APRS_MAXLEN-i, "%03d%02d.%02d%c%c", loni, lonm/100, lonm%100, s->lon<0?'W':'E', sym[1]); if(s->hs>0.5) { i=strlen(b); - snprintf(b+i, APRS_MAXLEN-i, "%03d/%03d", realcard(s->dir+1.5), realcard(s->hs*1.0/KNOTS+0.5)); + snprintf(b+i, APRS_MAXLEN-i, "%03d/%03d", realcard(s->dir+1.5), realcard(s->hs*3.6/KNOTS+0.5)); } if(s->alt>0.5) { i=strlen(b); @@ -299,13 +299,25 @@ char *aprs_senddata(SondeInfo *si, const char *usercall, const char *sym) { snprintf(b+i, APRS_MAXLEN-i, "!w%c%c!", 33+dao91(s->lat), 33+dao91(s->lon)); // ??? strcat(b, "&"); - char comm[100]; - snprintf(comm, 100, "Clb=%.1fm/s %.3fMHz Type=%s", s->vs, si->freq, sondeTypeStr[si->type]); - strcat(b, comm); - if( TYPE_IS_DFM(si->type) || TYPE_IS_METEO(si->type) ) { - snprintf(comm, 100, " ser=%s", s->ser); - strcat(b, comm); + i=strlen(b); + i += snprintf(b+i, APRS_MAXLEN-i, "Clb=%.1fm/s ", s->vs ); + if( !isnan(s->pressure) ) { + sprintf(b+strlen(b), "p=%.1fhPa ", s->pressure); } + if( !isnan(s->temperature) ) { + sprintf(b+strlen(b), "t=%.1fC ", s->temperature); + } + if( !isnan(s->relativeHumidity) ) { + sprintf(b+strlen(b), "h=%.1f%% ", s->relativeHumidity); + } + sprintf(b+strlen(b), "%.3fMHz Type=%s ", si->freq, sondeTypeStr[si->type]); + 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); + } + if( TYPE_IS_DFM(si->type) || TYPE_IS_METEO(si->type) ) { + sprintf(b + strlen(b), "ser=%s ", s->ser); + } + sprintf(b + strlen(b), "%s", version_name); return b; } diff --git a/RX_FSK/version.h b/RX_FSK/version.h index 9107600..49d9c59 100644 --- a/RX_FSK/version.h +++ b/RX_FSK/version.h @@ -1,4 +1,4 @@ const char *version_name = "rdzTTGOsonde"; -const char *version_id = "devel20210923"; +const char *version_id = "devel20210924"; const int SPIFFS_MAJOR=2; const int SPIFFS_MINOR=16; From 8bc4eda63c312ac77a0c44ff139c57ee0bbf7b86 Mon Sep 17 00:00:00 2001 From: "Hansi, dl9rdz" Date: Fri, 24 Sep 2021 12:09:32 +0200 Subject: [PATCH 2/8] use correct M10/M20 type everywhere --- RX_FSK/RX_FSK.ino | 45 ++++++++++++++++++++----------------------- RX_FSK/src/M10M20.cpp | 19 ++++++++++++++++++ RX_FSK/src/Sonde.cpp | 5 +++++ RX_FSK/src/Sonde.h | 2 ++ RX_FSK/src/aprs.cpp | 2 +- 5 files changed, 48 insertions(+), 25 deletions(-) diff --git a/RX_FSK/RX_FSK.ino b/RX_FSK/RX_FSK.ino index f264594..cf222e4 100644 --- a/RX_FSK/RX_FSK.ino +++ b/RX_FSK/RX_FSK.ino @@ -503,7 +503,7 @@ void addSondeStatus(char *ptr, int i) struct tm ts; SondeInfo *s = &sonde.sondeList[i]; strcat(ptr, ""); - sprintf(ptr + strlen(ptr), "
%3.3f MHz, Type: %s
ID: %s", s->freq, sondeTypeLongStr[s->type], + sprintf(ptr + strlen(ptr), "
%3.3f MHz, Type: %s
ID: %s", s->freq, sondeTypeLongStr[sonde.realType(s)], s->d.validID ? s->d.id : ""); if (s->d.validID && (TYPE_IS_DFM(s->type) || TYPE_IS_METEO(s->type) || s->type == STYPE_MP3H) ) { sprintf(ptr + strlen(ptr), " (ser: %s)", s->d.ser); @@ -548,7 +548,7 @@ const char *createLiveJson() { SondeInfo *s = &sonde.sondeList[sonde.currentSonde]; sprintf(ptr + strlen(ptr), "\"sonde\": {\"rssi\": %d, \"vframe\": %d, \"time\": %d,\"id\": \"%s\", \"freq\": %3.3f, \"type\": \"%s\"", - s->rssi, s->d.vframe, s->d.time, s->d.id, s->freq, sondeTypeStr[s->type]); + s->rssi, s->d.vframe, s->d.time, s->d.id, s->freq, sondeTypeStr[sonde.realType(s)]); if ( !isnan(s->d.lat) && !isnan(s->d.lon) ) sprintf(ptr + strlen(ptr), ", \"lat\": %.6f, \"lon\": %.6f", s->d.lat, s->d.lon); @@ -1309,7 +1309,7 @@ void addSondeStatusKML(char *ptr, int i) sprintf(ptr + strlen(ptr), "%sabsolute%.6f,%.6f,%.0f%3.3f MHz, Type: %s, h=%.0fm", s->d.id, s->d.id, s->d.lon, s->d.lat, s->d.alt, - s->freq, sondeTypeStr[s->type], s->d.alt); + s->freq, sondeTypeStr[sonde.realType(s)], s->d.alt); } const char *createKMLDynamic() { @@ -2528,20 +2528,20 @@ void loopDecoder() { Serial.print("sending: "); Serial.println(raw); tncclient.write(raw, rawlen); } - if(sonde.config.tcpfeed.active) { - static unsigned long lasttcp = 0; - if( tcpclient.disconnected()) { - tcpclient.connect(sonde.config.tcpfeed.host, sonde.config.tcpfeed.port); - } - else if( tcpclient.connected() ) { - unsigned long now = millis(); - if( (now-lasttcp) > sonde.config.tcpfeed.highrate*1000L ) { - strcat(str,"\r\n"); - Serial.print(str); - tcpclient.write(str, strlen(str)); - lasttcp = now; - } - } + if (sonde.config.tcpfeed.active) { + static unsigned long lasttcp = 0; + if ( tcpclient.disconnected()) { + tcpclient.connect(sonde.config.tcpfeed.host, sonde.config.tcpfeed.port); + } + else if ( tcpclient.connected() ) { + unsigned long now = millis(); + if ( (now - lasttcp) > sonde.config.tcpfeed.highrate * 1000L ) { + strcat(str, "\r\n"); + Serial.print(str); + tcpclient.write(str, strlen(str)); + lasttcp = now; + } + } } #if FEATURE_CHASEMAPPER if (sonde.config.cm.active) { @@ -2573,7 +2573,7 @@ void loopDecoder() { char raw[1024]; char gps[128]; const char *typestr = s->d.typestr; - if (*typestr == 0) typestr = sondeTypeStr[s->type]; + if (*typestr == 0) typestr = sondeTypeStr[sonde.realType(s)]; // TODO: only if GPS is valid... if (gpsPos.valid) { snprintf(gps, 128, ", \"gpslat\": %f," @@ -2775,13 +2775,13 @@ void enableNetwork(bool enable) { MDNS.end(); connected = false; } - tcpclient.onConnect([](void *arg, AsyncClient *s) { + tcpclient.onConnect([](void *arg, AsyncClient * s) { Serial.write("APRS: TCP connected\n"); char buf[128]; snprintf(buf, 128, "user %s pass %d vers %s %s\r\n", sonde.config.call, sonde.config.passcode, version_name, version_id); s->write(buf, strlen(buf)); }); - tcpclient.onData([](void *arg, AsyncClient *c, void *data, size_t len) { + tcpclient.onData([](void *arg, AsyncClient * c, void *data, size_t len) { Serial.write((const uint8_t *)data, len); }); Serial.println("enableNetwork done"); @@ -3646,11 +3646,8 @@ void sondehub_send_data(WiFiClient * client, SondeInfo * s, struct st_sondehub * char rs_msg[MSG_SIZE]; char *w; struct tm ts; - uint8_t realtype = s->type; // config setting M10 and M20 will both decode both types, so use the real type that was decoded - if (TYPE_IS_METEO(realtype)) { - realtype = s->d.subtype == 1 ? STYPE_M10 : STYPE_M20; - } + uint8_t realtype = sonde.realType(s); // For DFM, s->d.time is data from subframe DAT8 (gps date/hh/mm), and sec is from DAT1 (gps sec/usec) // For all others, sec should always be 0 and time the exact time in seconds diff --git a/RX_FSK/src/M10M20.cpp b/RX_FSK/src/M10M20.cpp index 5874ec2..c72d047 100644 --- a/RX_FSK/src/M10M20.cpp +++ b/RX_FSK/src/M10M20.cpp @@ -328,6 +328,25 @@ int M10M20::decodeframeM10(uint8_t *data) { if(dir<0) dir+=360; si->dir = dir; si->validPos = 0x3f; + // m10 temp + const float p0 = 1.07303516e-03, p1 = 2.41296733e-04, p2 = 2.26744154e-06, p3 = 6.52855181e-08; + const float Rs[3] = { 12.1e3 , 36.5e3 , 475.0e3 }; + const float Rp[3] = { 1e20 , 330.0e3 , 2000.0e3 }; + uint8_t sct = data[62]; + float rt = getint16(data+63) & (0xFFF); + float T = NAN; + if(rt!=0 && sct<3) { + rt = (4095-rt)/rt - (Rs[sct]/Rp[sct]); + if(rt>0) { + rt = Rs[sct] / rt; + if(rt>0) { + rt = log(rt); + rt = 1/( p0 + p1*rt + p2*rt*rt + p3*rt*rt*rt ) - 273.15; + if(rt>-99 && rt<50) { T = rt; } + } + } + } + si->temperature = T; uint32_t gpstime = getint32(data+10); uint16_t gpsweek = getint16(data+32); diff --git a/RX_FSK/src/Sonde.cpp b/RX_FSK/src/Sonde.cpp index 318accd..10dd28e 100644 --- a/RX_FSK/src/Sonde.cpp +++ b/RX_FSK/src/Sonde.cpp @@ -716,4 +716,9 @@ void Sonde::clearDisplay() { disp.rdis->clear(); } +SondeType Sonde::realType(SondeInfo *si) { + if(TYPE_IS_METEO(si->type)) { return si->d.subtype==1 ? STYPE_M10:STYPE_M20; } + else return si->type; +} + Sonde sonde = Sonde(); diff --git a/RX_FSK/src/Sonde.h b/RX_FSK/src/Sonde.h index 8381f0a..e8eb46f 100644 --- a/RX_FSK/src/Sonde.h +++ b/RX_FSK/src/Sonde.h @@ -319,6 +319,8 @@ public: // moved to heap, saving space in .bss //SondeInfo sondeList[MAXSONDE+1]; SondeInfo *sondeList; + // helper function for type string + static SondeType realType(SondeInfo *si); Sonde(); void defaultConfig(); diff --git a/RX_FSK/src/aprs.cpp b/RX_FSK/src/aprs.cpp index 6c0f95a..ec5fbd3 100644 --- a/RX_FSK/src/aprs.cpp +++ b/RX_FSK/src/aprs.cpp @@ -310,7 +310,7 @@ 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[si->type]); + sprintf(b+strlen(b), "%.3fMHz Type=%s ", si->freq, 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); } From 8d24d2fe78363e5dcef921ead2933080dd379861 Mon Sep 17 00:00:00 2001 From: "Hansi, dl9rdz" Date: Fri, 24 Sep 2021 12:59:15 +0200 Subject: [PATCH 3/8] workaround for app --- RX_FSK/RX_FSK.ino | 20 ++++++++++++++------ RX_FSK/version.h | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/RX_FSK/RX_FSK.ino b/RX_FSK/RX_FSK.ino index cf222e4..10501fe 100644 --- a/RX_FSK/RX_FSK.ino +++ b/RX_FSK/RX_FSK.ino @@ -2585,6 +2585,14 @@ void loopDecoder() { } else { *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; + // int len = snprintf(raw, 1024, "{" "\"res\": %d," @@ -2622,12 +2630,12 @@ void loopDecoder() { s->d.ser, (int)s->d.validID, s->launchsite, - s->d.lat, - s->d.lon, - s->d.alt, - s->d.vs, - s->d.hs, - s->d.dir, + lat, + lon, + alt, + vs, + hs, + dir, s->d.sats, s->d.validPos, s->d.time, diff --git a/RX_FSK/version.h b/RX_FSK/version.h index 49d9c59..d36b78e 100644 --- a/RX_FSK/version.h +++ b/RX_FSK/version.h @@ -1,4 +1,4 @@ const char *version_name = "rdzTTGOsonde"; -const char *version_id = "devel20210924"; +const char *version_id = "devel20210924b"; const int SPIFFS_MAJOR=2; const int SPIFFS_MINOR=16; From 5be57a02b5d784de943bf6ef3eeff0bb2982136b Mon Sep 17 00:00:00 2001 From: eben80 Date: Fri, 24 Sep 2021 14:55:53 +0200 Subject: [PATCH 4/8] Make telemetry values available on device display This is probably not the cleanest coding so apologies in advance. Tested on TTGO. --- RX_FSK/src/Display.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/RX_FSK/src/Display.cpp b/RX_FSK/src/Display.cpp index 3fa56ce..0272678 100644 --- a/RX_FSK/src/Display.cpp +++ b/RX_FSK/src/Display.cpp @@ -809,6 +809,10 @@ void Display::parseDispElement(char *text, DispEntry *de) de->extra = strdup(text+1); //Serial.printf("parsing 'f' entry: extra is '%s'\n", de->extra); break; + case 'm': + de->func = disp.drawTelemetry; + de->extra = strdup(text+1); + break; case 'n': // IP address / small always uses tiny font on TFT for backward compatibility // Large font can be used arbitrarily @@ -1283,6 +1287,31 @@ void Display::drawSite(DispEntry *de) { drawString(de, buf); } void Display::drawTelemetry(DispEntry *de) { + rdis->setFont(de->fmt); + float value=0; + switch(de->extra[0]) { + case 't': + value = sonde.si()->d.temperature; + if(value!=0xffff) snprintf(buf, 8, "%3.2f", value); + else strcpy(buf, " "); + break; + case 'p': + value = sonde.si()->d.pressure; + if(value!=0xffff) snprintf(buf, 7, "%4.2f", value); + else strcpy(buf, " "); + break; + case 'h': + value = sonde.si()->d.relativeHumidity; + if(value!=0xffff) snprintf(buf, 5, "%3.1f", value); + else strcpy(buf, " "); + break; + case 'b': + value = sonde.si()->d.batteryVoltage; + if(value!=0xffff) snprintf(buf, 5, "%1.2f", value); + else strcpy(buf, " "); + break; + } + drawString(de,buf); } void Display::drawKilltimer(DispEntry *de) { From 320d621cbcf1a141a71b9cd7cd772641994fe824 Mon Sep 17 00:00:00 2001 From: "Hansi, dl9rdz" Date: Fri, 24 Sep 2021 15:21:24 +0200 Subject: [PATCH 5/8] m10 temp, done right :) --- RX_FSK/src/M10M20.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RX_FSK/src/M10M20.cpp b/RX_FSK/src/M10M20.cpp index c72d047..74b0e78 100644 --- a/RX_FSK/src/M10M20.cpp +++ b/RX_FSK/src/M10M20.cpp @@ -333,7 +333,7 @@ int M10M20::decodeframeM10(uint8_t *data) { const float Rs[3] = { 12.1e3 , 36.5e3 , 475.0e3 }; const float Rp[3] = { 1e20 , 330.0e3 , 2000.0e3 }; uint8_t sct = data[62]; - float rt = getint16(data+63) & (0xFFF); + float rt = getint16_r(data+63) & (0xFFF); float T = NAN; if(rt!=0 && sct<3) { rt = (4095-rt)/rt - (Rs[sct]/Rp[sct]); From 93628c9d4faac60205c0969dc57a95a1c30ee43c Mon Sep 17 00:00:00 2001 From: "Hansi, dl9rdz" Date: Fri, 24 Sep 2021 16:47:27 +0200 Subject: [PATCH 6/8] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 022c404..3f209e5 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Manufacturer | Model | Position | Temperature | Humidity | Pressure Vaisala | RS92-SGP/NGP | :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: Graw | DFM06/09/17 | :heavy_check_mark: | :x: | :x: | :x: -Meteomodem | M10 | :heavy_check_mark: | :x: | :x: | Not Sent +Meteomodem | M10 | :heavy_check_mark: | :heavy_checkmark: | :x: | Not Sent Meteomodem | M20 | :heavy_check_mark: | :x: | :x: | Not Sent Meteo-Radiy | MP3-H1 (MRZ-H1) | :heavy_check_mark: | :x: | :x: | :x: From 49bff43090a00ca1efedc27c2f070337a2c3a57d Mon Sep 17 00:00:00 2001 From: "Hansi, dl9rdz" Date: Fri, 24 Sep 2021 18:09:19 +0200 Subject: [PATCH 7/8] +Display telemetry - some enhancements --- RX_FSK/data/screens1.txt | 19 +++++++++++++++++-- RX_FSK/data/screens2.txt | 31 ++++++++++++++++++++++++++++++- RX_FSK/src/Display.cpp | 30 ++++++++++++++++++++++-------- RX_FSK/version.h | 2 +- 4 files changed, 70 insertions(+), 12 deletions(-) diff --git a/RX_FSK/data/screens1.txt b/RX_FSK/data/screens1.txt index 47b9321..0844148 100644 --- a/RX_FSK/data/screens1.txt +++ b/RX_FSK/data/screens1.txt @@ -44,7 +44,7 @@ # S scan list entry info: l/empty: launch site name, #=entry nr, t=total entries, a=active entries, /: #/t # K RS41 kill timer values: Kl launch timer, Kb burst timer, Kc kill countdown # format: K_4: h:mm k_6: h:mm:ss k_s: sssss, nothing shown for other sonde -# Mx telemetry value x (t temp p preassure h hyg) [not yet implemented, maybe some day in future] +# Mx telemetry value x (t temp p preassure h hyg b battery) # Gx GPS-related data # raw data from GPS: GA, GO, GH, GC: LAtitude, lOngitude, Altutide(Height), Course over ground # relative to sonde: GD, GI, GB: Distance, dIrection (absolute), relative Bearing @@ -203,7 +203,7 @@ timeaction=#,#,# 7,0=gV 7,2=xd= 7,4=gD -7,12=gI° +7,12=gI° ############ @BatteryOLED @@ -224,3 +224,18 @@ fonts=0,1 6,0=xTemp: 6,5=bT C +############# +@Meteo +timer=-1,-1,-1 +key1action=+,0,F,W +key2action=>,#,#,# +timeaction=#,#,# +fonts=0,1 +0,0=Is +0,9=f +1,12=t +2,0=xTelemetry Data +4,0=Mt°C +4,9=Mh%rH +6,0=MphPa +6,11=MbV diff --git a/RX_FSK/data/screens2.txt b/RX_FSK/data/screens2.txt index f4e82ea..67b3e84 100644 --- a/RX_FSK/data/screens2.txt +++ b/RX_FSK/data/screens2.txt @@ -44,7 +44,7 @@ # S scan list entry info: l/empty: launch site name, #=entry nr, t=total entries, a=active entries, /: #/t # K RS41 kill timer values: Kl launch timer, Kb burst timer, Kc kill countdown # format: K_4: h:mm k_6: h:mm:ss k_s: sssss, nothing shown for other sonde -# Mx telemetry value x (t temp p preassure h hyg) [not yet implemented, maybe some day in future] +# Mx telemetry value x (t temp p preassure h hyg b batt) # Gx GPS-related data # raw data from GPS: GA, GO, GH, GC: LAtitude, lOngitude, Altutide(Height), Course over ground # relative to sonde: GD, GI, GB: Distance, dIrection (absolute), relative Bearing @@ -571,3 +571,32 @@ color=639AFF color=FF0000,000000 12.7,0.4=Q4 12.7,18=bVV + +################# +@TelemetryData +scale=22,13 +timer=-1,-1,N +key1action=+,0,F,W +key2action=>,#,#,# +timeaction=#,#,0 +fonts=5,6 +color=FFD700 +0,0,10.5=Is +color=0000FF +0,11,-5.5=f +1,0,4=t +1,10.5,-6=c +color=00ff00 +2,0,7=L +3,0,7=O +color=FFA500 +2,9.5,-7=a +2.8,9.5,-7=vm/s +color=AA5522 +3.6,9.5,-7=hkkm/h +color=FFFFFF +4.4,0=xTelemetry Data: +5.3,0=Mt C +5.3,9=Mh%rH +6.5,0=MphPa +6.5,11=MbV diff --git a/RX_FSK/src/Display.cpp b/RX_FSK/src/Display.cpp index 0272678..eeb8a1a 100644 --- a/RX_FSK/src/Display.cpp +++ b/RX_FSK/src/Display.cpp @@ -1289,26 +1289,40 @@ void Display::drawSite(DispEntry *de) { void Display::drawTelemetry(DispEntry *de) { rdis->setFont(de->fmt); float value=0; + memset(buf, ' ', 16); switch(de->extra[0]) { case 't': value = sonde.si()->d.temperature; - if(value!=0xffff) snprintf(buf, 8, "%3.2f", value); - else strcpy(buf, " "); + if(!isnan(value)) { + sprintf(buf, "%5.1f", value); + strcat(buf, de->extra+1); + } + buf[5+strlen(de->extra+1)] = 0; break; case 'p': value = sonde.si()->d.pressure; - if(value!=0xffff) snprintf(buf, 7, "%4.2f", value); - else strcpy(buf, " "); + if(!isnan(value)) { + if(value>=1000) sprintf(buf, "%6.1f", value); + else sprintf(buf, "%6.2f", value); + strcat(buf, de->extra+1); + } + buf[6+strlen(de->extra+1)] = 0; break; case 'h': value = sonde.si()->d.relativeHumidity; - if(value!=0xffff) snprintf(buf, 5, "%3.1f", value); - else strcpy(buf, " "); + if(!isnan(value)) { + sprintf(buf, "%4.1f", value); + strcat(buf, de->extra+1); + } + buf[4+strlen(de->extra+1)] = 0; break; case 'b': value = sonde.si()->d.batteryVoltage; - if(value!=0xffff) snprintf(buf, 5, "%1.2f", value); - else strcpy(buf, " "); + if(!isnan(value)) { + snprintf(buf, 5, "%4.2f", value); + strcat(buf, de->extra+1); + } + buf[5+strlen(de->extra+1)] = 0; break; } drawString(de,buf); diff --git a/RX_FSK/version.h b/RX_FSK/version.h index d36b78e..20c7c65 100644 --- a/RX_FSK/version.h +++ b/RX_FSK/version.h @@ -1,4 +1,4 @@ const char *version_name = "rdzTTGOsonde"; -const char *version_id = "devel20210924b"; +const char *version_id = "devel20210924c"; const int SPIFFS_MAJOR=2; const int SPIFFS_MINOR=16; From f30c9b6d89662f1aa5bd623eea7432a91d60596c Mon Sep 17 00:00:00 2001 From: "Hansi, dl9rdz" Date: Sat, 25 Sep 2021 10:51:04 +0200 Subject: [PATCH 8/8] exception workaround --- Notes-on-Using-WiFiClient.txt | 18 ++++++++++++++ RX_FSK/RX_FSK.ino | 13 +++++++--- RX_FSK/src/Display.cpp | 45 ++++++++++------------------------- RX_FSK/version.h | 2 +- 4 files changed, 41 insertions(+), 37 deletions(-) create mode 100644 Notes-on-Using-WiFiClient.txt diff --git a/Notes-on-Using-WiFiClient.txt b/Notes-on-Using-WiFiClient.txt new file mode 100644 index 0000000..c854d51 --- /dev/null +++ b/Notes-on-Using-WiFiClient.txt @@ -0,0 +1,18 @@ + +Important behaviour of WiFiClient: + +If anything goes wrong in a read or write operation on a WiFiClient, it internally +will call WiFiClient.stop(), which sets _rxBuffer to NULL and connected to false. + +Subsequently, any function call to WiFiClient that uses _rxBuffer will cause an +>>> Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled. +error and subsequent reboot. + +available() is safe to call (it checks that rxBuffer is not null) +write() is safe to call (it checks that connected is true) +but read() and peek() are not. + +This has been fixed in newer versions of the esp library, see +https://github.com/espressif/arduino-esp32/commit/cb7aef1e886ffe43213f9a090e0a8968205a41df#diff-0d8101826fd3df09b38bef2aeca6d093de76841daf38f65f4fefbf6b56da8f81 + +So there is at least one reason to eventually upgrade to 2.0.0. Currently we stick to 1.0.6. diff --git a/RX_FSK/RX_FSK.ino b/RX_FSK/RX_FSK.ino index 10501fe..64d5c72 100644 --- a/RX_FSK/RX_FSK.ino +++ b/RX_FSK/RX_FSK.ino @@ -3518,9 +3518,16 @@ void sondehub_station_update(WiFiClient * client, struct st_sondehub * conf) { Serial.println(data); Serial.println("Waiting for response"); // TODO: better do this asyncrhonously - String response = client->readString(); - Serial.println(response); - Serial.println("Response done..."); + // 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()) { + String response = client->readString(); + Serial.println(response); + Serial.println("Response done..."); + } else { + Serial.println("SH client connection closed\n"); + } //client->stop(); } diff --git a/RX_FSK/src/Display.cpp b/RX_FSK/src/Display.cpp index eeb8a1a..d014218 100644 --- a/RX_FSK/src/Display.cpp +++ b/RX_FSK/src/Display.cpp @@ -1363,7 +1363,6 @@ void Display::drawKilltimer(DispEntry *de) { #define PI (3.1415926535897932384626433832795) #endif // defined by Arduino.h #define radians(x) ( (x)*180.0F/PI ) -#define FAKEGPS 0 extern int lastCourse; // from RX_FSK.ino @@ -1376,42 +1375,22 @@ float calcLatLonDist(float lat1, float lon1, float lat2, float lon2) { } void Display::calcGPS() { - // base data -#if 0 -#if FAKEGPS - gpsValid = true; - gpsLat = 48.9; - gpsLon = 13.3; - gpsAlt = 33000; -static int tmpc=0; - tmpc = (tmpc+5)%360; - gpsCourse = tmpc; -#else - gpsValid = nmea.isValid(); - gpsLon = nmea.getLongitude()*0.000001; - gpsLat = nmea.getLatitude()*0.000001; - long alt = 0; - nmea.getAltitude(alt); gpsAlt=(int)(alt/1000); - gpsCourse = (int)(nmea.getCourse()/1000); - gpsCourseOld = false; - if(gpsCourse==0) { - // either north or not new - if(lastCourse!=0) // use old value... - { - gpsCourseOld = true; - gpsCourse = lastCourse; - } + float mylat = sonde.config.rxlat; + float mylon = sonde.config.rxlon; + bool valid = !(isnan(mylat)||isnan(mylon)); + if( gpsPos.valid) { + mylat = gpsPos.lat; + mylon = gpsPos.lon; + valid = true; } -#endif -#endif // distance - if( gpsPos.valid && (sonde.si()->d.validPos&0x03)==0x03 && (layout->usegps&GPSUSE_DIST)) { + if( valid && (sonde.si()->d.validPos&0x03)==0x03 && (layout->usegps&GPSUSE_DIST)) { gpsDist = (int)calcLatLonDist(gpsPos.lat, gpsPos.lon, sonde.si()->d.lat, sonde.si()->d.lon); } else { gpsDist = -1; } // bearing - if( gpsPos.valid && (sonde.si()->d.validPos&0x03)==0x03 && (layout->usegps&GPSUSE_BEARING)) { + if( valid && (sonde.si()->d.validPos&0x03)==0x03 && (layout->usegps&GPSUSE_BEARING)) { float lat1 = radians(gpsPos.lat); float lat2 = radians(sonde.si()->d.lat); float lon1 = radians(gpsPos.lon); @@ -1471,7 +1450,7 @@ void Display::drawGPS(DispEntry *de) { if( (sonde.si()->d.validPos&0x03)!=0x03 ) { snprintf(buf, 16, "no pos "); if(de->extra && *de->extra=='5') buf[5]=0; - } else if(!gpsPos.valid) { + } else if( disp.gpsDist < 0 ) { snprintf(buf, 16, "no gps "); if(de->extra && *de->extra=='5') buf[5]=0; } else { @@ -1491,7 +1470,7 @@ void Display::drawGPS(DispEntry *de) { break; case 'I': // dIrection - if( (!gpsPos.valid) || ((sonde.si()->d.validPos&0x03)!=0x03 ) ) { + if( disp.gpsDir<0 ) { // 0..360 valid, -1 invalid drawString(de, "---"); break; } @@ -1503,7 +1482,7 @@ void Display::drawGPS(DispEntry *de) { break; case 'B': // relative bearing - if( (!gpsPos.valid) || ((sonde.si()->d.validPos&0x03)!=0x03 ) ) { + if( disp.gpsBear < 0 ) { // 0..360 valid, -1 invalid drawString(de, "---"); break; } diff --git a/RX_FSK/version.h b/RX_FSK/version.h index 20c7c65..916164c 100644 --- a/RX_FSK/version.h +++ b/RX_FSK/version.h @@ -1,4 +1,4 @@ const char *version_name = "rdzTTGOsonde"; -const char *version_id = "devel20210924c"; +const char *version_id = "devel20210925"; const int SPIFFS_MAJOR=2; const int SPIFFS_MINOR=16;