| 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,21 +2528,20 @@ void loopDecoder() {
Serial.print("sending: "); Serial.println(raw);
tncclient.write(raw, rawlen);
}
- 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);
- }
- 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) {
@@ -2574,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,"
@@ -2586,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,"
@@ -2623,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,
@@ -2776,13 +2783,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");
@@ -3647,11 +3654,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 913a1a5..ec5fbd3 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[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);
+ }
+ 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..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 = "devel20210923";
+const char *version_id = "devel20210924b";
const int SPIFFS_MAJOR=2;
const int SPIFFS_MINOR=16;
|