more info (frame#,sats) and time stamps from sonde in aprsmap data
This commit is contained in:
parent
08818e385e
commit
de5308893a
|
|
@ -338,13 +338,15 @@ void addSondeStatus(char *ptr, int i)
|
||||||
struct tm ts;
|
struct tm ts;
|
||||||
SondeInfo *s = &sonde.sondeList[i];
|
SondeInfo *s = &sonde.sondeList[i];
|
||||||
strcat(ptr, "<table>");
|
strcat(ptr, "<table>");
|
||||||
sprintf(ptr + strlen(ptr), "<tr><td id=\"sfreq\">%3.3f MHz, Type: %s</td><tr><td>ID: %s</td></tr><tr><td>QTH: %.6f,%.6f h=%.0fm</td></tr>\n",
|
sprintf(ptr + strlen(ptr), "<tr><td id=\"sfreq\">%3.3f MHz, Type: %s</td><tr><td>ID: %s", s->freq, sondeTypeStr[s->type],
|
||||||
s->freq, sondeTypeStr[s->type],
|
s->validID ? s->id : "<?""?>");
|
||||||
s->validID ? s->id : "<?""?>",
|
if (s->validID && (s->type == STYPE_DFM06 || s->type == STYPE_DFM09 || s->type == STYPE_M10)) {
|
||||||
s->lat, s->lon, s->alt);
|
sprintf(ptr + strlen(ptr), " (ser: %s)", s->ser);
|
||||||
|
}
|
||||||
|
sprintf(ptr + strlen(ptr), "</td></tr><tr><td>QTH: %.6f,%.6f h=%.0fm</td></tr>\n", s->lat, s->lon, s->alt);
|
||||||
const time_t t = s->time;
|
const time_t t = s->time;
|
||||||
ts = *gmtime(&t);
|
ts = *gmtime(&t);
|
||||||
sprintf(ptr + strlen(ptr), "<tr><td>Frame# %d, Sats=%d, %04d-%02d-%02d %02d:%02d:%02d %d</td></tr>",
|
sprintf(ptr + strlen(ptr), "<tr><td>Frame# %d, Sats=%d, %04d-%02d-%02d %02d:%02d:%02d</td></tr>",
|
||||||
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);
|
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), "<tr><td><a target=\"_empty\" href=\"geo:%.6f,%.6f\">GEO-App</a> - ", s->lat, s->lon);
|
sprintf(ptr + strlen(ptr), "<tr><td><a target=\"_empty\" href=\"geo:%.6f,%.6f\">GEO-App</a> - ", s->lat, s->lon);
|
||||||
sprintf(ptr + strlen(ptr), "<a target=\"_empty\" href=\"https://wx.dl2mf.de/?%s\">WX.DL2MF.de</a> - ", s->id);
|
sprintf(ptr + strlen(ptr), "<a target=\"_empty\" href=\"https://wx.dl2mf.de/?%s\">WX.DL2MF.de</a> - ", s->id);
|
||||||
|
|
@ -1497,8 +1499,7 @@ void loopDecoder() {
|
||||||
// first check if ID and position lat+lonis ok
|
// first check if ID and position lat+lonis ok
|
||||||
SondeInfo *s = &sonde.sondeList[rxtask.receiveSonde];
|
SondeInfo *s = &sonde.sondeList[rxtask.receiveSonde];
|
||||||
if (s->validID && ((s->validPos & 0x03) == 0x03)) {
|
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",
|
const char *str = aprs_senddata(s, sonde.config.call, sonde.config.udpfeed.symbol);
|
||||||
sonde.config.udpfeed.symbol);
|
|
||||||
if (connected) {
|
if (connected) {
|
||||||
char raw[201];
|
char raw[201];
|
||||||
int rawlen = aprsstr_mon2raw(str, raw, APRS_MAXLEN);
|
int rawlen = aprsstr_mon2raw(str, raw, APRS_MAXLEN);
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
const char *version_name = "rdzTTGOsonde";
|
const char *version_name = "rdzTTGOsonde";
|
||||||
const char *version_id = "devel20191101";
|
const char *version_id = "devel20191102";
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,9 @@ void DFM::decodeCFG(uint8_t *cfg)
|
||||||
if(idgood==3) {
|
if(idgood==3) {
|
||||||
uint32_t dfmid = (highid<<16) | lowid;
|
uint32_t dfmid = (highid<<16) | lowid;
|
||||||
Serial.print("DFM-09 ID: "); Serial.print(dfmid);
|
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;
|
sonde.si()->validID = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,7 @@ void U8x8Display::welcome() {
|
||||||
drawString(8 - strlen(version_name) / 2, 0, version_name);
|
drawString(8 - strlen(version_name) / 2, 0, version_name);
|
||||||
drawString(8 - strlen(version_id) / 2, 2, version_id);
|
drawString(8 - strlen(version_id) / 2, 2, version_id);
|
||||||
setFont(FONT_SMALL);
|
setFont(FONT_SMALL);
|
||||||
drawString(0, 4, "RS41,RS92,DFM6/9");
|
drawString(0, 4, "RS41/92,DFM,M10");
|
||||||
drawString(0, 6, "by Hansi, DL9RDZ");
|
drawString(0, 6, "by Hansi, DL9RDZ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -427,10 +427,10 @@ void ILI9225Display::welcome() {
|
||||||
setFont(5);
|
setFont(5);
|
||||||
int l=3*22;
|
int l=3*22;
|
||||||
if(sonde.config.tft_orient&1) {
|
if(sonde.config.tft_orient&1) {
|
||||||
drawString(0, 1*22, "RS41,RS92,DFM6/9");
|
drawString(0, 1*22, "RS41/92,DFM6/9,M10");
|
||||||
} else {
|
} else {
|
||||||
drawString(0, 1*22, "RS41,RS92,");
|
drawString(0, 1*22, "RS41,RS92,");
|
||||||
drawString(0, 2*22, "DFM6/9");
|
drawString(0, 2*22, "DFM6/9,M10");
|
||||||
l+=22;
|
l+=22;
|
||||||
}
|
}
|
||||||
drawString(0, l, version_id);
|
drawString(0, l, version_id);
|
||||||
|
|
@ -945,18 +945,21 @@ void Display::drawID(DispEntry *de) {
|
||||||
|
|
||||||
if(!de->extra || de->extra[0]=='s') {
|
if(!de->extra || de->extra[0]=='s') {
|
||||||
// real serial number, as printed on sonde
|
// real serial number, as printed on sonde
|
||||||
drawString(de, sonde.si()->id);
|
drawString(de, sonde.si()->ser);
|
||||||
} else if (de->extra[0]=='a') {
|
} else if (de->extra[0]=='a') {
|
||||||
// autorx sonde number ("DF9" and last 6 digits of real serial number
|
// autorx sonde number ("DF9" and last 6 digits of real serial number)
|
||||||
strcpy(buf, sonde.si()->id);
|
if(sonde.si()->type == STYPE_DFM09) {
|
||||||
|
int n = strlen(sonde.si()->ser) - 6;
|
||||||
|
if(n<0) n=0;
|
||||||
memcpy(buf, "DF9", 3);
|
memcpy(buf, "DF9", 3);
|
||||||
|
memcpy(buf+3, sonde.si()->ser+n, 6);
|
||||||
drawString(de, buf);
|
drawString(de, buf);
|
||||||
|
} else {
|
||||||
|
drawString(de, sonde.si()->ser);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// dxlAPRS sonde number (DF6 (why??) and 5 last digits of serial number as hex number
|
// dxlAPRS sonde number (DF6 (why??) and 5 last digits of serial number as hex number
|
||||||
uint32_t id = atoi(sonde.si()->id);
|
drawString(de, sonde.si()->id);
|
||||||
id = id&0xfffff;
|
|
||||||
snprintf(buf, 16, "DF6%05X", id);
|
|
||||||
drawString(de, buf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Display::drawRSSI(DispEntry *de) {
|
void Display::drawRSSI(DispEntry *de) {
|
||||||
|
|
|
||||||
|
|
@ -18,33 +18,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
static byte data1[512];
|
||||||
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 *dataptr=data1;
|
static byte *dataptr=data1;
|
||||||
|
|
||||||
static uint8_t rxbitc;
|
static uint8_t rxbitc;
|
||||||
static int32_t asynst[10]={0};
|
|
||||||
static uint16_t rxbyte;
|
static uint16_t rxbyte;
|
||||||
static int rxp=0;
|
static int rxp=0;
|
||||||
static int haveNewFrame = 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));
|
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) {
|
static char hex(uint8_t nr) {
|
||||||
nr = nr&0x0f;
|
nr = nr&0x0f;
|
||||||
if(nr<10) return '0'+nr;
|
if(nr<10) return '0'+nr;
|
||||||
|
|
@ -294,6 +275,17 @@ bool M10::decodeframeM10(uint8_t *data) {
|
||||||
ids[8] = hex(id);
|
ids[8] = hex(id);
|
||||||
ids[9] = 0;
|
ids[9] = 0;
|
||||||
strncpy(sonde.si()->id, ids, 10);
|
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;
|
sonde.si()->validID = true;
|
||||||
Serial.printf("ID is %s [%02x %02x %d]\n", ids, data[95], data[93], id);
|
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
|
// ID printed on sonde is ...-.-abbbb, with a=id>>13, bbbb=id&0x1fff in decimal
|
||||||
|
|
|
||||||
|
|
@ -427,6 +427,8 @@ int RS41::decode41(byte *data, int maxlen)
|
||||||
sonde.si()->type=STYPE_RS41;
|
sonde.si()->type=STYPE_RS41;
|
||||||
strncpy(sonde.si()->id, (const char *)(data+p+2), 8);
|
strncpy(sonde.si()->id, (const char *)(data+p+2), 8);
|
||||||
sonde.si()->id[8]=0;
|
sonde.si()->id[8]=0;
|
||||||
|
strncpy(sonde.si()->ser, (const char *)(data+p+2), 8);
|
||||||
|
sonde.si()->ser[8]=0;
|
||||||
sonde.si()->validID=true;
|
sonde.si()->validID=true;
|
||||||
}
|
}
|
||||||
// TODO: some more data
|
// TODO: some more data
|
||||||
|
|
|
||||||
|
|
@ -622,6 +622,7 @@ int RS92::waitRXcomplete() {
|
||||||
si->dir = gpx.vD;
|
si->dir = gpx.vD;
|
||||||
si->validPos = 0x3f;
|
si->validPos = 0x3f;
|
||||||
memcpy(si->id, gpx.id, 9);
|
memcpy(si->id, gpx.id, 9);
|
||||||
|
memcpy(si->ser, gpx.id, 9);
|
||||||
si->validID = true;
|
si->validID = true;
|
||||||
si->frame = gpx.frnr;
|
si->frame = gpx.frnr;
|
||||||
si->sats = gpx.k;
|
si->sats = gpx.k;
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ void Sonde::defaultConfig() {
|
||||||
config.touch_thresh = 70;
|
config.touch_thresh = 70;
|
||||||
config.led_pout = 9;
|
config.led_pout = 9;
|
||||||
config.power_pout = -1;
|
config.power_pout = -1;
|
||||||
|
config.spectrum=10;
|
||||||
// Try autodetecting board type
|
// Try autodetecting board type
|
||||||
// Seems like on startup, GPIO4 is 1 on v1 boards, 0 on v2.1 boards?
|
// Seems like on startup, GPIO4 is 1 on v1 boards, 0 on v2.1 boards?
|
||||||
config.gps_rxd = -1;
|
config.gps_rxd = -1;
|
||||||
|
|
@ -112,6 +113,7 @@ void Sonde::defaultConfig() {
|
||||||
config.oled_rst = 14;
|
config.oled_rst = 14;
|
||||||
config.tft_rs = 2;
|
config.tft_rs = 2;
|
||||||
config.tft_cs = 0;
|
config.tft_cs = 0;
|
||||||
|
config.spectrum = -1; // no spectrum for now on large display
|
||||||
} else {
|
} else {
|
||||||
// OLED display, pins 21,22 ok...
|
// OLED display, pins 21,22 ok...
|
||||||
config.disptype = 0;
|
config.disptype = 0;
|
||||||
|
|
@ -131,6 +133,7 @@ void Sonde::defaultConfig() {
|
||||||
config.oled_rst = 22;
|
config.oled_rst = 22;
|
||||||
config.tft_rs = 2;
|
config.tft_rs = 2;
|
||||||
config.tft_cs = 0;
|
config.tft_cs = 0;
|
||||||
|
config.spectrum = -1; // no spectrum for now on large display
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -151,7 +154,6 @@ void Sonde::defaultConfig() {
|
||||||
config.display[2]=-1;
|
config.display[2]=-1;
|
||||||
config.startfreq=400;
|
config.startfreq=400;
|
||||||
config.channelbw=10;
|
config.channelbw=10;
|
||||||
config.spectrum=10;
|
|
||||||
config.marker=0;
|
config.marker=0;
|
||||||
config.showafc=0;
|
config.showafc=0;
|
||||||
config.freqofs=0;
|
config.freqofs=0;
|
||||||
|
|
@ -191,6 +193,7 @@ void Sonde::setConfig(const char *cfg) {
|
||||||
if(config.noisefloor==0) config.noisefloor=-130;
|
if(config.noisefloor==0) config.noisefloor=-130;
|
||||||
} else if(strcmp(cfg,"call")==0) {
|
} else if(strcmp(cfg,"call")==0) {
|
||||||
strncpy(config.call, val, 9);
|
strncpy(config.call, val, 9);
|
||||||
|
config.call[9]=0;
|
||||||
} else if(strcmp(cfg,"passcode")==0) {
|
} else if(strcmp(cfg,"passcode")==0) {
|
||||||
strncpy(config.passcode, val, 9);
|
strncpy(config.passcode, val, 9);
|
||||||
} else if(strcmp(cfg,"button_pin")==0) {
|
} else if(strcmp(cfg,"button_pin")==0) {
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
#ifndef Sonde_h
|
#ifndef Sonde_h
|
||||||
#define Sonde_h
|
#define Sonde_h
|
||||||
|
|
||||||
#include "aprs.h"
|
|
||||||
|
|
||||||
// RX_TIMEOUT: no header detected
|
// RX_TIMEOUT: no header detected
|
||||||
// RX_ERROR: header detected, but data not decoded (crc error, etc.)
|
// RX_ERROR: header detected, but data not decoded (crc error, etc.)
|
||||||
// RX_OK: header and data ok
|
// 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 };
|
enum SondeType { STYPE_DFM06, STYPE_DFM09, STYPE_RS41, STYPE_RS92, STYPE_M10 };
|
||||||
extern const char *sondeTypeStr[NSondeTypes];
|
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
|
// Used for interacting with the RX background task
|
||||||
typedef struct st_RXTask {
|
typedef struct st_RXTask {
|
||||||
// Variables set by Arduino main loop to value >=0 for requesting
|
// Variables set by Arduino main loop to value >=0 for requesting
|
||||||
|
|
@ -84,6 +118,29 @@ struct st_dfmconfig {
|
||||||
int rxbw;
|
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 {
|
typedef struct st_rdzconfig {
|
||||||
// hardware configuration
|
// hardware configuration
|
||||||
int button_pin; // PIN port number menu button (+128 for touch mode)
|
int button_pin; // PIN port number menu button (+128 for touch mode)
|
||||||
|
|
@ -120,48 +177,13 @@ typedef struct st_rdzconfig {
|
||||||
struct st_dfmconfig dfm;
|
struct st_dfmconfig dfm;
|
||||||
// data feed configuration
|
// data feed configuration
|
||||||
// for now, one feed for each type is enough, but might get extended to more?
|
// 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
|
char passcode[9]; // APRS passcode
|
||||||
struct st_feedinfo udpfeed; // target for AXUDP messages
|
struct st_feedinfo udpfeed; // target for AXUDP messages
|
||||||
struct st_feedinfo tcpfeed; // target for APRS-IS TCP connections
|
struct st_feedinfo tcpfeed; // target for APRS-IS TCP connections
|
||||||
struct st_kisstnc kisstnc; // target for KISS TNC (via TCP, mainly for APRSdroid)
|
struct st_kisstnc kisstnc; // target for KISS TNC (via TCP, mainly for APRSdroid)
|
||||||
} RDZConfig;
|
} 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
|
#define MAXSONDE 99
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <WString.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
//#include <arpa/inet.h>
|
//#include <arpa/inet.h>
|
||||||
//#include <sys/socket.h>
|
//#include <sys/socket.h>
|
||||||
|
|
@ -274,8 +274,8 @@ static uint32_t dao91(double x)
|
||||||
char b[201];
|
char b[201];
|
||||||
char raw[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;
|
*b=0;
|
||||||
aprsstr_append(b, usercall);
|
aprsstr_append(b, usercall);
|
||||||
aprsstr_append(b, ">");
|
aprsstr_append(b, ">");
|
||||||
|
|
@ -284,39 +284,43 @@ char * aprs_senddata(float lat, float lon, float alt, float speed, float dir, fl
|
||||||
// uncompressed
|
// uncompressed
|
||||||
aprsstr_append(b, ":;");
|
aprsstr_append(b, ":;");
|
||||||
char tmp[10];
|
char tmp[10];
|
||||||
snprintf(tmp,10,"%s ",objname);
|
snprintf(tmp,10,"%s ",s->id);
|
||||||
aprsstr_append(b, tmp);
|
aprsstr_append(b, tmp);
|
||||||
aprsstr_append(b, "*");
|
aprsstr_append(b, "*");
|
||||||
// TODO: time
|
// time
|
||||||
//aprsstr_append_data(time, ds);
|
|
||||||
aprsstr_append(b, "121212z");
|
|
||||||
int i = strlen(b);
|
int i = strlen(b);
|
||||||
int lati = abs((int)lat);
|
int sec = s->time % 86400;
|
||||||
int latm = (fabs(lat)-lati)*6000;
|
snprintf(b+i, APRS_MAXLEN-1, "%02d%02d%02dz", sec/(60*60), (sec%(60*60))/60, sec%60);
|
||||||
snprintf(b+i, APRS_MAXLEN-i, "%02d%02d.%02d%c%c", lati, latm/100, latm%100, lat<0?'S':'N', sym[0]);
|
|
||||||
i = strlen(b);
|
i = strlen(b);
|
||||||
int loni = abs((int)lon);
|
//aprsstr_append_data(time, ds);
|
||||||
int lonm = (fabs(lon)-loni)*6000;
|
int lati = abs((int)s->lat);
|
||||||
snprintf(b+i, APRS_MAXLEN-i, "%03d%02d.%02d%c%c", loni, lonm/100, lonm%100, lon<0?'W':'E', sym[1]);
|
int latm = (fabs(s->lat)-lati)*6000;
|
||||||
#if 1
|
snprintf(b+i, APRS_MAXLEN-i, "%02d%02d.%02d%c%c", lati, latm/100, latm%100, s->lat<0?'S':'N', sym[0]);
|
||||||
if(speed>0.5) {
|
|
||||||
i = strlen(b);
|
i = strlen(b);
|
||||||
snprintf(b+i, APRS_MAXLEN-i, "%03d/%03d", realcard(dir+1.5), realcard(speed*1.0/KNOTS+0.5));
|
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(s->dir+1.5), realcard(s->hs*1.0/KNOTS+0.5));
|
||||||
}
|
}
|
||||||
#endif
|
if(s->alt>0.5) {
|
||||||
if(alt>0.5) {
|
|
||||||
i=strlen(b);
|
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;
|
int dao=1;
|
||||||
if(dao) {
|
if(dao) {
|
||||||
i=strlen(b);
|
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
|
strcat(b, "&");
|
||||||
const char *comm="&test";
|
char comm[100];
|
||||||
|
snprintf(comm, 100, "Clb=%.1fm/s %.3fMHz Type=%s", s->vs, s->freq, sondeTypeStr[s->type]);
|
||||||
strcat(b, comm);
|
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;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,14 @@
|
||||||
|
|
||||||
#ifndef _aprs_h
|
#ifndef _aprs_h
|
||||||
#define _aprs_h
|
#define _aprs_h
|
||||||
|
#include "Sonde.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;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define APRS_MAXLEN 201
|
#define APRS_MAXLEN 201
|
||||||
void aprs_gencrctab(void);
|
void aprs_gencrctab(void);
|
||||||
int aprsstr_mon2raw(const char *mon, char raw[], int raw_len);
|
int aprsstr_mon2raw(const char *mon, char raw[], int raw_len);
|
||||||
int aprsstr_mon2kiss(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
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue