diff --git a/RX_FSK/RX_FSK.ino b/RX_FSK/RX_FSK.ino
index 89dcf23..c9f0dc5 100644
--- a/RX_FSK/RX_FSK.ino
+++ b/RX_FSK/RX_FSK.ino
@@ -227,7 +227,7 @@ const char *handleQRGPost(AsyncWebServerRequest *request) {
const char *tstr = tstring.c_str();
const char *sstr = sstring.c_str();
Serial.printf("Processing a=%s, f=%s, t=%s, site=%s\n", active ? "YES" : "NO", fstr, tstr, sstr);
- char typech = (tstr[2] == '4' ? '4' : tstr[2] == '9' ? 'R' : tstr[0]=='M' ? 'M' : tstr[3]); // a bit ugly
+ char typech = (tstr[2] == '4' ? '4' : tstr[2] == '9' ? 'R' : tstr[0] == 'M' ? 'M' : tstr[3]); // a bit ugly
file.printf("%3.3f %c %c %s\n", atof(fstr), typech, active ? '+' : '-', sstr);
}
file.close();
@@ -338,14 +338,16 @@ 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 |
| QTH: %.6f,%.6f h=%.0fm |
\n",
- s->freq, sondeTypeStr[s->type],
- s->validID ? s->id : """?>",
- s->lat, s->lon, s->alt);
+ sprintf(ptr + strlen(ptr), "| %3.3f MHz, Type: %s |
| ID: %s", s->freq, sondeTypeStr[s->type],
+ s->validID ? s->id : """?>");
+ if (s->validID && (s->type == STYPE_DFM06 || s->type == STYPE_DFM09 || s->type == STYPE_M10)) {
+ sprintf(ptr + strlen(ptr), " (ser: %s)", s->ser);
+ }
+ sprintf(ptr + strlen(ptr), " |
| QTH: %.6f,%.6f h=%.0fm |
\n", s->lat, s->lon, s->alt);
const time_t t = s->time;
ts = *gmtime(&t);
- sprintf(ptr + strlen(ptr), "| Frame# %d, Sats=%d, %04d-%02d-%02d %02d:%02d:%02d %d |
",
- s->frame, s->sats, ts.tm_year+1900, ts.tm_mon+1, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec+s->sec);
+ sprintf(ptr + strlen(ptr), "| Frame# %d, Sats=%d, %04d-%02d-%02d %02d:%02d:%02d |
",
+ s->frame, s->sats, ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec + s->sec);
sprintf(ptr + strlen(ptr), "| GEO-App - ", s->lat, s->lon);
sprintf(ptr + strlen(ptr), "WX.DL2MF.de - ", s->id);
sprintf(ptr + strlen(ptr), "OSM |
", s->lat, s->lon);
@@ -1497,8 +1499,7 @@ void loopDecoder() {
// first check if ID and position lat+lonis ok
SondeInfo *s = &sonde.sondeList[rxtask.receiveSonde];
if (s->validID && ((s->validPos & 0x03) == 0x03)) {
- const char *str = aprs_senddata(s->lat, s->lon, s->alt, s->hs, s->dir, s->vs, sondeTypeStr[s->type], s->id, "TE0ST",
- sonde.config.udpfeed.symbol);
+ const char *str = aprs_senddata(s, sonde.config.call, sonde.config.udpfeed.symbol);
if (connected) {
char raw[201];
int rawlen = aprsstr_mon2raw(str, raw, APRS_MAXLEN);
diff --git a/RX_FSK/version.h b/RX_FSK/version.h
index 62f5e9f..96c51eb 100644
--- a/RX_FSK/version.h
+++ b/RX_FSK/version.h
@@ -1,2 +1,2 @@
const char *version_name = "rdzTTGOsonde";
-const char *version_id = "devel20191101";
+const char *version_id = "devel20191102";
diff --git a/libraries/SondeLib/DFM.cpp b/libraries/SondeLib/DFM.cpp
index cd0de38..a0fad81 100644
--- a/libraries/SondeLib/DFM.cpp
+++ b/libraries/SondeLib/DFM.cpp
@@ -183,7 +183,9 @@ void DFM::decodeCFG(uint8_t *cfg)
if(idgood==3) {
uint32_t dfmid = (highid<<16) | lowid;
Serial.print("DFM-09 ID: "); Serial.print(dfmid);
- snprintf(sonde.si()->id, 10, "%d", dfmid);
+ snprintf(sonde.si()->ser, 10, "%d", dfmid);
+ // dxlAPRS sonde number (DF6 (why??) and 5 last digits of serial number as hex number
+ snprintf(sonde.si()->id, 9, "DF6%05X", dfmid&0xfffff);
sonde.si()->validID = true;
}
}
diff --git a/libraries/SondeLib/Display.cpp b/libraries/SondeLib/Display.cpp
index aec3bf8..5d86097 100644
--- a/libraries/SondeLib/Display.cpp
+++ b/libraries/SondeLib/Display.cpp
@@ -24,7 +24,7 @@ extern bool axp192_found;
SPIClass spiDisp(HSPI);
-const char *sondeTypeStr[NSondeTypes] = { "DFM6", "DFM9", "RS41", "RS92", "M10 " };
+const char *sondeTypeStr[NSondeTypes] = { "DFM6", "DFM9", "RS41", "RS92", "M10" };
byte myIP_tiles[8*11];
static uint8_t ap_tile[8]={0x00,0x04,0x22,0x92, 0x92, 0x22, 0x04, 0x00};
@@ -256,7 +256,7 @@ void U8x8Display::welcome() {
drawString(8 - strlen(version_name) / 2, 0, version_name);
drawString(8 - strlen(version_id) / 2, 2, version_id);
setFont(FONT_SMALL);
- drawString(0, 4, "RS41,RS92,DFM6/9");
+ drawString(0, 4, "RS41/92,DFM,M10");
drawString(0, 6, "by Hansi, DL9RDZ");
}
@@ -427,10 +427,10 @@ void ILI9225Display::welcome() {
setFont(5);
int l=3*22;
if(sonde.config.tft_orient&1) {
- drawString(0, 1*22, "RS41,RS92,DFM6/9");
+ drawString(0, 1*22, "RS41/92,DFM6/9,M10");
} else {
drawString(0, 1*22, "RS41,RS92,");
- drawString(0, 2*22, "DFM6/9");
+ drawString(0, 2*22, "DFM6/9,M10");
l+=22;
}
drawString(0, l, version_id);
@@ -945,18 +945,21 @@ void Display::drawID(DispEntry *de) {
if(!de->extra || de->extra[0]=='s') {
// real serial number, as printed on sonde
- drawString(de, sonde.si()->id);
+ drawString(de, sonde.si()->ser);
} else if (de->extra[0]=='a') {
- // autorx sonde number ("DF9" and last 6 digits of real serial number
- strcpy(buf, sonde.si()->id);
- memcpy(buf, "DF9", 3);
- drawString(de, buf);
+ // autorx sonde number ("DF9" and last 6 digits of real serial number)
+ if(sonde.si()->type == STYPE_DFM09) {
+ int n = strlen(sonde.si()->ser) - 6;
+ if(n<0) n=0;
+ memcpy(buf, "DF9", 3);
+ memcpy(buf+3, sonde.si()->ser+n, 6);
+ drawString(de, buf);
+ } else {
+ drawString(de, sonde.si()->ser);
+ }
} else {
// dxlAPRS sonde number (DF6 (why??) and 5 last digits of serial number as hex number
- uint32_t id = atoi(sonde.si()->id);
- id = id&0xfffff;
- snprintf(buf, 16, "DF6%05X", id);
- drawString(de, buf);
+ drawString(de, sonde.si()->id);
}
}
void Display::drawRSSI(DispEntry *de) {
diff --git a/libraries/SondeLib/M10.cpp b/libraries/SondeLib/M10.cpp
index b94d976..004c979 100644
--- a/libraries/SondeLib/M10.cpp
+++ b/libraries/SondeLib/M10.cpp
@@ -18,33 +18,10 @@
#endif
-#if 0
-static double atang2(double x, double y)
-{
- double w;
- if (fabs(x)>fabs(y)) {
- w = (double)atan((float)(X2C_DIVL(y,x)));
- if (x<0.0) {
- if (y>0.0) w = 3.1415926535898+w;
- else w = w-3.1415926535898;
- }
- }
- else if (y!=0.0) {
- w = (double)(1.5707963267949f-atan((float)(X2C_DIVL(x,
- y))));
- if (y<0.0) w = w-3.1415926535898;
- }
- else w = 0.0;
- return w;
-} /* end atang2() */
-#endif
-
-static byte data1[512]={0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x10};
-static byte data2[512]={0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x10};
+static byte data1[512];
static byte *dataptr=data1;
static uint8_t rxbitc;
-static int32_t asynst[10]={0};
static uint16_t rxbyte;
static int rxp=0;
static int haveNewFrame = 0;
@@ -239,6 +216,10 @@ static int16_t getint16(uint8_t *data) {
return (int16_t)(data[1]|((uint16_t)data[0]<<8));
}
+static char dez(uint8_t nr) {
+ nr = nr%10;
+ return '0'+nr;
+}
static char hex(uint8_t nr) {
nr = nr&0x0f;
if(nr<10) return '0'+nr;
@@ -294,6 +275,17 @@ bool M10::decodeframeM10(uint8_t *data) {
ids[8] = hex(id);
ids[9] = 0;
strncpy(sonde.si()->id, ids, 10);
+ ids[0] = hex(data[95]/16);
+ ids[1] = dez((data[95]&0x0f)/10);
+ ids[2] = dez((data[95]&0x0f));
+ ids[3] = dez(data[93]);
+ ids[4] = dez(id>>13);
+ id &= 0x1fff;
+ ids[5] = dez(id/1000);
+ ids[6] = dez((id/100)%10);
+ ids[7] = dez((id/10)%10);
+ ids[8] = dez(id%10);
+ strncpy(sonde.si()->ser, ids, 10);
sonde.si()->validID = true;
Serial.printf("ID is %s [%02x %02x %d]\n", ids, data[95], data[93], id);
// ID printed on sonde is ...-.-abbbb, with a=id>>13, bbbb=id&0x1fff in decimal
diff --git a/libraries/SondeLib/RS41.cpp b/libraries/SondeLib/RS41.cpp
index 63264df..d885806 100644
--- a/libraries/SondeLib/RS41.cpp
+++ b/libraries/SondeLib/RS41.cpp
@@ -427,6 +427,8 @@ int RS41::decode41(byte *data, int maxlen)
sonde.si()->type=STYPE_RS41;
strncpy(sonde.si()->id, (const char *)(data+p+2), 8);
sonde.si()->id[8]=0;
+ strncpy(sonde.si()->ser, (const char *)(data+p+2), 8);
+ sonde.si()->ser[8]=0;
sonde.si()->validID=true;
}
// TODO: some more data
diff --git a/libraries/SondeLib/RS92.cpp b/libraries/SondeLib/RS92.cpp
index 3c6cdd1..5d777ed 100644
--- a/libraries/SondeLib/RS92.cpp
+++ b/libraries/SondeLib/RS92.cpp
@@ -622,6 +622,7 @@ int RS92::waitRXcomplete() {
si->dir = gpx.vD;
si->validPos = 0x3f;
memcpy(si->id, gpx.id, 9);
+ memcpy(si->ser, gpx.id, 9);
si->validID = true;
si->frame = gpx.frnr;
si->sats = gpx.k;
diff --git a/libraries/SondeLib/Sonde.cpp b/libraries/SondeLib/Sonde.cpp
index 54f5541..51a1843 100644
--- a/libraries/SondeLib/Sonde.cpp
+++ b/libraries/SondeLib/Sonde.cpp
@@ -70,6 +70,7 @@ void Sonde::defaultConfig() {
config.touch_thresh = 70;
config.led_pout = 9;
config.power_pout = -1;
+ config.spectrum=10;
// Try autodetecting board type
// Seems like on startup, GPIO4 is 1 on v1 boards, 0 on v2.1 boards?
config.gps_rxd = -1;
@@ -112,6 +113,7 @@ void Sonde::defaultConfig() {
config.oled_rst = 14;
config.tft_rs = 2;
config.tft_cs = 0;
+ config.spectrum = -1; // no spectrum for now on large display
} else {
// OLED display, pins 21,22 ok...
config.disptype = 0;
@@ -131,6 +133,7 @@ void Sonde::defaultConfig() {
config.oled_rst = 22;
config.tft_rs = 2;
config.tft_cs = 0;
+ config.spectrum = -1; // no spectrum for now on large display
}
}
} else {
@@ -151,7 +154,6 @@ void Sonde::defaultConfig() {
config.display[2]=-1;
config.startfreq=400;
config.channelbw=10;
- config.spectrum=10;
config.marker=0;
config.showafc=0;
config.freqofs=0;
@@ -191,6 +193,7 @@ void Sonde::setConfig(const char *cfg) {
if(config.noisefloor==0) config.noisefloor=-130;
} else if(strcmp(cfg,"call")==0) {
strncpy(config.call, val, 9);
+ config.call[9]=0;
} else if(strcmp(cfg,"passcode")==0) {
strncpy(config.passcode, val, 9);
} else if(strcmp(cfg,"button_pin")==0) {
diff --git a/libraries/SondeLib/Sonde.h b/libraries/SondeLib/Sonde.h
index 3135cde..2f6b186 100644
--- a/libraries/SondeLib/Sonde.h
+++ b/libraries/SondeLib/Sonde.h
@@ -2,8 +2,6 @@
#ifndef Sonde_h
#define Sonde_h
-#include "aprs.h"
-
// RX_TIMEOUT: no header detected
// RX_ERROR: header detected, but data not decoded (crc error, etc.)
// RX_OK: header and data ok
@@ -51,6 +49,42 @@ extern const char *RXstr[];
enum SondeType { STYPE_DFM06, STYPE_DFM09, STYPE_RS41, STYPE_RS92, STYPE_M10 };
extern const char *sondeTypeStr[NSondeTypes];
+typedef struct st_sondeinfo {
+ // receiver configuration
+ bool active;
+ SondeType type;
+ float freq;
+ // decoded ID
+ char id[10];
+ char ser[12];
+ bool validID;
+ char launchsite[18];
+ // decoded position
+ float lat; // latitude
+ float lon; // longitude
+ float alt; // altitude
+ float vs; // vertical speed
+ float hs; // horizontal speed
+ float dir; // 0..360
+ uint8_t sats; // number of sats
+ uint8_t validPos; // bit pattern for validity of above 6 fields
+ // decoded GPS time
+ uint32_t time;
+ uint16_t sec;
+ uint32_t frame;
+ bool validTime;
+ // RSSI from receiver
+ int rssi; // signal strength
+ int32_t afc; // afc correction value
+ // statistics
+ uint8_t rxStat[20];
+ uint32_t rxStart; // millis() timestamp of continuous rx start
+ uint32_t norxStart; // millis() timestamp of continuous no rx start
+ uint32_t viewStart; // millis() timestamp of viewinf this sonde with current display
+ int8_t lastState; // -1: disabled; 0: norx; 1: rx
+} SondeInfo;
+// rxStat: 3=undef[empty] 1=timeout[.] 2=errro[E] 3=ok[1] 5=no valid position[°]
+
// Used for interacting with the RX background task
typedef struct st_RXTask {
// Variables set by Arduino main loop to value >=0 for requesting
@@ -84,6 +118,29 @@ struct st_dfmconfig {
int rxbw;
};
+
+enum IDTYPE { ID_DFMDXL, ID_DFMGRAW, ID_DFMAUTO };
+
+struct st_feedinfo {
+ bool active;
+ int type; // 0:UDP(axudp), 1:TCP(aprs.fi)
+ char host[64];
+ int port;
+ char symbol[3];
+ 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;
+};
+
+
typedef struct st_rdzconfig {
// hardware configuration
int button_pin; // PIN port number menu button (+128 for touch mode)
@@ -120,48 +177,13 @@ typedef struct st_rdzconfig {
struct st_dfmconfig dfm;
// data feed configuration
// for now, one feed for each type is enough, but might get extended to more?
- char call[9]; // APRS callsign
+ char call[10]; // APRS callsign
char passcode[9]; // APRS passcode
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)
} RDZConfig;
-typedef struct st_sondeinfo {
- // receiver configuration
- bool active;
- SondeType type;
- float freq;
- // decoded ID
- char id[10];
- bool validID;
- char launchsite[18];
- // decoded position
- float lat; // latitude
- float lon; // longitude
- float alt; // altitude
- float vs; // vertical speed
- float hs; // horizontal speed
- float dir; // 0..360
- uint8_t sats; // number of sats
- uint8_t validPos; // bit pattern for validity of above 6 fields
- // decoded GPS time
- uint32_t time;
- uint16_t sec;
- uint32_t frame;
- bool validTime;
- // RSSI from receiver
- int rssi; // signal strength
- int32_t afc; // afc correction value
- // statistics
- uint8_t rxStat[20];
- uint32_t rxStart; // millis() timestamp of continuous rx start
- uint32_t norxStart; // millis() timestamp of continuous no rx start
- uint32_t viewStart; // millis() timestamp of viewinf this sonde with current display
- int8_t lastState; // -1: disabled; 0: norx; 1: rx
-} SondeInfo;
-// rxStat: 3=undef[empty] 1=timeout[.] 2=errro[E] 3=ok[1] 5=no valid position[°]
-
#define MAXSONDE 99
diff --git a/libraries/SondeLib/aprs.cpp b/libraries/SondeLib/aprs.cpp
index bfa73fc..0b7b14b 100644
--- a/libraries/SondeLib/aprs.cpp
+++ b/libraries/SondeLib/aprs.cpp
@@ -8,7 +8,7 @@
*/
#include
-#include
+#include
#include
//#include
//#include
@@ -274,8 +274,8 @@ static uint32_t dao91(double x)
char b[201];
char raw[201];
-char * aprs_senddata(float lat, float lon, float alt, float speed, float dir, float climb, const char *type, const char *objname, const char *usercall, const char *sym)
-{
+char *aprs_senddata(SondeInfo *s, 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)
*b=0;
aprsstr_append(b, usercall);
aprsstr_append(b, ">");
@@ -284,39 +284,43 @@ char * aprs_senddata(float lat, float lon, float alt, float speed, float dir, fl
// uncompressed
aprsstr_append(b, ":;");
char tmp[10];
- snprintf(tmp,10,"%s ",objname);
+ snprintf(tmp,10,"%s ",s->id);
aprsstr_append(b, tmp);
aprsstr_append(b, "*");
- // TODO: time
- //aprsstr_append_data(time, ds);
- aprsstr_append(b, "121212z");
+ // time
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]);
+ int sec = s->time % 86400;
+ snprintf(b+i, APRS_MAXLEN-1, "%02d%02d%02dz", sec/(60*60), (sec%(60*60))/60, sec%60);
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]);
-#if 1
- if(speed>0.5) {
+ //aprsstr_append_data(time, ds);
+ int lati = abs((int)s->lat);
+ int latm = (fabs(s->lat)-lati)*6000;
+ snprintf(b+i, APRS_MAXLEN-i, "%02d%02d.%02d%c%c", lati, latm/100, latm%100, s->lat<0?'S':'N', sym[0]);
+ i = strlen(b);
+ int loni = abs((int)s->lon);
+ int lonm = (fabs(s->lon)-loni)*6000;
+ 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(dir+1.5), realcard(speed*1.0/KNOTS+0.5));
+ snprintf(b+i, APRS_MAXLEN-i, "%03d/%03d", realcard(s->dir+1.5), realcard(s->hs*1.0/KNOTS+0.5));
}
-#endif
- if(alt>0.5) {
+ if(s->alt>0.5) {
i=strlen(b);
- snprintf(b+i, APRS_MAXLEN-i, "/A=%06d", realcard(alt*FEET+0.5));
+ snprintf(b+i, APRS_MAXLEN-i, "/A=%06d", realcard(s->alt*FEET+0.5));
}
-#if 1
int dao=1;
if(dao) {
i=strlen(b);
- snprintf(b+i, APRS_MAXLEN-i, "!w%c%c!", 33+dao91(lat), 33+dao91(lon));
+ snprintf(b+i, APRS_MAXLEN-i, "!w%c%c!", 33+dao91(s->lat), 33+dao91(s->lon));
}
-#endif
- const char *comm="&test";
+ strcat(b, "&");
+ char comm[100];
+ snprintf(comm, 100, "Clb=%.1fm/s %.3fMHz Type=%s", s->vs, s->freq, sondeTypeStr[s->type]);
strcat(b, comm);
+ if(s->type==STYPE_M10||s->type==STYPE_DFM06||s->type==STYPE_DFM09) {
+ snprintf(comm, 100, " ser=%s", s->ser);
+ strcat(b, comm);
+ }
return b;
}
diff --git a/libraries/SondeLib/aprs.h b/libraries/SondeLib/aprs.h
index 5f993fd..6ac8b8e 100644
--- a/libraries/SondeLib/aprs.h
+++ b/libraries/SondeLib/aprs.h
@@ -1,34 +1,14 @@
#ifndef _aprs_h
#define _aprs_h
-
-enum IDTYPE { ID_DFMDXL, ID_DFMGRAW, ID_DFMAUTO };
-
-struct st_feedinfo {
- bool active;
- int type; // 0:UDP(axudp), 1:TCP(aprs.fi)
- char host[64];
- int port;
- char symbol[3];
- 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;
-};
+#include "Sonde.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(float lat, float lon, float alt, float speed, float dir, float climb, const char *type, const char *objname, const char *usercall, const char *sym);
+char *aprs_senddata(SondeInfo *s, const char *usercall, const char *sym);
#endif