Merge branch 'dl9rdz:devel' into devel

pull/161/head
eben80 2021-09-07 14:42:19 +02:00 zatwierdzone przez GitHub
commit 031a8a4819
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
11 zmienionych plików z 98 dodań i 208 usunięć

Wyświetl plik

@ -211,13 +211,7 @@ void setupChannelList() {
} else if (space[1] == 'R') {
type = STYPE_RS92;
}
else if (space[1] == '9') {
type = STYPE_DFM09_OLD;
}
else if (space[1] == '6') {
type = STYPE_DFM06_OLD;
}
else if (space[1] == 'D') {
else if (space[1] == 'D' || space[1] == '9' || space[1] == '6') {
type = STYPE_DFM;
}
else if (space[1] == 'M') {
@ -262,32 +256,6 @@ const char *createQRGForm() {
char *ptr = message;
strcpy(ptr, HTMLHEAD);
strcat(ptr, "<script src=\"rdz.js\"/> <script> window.onload = prep; </script></head>");
/*
strcat(ptr, "<script type=\"text/javascript\">"
"let stypes=new Map();"
"stypes.set('4', 'RS41');"
"stypes.set('R', 'RS92');"
"stypes.set('9', 'DFM9 (old)');"
"stypes.set('6', 'DFM6 (old)');"
"stypes.set('D', 'DFM');"
"stypes.set('M', 'M10');"
"stypes.set('2', 'M20');"
"function prep() {"
" var stlist=document.querySelectorAll(\"input.stype\");"
" for(txt of stlist){"
" var val=txt.getAttribute('value'); var nam=txt.getAttribute('name'); "
" var sel=document.createElement('select');"
" sel.setAttribute('name',nam);"
" for(stype of stypes) { "
" var opt=document.createElement('option');"
" opt.value=stype[0];"
" opt.innerHTML=stype[1];"
" if(stype[0]==val) { opt.setAttribute('selected','selected'); }"
" sel.appendChild(opt);"
" } txt.replaceWith(sel); } } "
" window.onload = prep; "
"</script>");
*/
HTMLBODY(ptr, "qrg.html");
//strcat(ptr, "<body><form class=\"wrapper\" action=\"qrg.html\" method=\"post\"><div class=\"content\"><table><tr><th>ID</th><th>Active</th><th>Freq</th><th>Launchsite</th><th>Mode</th></tr>");
strcat(ptr, "<table><tr><th>ID</th><th>Active</th><th>Freq</th><th>Launchsite</th><th>Mode</th></tr>");
@ -349,6 +317,7 @@ const char *handleQRGPost(AsyncWebServerRequest *request) {
const char *fstr = fstring.c_str();
const char *tstr = tstring.c_str();
const char *sstr = sstring.c_str();
if(*tstr=='6' || *tstr=='9') tstr="D";
Serial.printf("Processing a=%s, f=%s, t=%s, site=%s\n", active ? "YES" : "NO", fstr, tstr, sstr);
char typech = tstr[0];
file.printf("%3.3f %c %c %s\n", atof(fstr), typech, active ? '+' : '-', sstr);
@ -499,7 +468,7 @@ void addSondeStatus(char *ptr, int i)
const time_t t = s->time;
ts = *gmtime(&t);
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);
if (s->type == STYPE_RS41) {
sprintf(ptr + strlen(ptr), "<tr><td>Burst-KT=%d Launch-KT=%d Countdown=%d (vor %ds)</td></tr>\n",
s->burstKT, s->launchKT, s->countKT, ((uint16_t)s->frame - s->crefKT));
@ -1754,9 +1723,9 @@ void IRAM_ATTR button2ISR() {
int getKeyPress() {
KeyPress p = button1.pressed;
button1.pressed = KP_NONE;
//int x = digitalRead(button1.pin);
//Serial.printf("Debug: bdd1=%ld, bdd2=%ld\b", bdd1, bdd2);
//Serial.printf("button1 press (dbl:%d) (now:%d): %d at %ld (%d)\n", button1.doublepress, x, p, button1.keydownTime, button1.numberKeyPresses);
int x = digitalRead(button1.pin);
Serial.printf("Debug: bdd1=%ld, bdd2=%ld\b", bdd1, bdd2);
Serial.printf("button1 press (dbl:%d) (now:%d): %d at %ld (%d)\n", button1.doublepress, x, p, button1.keydownTime, button1.numberKeyPresses);
return p;
}
@ -2074,7 +2043,6 @@ void setup()
sx1278.setup(globalLock);
uint8_t state = 2;
int i=0;
while(++i<3) {
delay(500);
@ -2376,7 +2344,6 @@ void loopDecoder() {
"\"sats\": %d,"
"\"validPos\": %d,"
"\"time\": %d,"
"\"sec\": %d,"
"\"frame\": %d,"
"\"validTime\": %d,"
"\"rssi\": %d,"
@ -2404,7 +2371,6 @@ void loopDecoder() {
s->sats,
s->validPos,
s->time,
s->sec,
s->frame,
(int)s->validTime,
s->rssi,
@ -3214,8 +3180,8 @@ enum SHState { SH_DISCONNECTED, SH_CONNECTING, SH_CONN_IDLE, SH_CONN_APPENDING,
SHState shState = SH_DISCONNECTED;
time_t shStart = 0;
/* Sonde.h: enum SondeType { STYPE_DFM, STYPE_DFM09_OLD, STYPE_RS41, STYPE_RS92, STYPE_M10, STYPE_M20, STYPE_DFM06_OLD, STYPE_MP3H }; */
const char *sondeTypeStrSH[NSondeTypes] = { "DFM", "DFM", "RS41", "RS92", "M10", "M20", "DFM", "MRZ" };
/* Sonde.h: enum SondeType { STYPE_DFM,, STYPE_RS41, STYPE_RS92, STYPE_M10, STYPE_M20, STYPE_MP3H }; */
const char *sondeTypeStrSH[NSondeTypes] = { "DFM", "RS41", "RS92", "M10", "M20", "MRZ" };
const char *dfmSubtypeStrSH[16] = { NULL, NULL, NULL, NULL, NULL, NULL,
"DFM06", // 0x06
"PS15", // 0x07
@ -3246,11 +3212,11 @@ void sondehub_send_data(WiFiClient * client, SondeInfo * s, struct st_sondehub *
// For DFM, s->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
time_t t = s->time + s->sec;
time_t t = s->time;
while (client->available() > 0) {
// data is available from remote server, process it...
int cnt = client->readBytesUntil('\n', rs_msg, MSG_SIZE);
int cnt = client->readBytesUntil('\n', rs_msg, MSG_SIZE-1);
rs_msg[cnt] = 0;
Serial.println(rs_msg);
// If something that looks like a valid HTTP response is received, we are ready to send the next data item
@ -3329,7 +3295,7 @@ void sondehub_send_data(WiFiClient * client, SondeInfo * s, struct st_sondehub *
version_name, version_id, conf->callsign,
timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec,
manufacturer_string[realtype], s->ser,
ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec + s->sec,
ts.tm_year + 1900, ts.tm_mon + 1, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec,
(float)s->lat, (float)s->lon, (float)s->alt, (float)s->freq, (float)s->hs, (float)s->vs,
(float)s->dir, -((float)s->rssi / 2)
);
@ -3340,19 +3306,7 @@ void sondehub_send_data(WiFiClient * client, SondeInfo * s, struct st_sondehub *
w += strlen(w);
}
if ( TYPE_IS_DFM(realtype) || TYPE_IS_METEO(realtype) || realtype == STYPE_MP3H ) {
// send frame as gps timestamp for these sonde, identical to autorx
// For M10, this is real GPS time (seconds since Jqn 6 1980, without adjusting for leap seconds)
// DFM and MP3H send real UTC (with leap seconds considered), so for them the frame number actually
// is gps time plus number of leap seconds since the beginning of GPS time.
int frame = (int)(t - 315964800);
if (realtype == STYPE_M10) {
frame += 18;
};
sprintf(w, "\"frame\": %d,", frame);
} else {
sprintf(w, "\"frame\": %d,", s->frame);
}
sprintf(w, "\"frame\": %d,", s->vframe);
w += strlen(w);
sprintf(w, "\"type\": \"%s\",", sondeTypeStrSH[realtype]);

Wyświetl plik

@ -1,4 +1,4 @@
const char *version_name = "rdzTTGOsonde";
const char *version_id = "devel20210905";
const char *version_id = "devel20210907";
const int SPIFFS_MAJOR=2;
const int SPIFFS_MINOR=14;

Wyświetl plik

@ -23,8 +23,11 @@ static struct st_dfmstat {
uint8_t start[50];
uint16_t dat[50*2];
uint8_t cnt[50*2];
uint16_t good;
uint16_t msec;
uint8_t nameregok;
uint8_t nameregtop;
uint8_t lastdat;
} dfmstate;
int DFM::setup(float frequency, int type)
@ -60,36 +63,8 @@ int DFM::setup(float frequency, int type)
return 1;
}
if(type == STYPE_DFM09_OLD || type == STYPE_DFM06_OLD) {
// packet mode, old version, misses some frames because chip enables rx too late after
// one frame was recevied. TODO: check if this can be fixed by changing parameters
// Enable auto-AFC, auto-AGC, RX Trigger by preamble
if(sx1278.setRxConf(0x1E)!=0) {
DFM_DBG(Serial.println("Setting RX Config FAILED"));
return 1;
}
// Set autostart_RX to 01, preamble 0, SYNC detect==on, syncsize=3 (==4 byte
//char header[] = "0110.0101 0110.0110 1010.0101 1010.1010";
const char *SYNC=(stype==STYPE_DFM09_OLD)?"\x9A\x99\x5A\x55":"\x65\x66\xA5\xAA";
if(sx1278.setSyncConf(0x53, 4, (const uint8_t *)SYNC)!=0) {
DFM_DBG(Serial.println("Setting SYNC Config FAILED"));
return 1;
}
//if(sx1278.setPreambleDetect(0xA8)!=0) {
if(sx1278.setPreambleDetect(0xAA)!=0) {
DFM_DBG(Serial.println("Setting PreambleDetect FAILED"));
return 1;
}
// Packet config 1: fixed len, mancecer, no crc, no address filter
// Packet config 2: packet mode, no home ctrl, no beackn, msb(packetlen)=0)
if(sx1278.setPacketConfig(0x28, 0x40)!=0) {
DFM_DBG(Serial.println("Setting Packet config FAILED"));
return 1;
}
sx1278.setPayloadLength(33); // Expect 33 bytes (7+13+13 bytes)
} else {
// DFM OLD support has been removed
{
// continuous mode
// Enable auto-AFC, auto-AGC, RX Trigger by preamble ????
if(sx1278.setRxConf(0x1E)!=0) {
@ -349,39 +324,10 @@ void DFM::finddfname(uint8_t *b)
void DFM::decodeCFG(uint8_t *cfg)
{
#if 1
// new ID
finddfname(cfg);
// new aprs ID (dxlaprs, autorx) is now "D" + serial (8 digits) by consensus
memcpy(sonde.si()->ser, sonde.si()->id+1, 9);
#else
// old ID
static int lowid, highid, idgood=0, type=0;
if((cfg[0]>>4)==0x06 && type==0) { // DFM-6 ID
lowid = ((cfg[0]&0x0F)<<20) | (cfg[1]<<12) | (cfg[2]<<4) | (cfg[3]&0x0f);
Serial.print("DFM-06 ID: "); Serial.print(lowid, HEX);
snprintf(sonde.si()->id, 10, "%x", lowid);
sonde.si()->validID = true;
}
if((cfg[0]>>4)==0x0A) { // DMF-9 ID
type=9;
if(cfg[3]==1) {
lowid = (cfg[1]<<8) | cfg[2];
idgood |= 1;
} else {
highid = (cfg[1]<<8) | cfg[2];
idgood |= 2;
}
if(idgood==3) {
uint32_t dfmid = (highid<<16) | lowid;
Serial.print("DFM-09 ID: "); Serial.print(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;
}
}
#endif
}
static int bitCount(int x) {
@ -396,19 +342,26 @@ uint16_t MON[]={0,0,31,59,90,120,151,181,212,243,273,304,334};
void DFM::decodeDAT(uint8_t *dat)
{
SondeInfo *si = sonde.si();
Serial.print(" DAT["); Serial.print(dat[6]); Serial.print("]: ");
// We can have a 8 and 0 subframe in a single frame. So do the reset only for dat>0
if( !(dat[6]==0 && dfmstate.lastdat==8) ) { // if we have DAT8 + DAT0, don't reset before returing the 8 frame...
if(dat[6] < dfmstate.lastdat) dfmstate.good = 0; // next iteration detected
}
dfmstate.lastdat = dat[6];
dfmstate.good |= (1<<dat[6]);
switch(dat[6]) {
case 0:
Serial.print("Packet counter: "); Serial.print(dat[3]);
sonde.si()->frame = dat[3];
si->frame = dat[3];
break;
case 1:
{
int val = (((uint16_t)dat[4])<<8) + (uint16_t)dat[5];
Serial.print("UTC-msec: "); Serial.print(val);
sonde.si()->sec = (val+500)/1000;
dfmstate.msec = val;
uint32_t tmp = ((uint32_t)dat[0]<<24) + ((uint32_t)dat[1]<<16) + ((uint32_t)dat[2]<<8) + ((uint32_t)dat[3]);
sonde.si()->sats = bitCount(tmp); // maybe!?!?!?
si->sats = bitCount(tmp);
}
break;
case 2:
@ -418,9 +371,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);
sonde.si()->lat = lat*0.0000001;
sonde.si()->hs = vh*0.01;
sonde.si()->validPos |= 0x11;
si->lat = lat*0.0000001;
si->hs = vh*0.01;
si->validPos |= 0x11;
}
break;
case 3:
@ -430,9 +383,9 @@ void DFM::decodeDAT(uint8_t *dat)
dir = ((uint16_t)dat[4]<<8) + dat[5];
Serial.print("GPS-lon: "); Serial.print(lon*0.0000001);
Serial.print(", dir: "); Serial.print(dir*0.01);
sonde.si()->lon = lon*0.0000001;
sonde.si()->dir = dir*0.01;
sonde.si()->validPos |= 0x42;
si->lon = lon*0.0000001;
si->dir = dir*0.01;
si->validPos |= 0x42;
}
break;
case 4:
@ -442,9 +395,9 @@ void DFM::decodeDAT(uint8_t *dat)
vv = (int16_t)( ((int16_t)dat[4]<<8) | dat[5] );
Serial.print("GPS-height: "); Serial.print(alt*0.01);
Serial.print(", vv: "); Serial.print(vv*0.01);
sonde.si()->alt = alt*0.01;
sonde.si()->vs = vv*0.01;
sonde.si()->validPos |= 0x0C;
si->alt = alt*0.01;
si->vs = vv*0.01;
si->validPos |= 0x0C;
}
break;
case 8:
@ -461,7 +414,14 @@ 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;
sonde.si()->time = tt;
si->time = tt + dfmstate.msec/1000;
// Lets be consistent with autorx: the timestamp uses the msec value truncated to seconds,
// whereas the virtual frame number for DFM uses the msec value rounded to full seconds.
// Actually, tt is real UTC, and the transformation to GPS seconds lacks adjusting for leap seconds
si->vframe = tt + (dfmstate.msec+500)/1000 - 315964800;
// maybe TODO: if we missed the type 0 frame, we still might caculate the right seconds from system time.
// but we only send time stamps to external servers (in particular to sondehub), if all
// required frame types have been correctly decoded, so this does not matter much.
}
break;
default:
@ -538,19 +498,11 @@ int DFM::processDFMdata(uint8_t dt) {
}
int DFM::receive() {
if( stype == STYPE_DFM ) {
return receiveNew();
} else {
return receiveOld();
}
}
int rxframes = 5; // UP TO 5 frames, stop at type 8 frame
int DFM::receiveNew() {
int rxframes = 4;
// tentative continuous RX version...
unsigned long t0 = millis();
while( ( millis() - t0 ) < 1000 ) {
while( ( millis() - t0 ) < 1300 ) {
uint8_t value = sx1278.readRegister(REG_IRQ_FLAGS2);
if ( bitRead(value, 7) ) {
Serial.println("FIFO full");
@ -570,38 +522,24 @@ int DFM::receiveNew() {
processDFMdata(data);
value = sx1278.readRegister(REG_IRQ_FLAGS2);
} else {
#if 0
if(headerDetected) {
t0 = millis(); // restart timer... don't time out if header detected...
headerDetected = 0;
}
#endif
if(haveNewFrame) {
//Serial.printf("DFM::receive(): new frame complete after %ldms\n", millis()-t0);
Serial.printf("receive newframe: %d, good: %x\n", rxframes, dfmstate.good);
haveNewFrame = 0;
rxframes--;
if(rxframes==0) return RX_OK;
if(dfmstate.good & 0x100) {
if(dfmstate.good & 0x11E) {
dfmstate.good = 0; return RX_OK; // type 8 frame has been received
} else {
dfmstate.good = 0; return RX_ERROR;
}
}
if(rxframes==0) return RX_ERROR;
}
delay(2);
}
}
return rxframes == 4 ? RX_TIMEOUT : RX_OK;
}
int DFM::receiveOld() {
byte data[1000]; // pending data from previous mode may write more than 33 bytes. TODO.
for(int i=0; i<2; i++) {
sx1278.setPayloadLength(33); // Expect 33 bytes (7+13+13 bytes)
sx1278.writeRegister(REG_OP_MODE, FSK_RX_MODE);
//int t = millis();
int e = sx1278.receivePacketTimeout(1000, data);
//Serial.printf("rxPTO done after %d ms", (int)(millis()-t));
if(e) { return RX_TIMEOUT; } //if timeout... return 1
if(!(stype==STYPE_DFM09_OLD)) { for(int i=0; i<33; i++) { data[i]^=0xFF; } }
decodeFrameDFM(data);
}
return RX_OK;
return rxframes == 5 ? RX_TIMEOUT : RX_OK;
}
int DFM::decodeFrameDFM(uint8_t *data) {

Wyświetl plik

@ -36,10 +36,6 @@ struct GpsPos gpsPos;
//SPIClass spiDisp(HSPI);
const char *sondeTypeStr[NSondeTypes] = { "DFM ", "DFM9", "RS41", "RS92", "M10 ", "M20 ", "DFM6", "MP3H" };
const char *sondeTypeLongStr[NSondeTypes] = { "DFM (all)", "DFM9 (old)", "RS41", "RS92", "M10 ", "M20 ", "DFM6 (old)", "MP3-H1" };
const char sondeTypeChar[NSondeTypes] = { 'D', '9', '4', 'R', 'M', '2', '6', '3' };
byte myIP_tiles[8*11];
static uint8_t ap_tile[8]={0x00,0x04,0x22,0x92, 0x92, 0x22, 0x04, 0x00};

Wyświetl plik

@ -280,6 +280,7 @@ int M10M20::decodeframeM10(uint8_t *data) {
if(data[1]==0x9F && data[2]==0x20) {
Serial.println("Decoding...");
SondeInfo *si = sonde.si();
// Its a M10
// getid...
char ids[12];
@ -308,23 +309,23 @@ int M10M20::decodeframeM10(uint8_t *data) {
ids[9] = dez((id/10)%10);
ids[10] = dez(id%10);
ids[11] = 0;
strncpy(sonde.si()->ser, ids, 12);
sonde.si()->validID = true;
strncpy(si->ser, ids, 12);
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
// position data
sonde.si()->lat = getint32(data+14) * DEGMUL;
sonde.si()->lon = getint32(data+18) * DEGMUL;
sonde.si()->alt = getint32(data+22) * 0.001;
si->lat = getint32(data+14) * DEGMUL;
si->lon = getint32(data+18) * DEGMUL;
si->alt = getint32(data+22) * 0.001;
float ve = getint16(data+4)*VMUL;
float vn = getint16(data+6)*VMUL;
sonde.si()->vs = getint16(data+8) * VMUL;
sonde.si()->hs = sqrt(ve*ve+vn*vn);
sonde.si()->sats = data[30];
si->vs = getint16(data+8) * VMUL;
si->hs = sqrt(ve*ve+vn*vn);
si->sats = data[30];
float dir = atan2(ve, vn)*(1.0/RAD);
if(dir<0) dir+=360;
sonde.si()->dir = dir;
sonde.si()->validPos = 0x3f;
si->dir = dir;
si->validPos = 0x3f;
uint32_t gpstime = getint32(data+10);
uint16_t gpsweek = getint16(data+32);
@ -333,8 +334,11 @@ int M10M20::decodeframeM10(uint8_t *data) {
// unix epoch starts jan 1st 1970 0:00
// gps time starts jan 6, 1980 0:00. thats 315964800 epoch seconds.
// subtracting 86400 yields 315878400UL
sonde.si()->time = (gpstime/1000) + 86382 + gpsweek*604800 + 315878400UL;
sonde.si()->validTime = true;
si->time = (gpstime/1000) + 86382 + gpsweek*604800 + 315878400UL;
// consistent with autorx, vframe is based on GPS time without the -18 seconds adjustment
// for the GPS time / UTC time difference (included in 86382 above)
si->vframe = si->time - 315964800 + 18;
si->validTime = true;
} else {
Serial.printf("data is %02x %02x %02x\n", data[0], data[1], data[2]);
return 0;
@ -482,6 +486,7 @@ int M10M20::decodeframeM20(uint8_t *data) {
int repl = 0;
bool crcok = false;
bool crcbok = false;
SondeInfo *si = sonde.si();
// error correction, inspired by oe5dxl's sondeudp
// check first block
uint8_t s[200];
@ -532,9 +537,9 @@ 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);
strncpy(sonde.si()->id, ids, 10);
strncpy(si->id, ids, 10);
// Serial: AAB-C-DDEEE
char *ser = sonde.si()->ser;
char *ser = si->ser;
uint8_t tmp = data[18] & 0x7F;
ser[0] = (tmp/12) + '0';
ser[1] = ((tmp%12 + 1) / 10 ) + '0';
@ -551,35 +556,36 @@ int M10M20::decodeframeM20(uint8_t *data) {
// TODO
if(crcok) {
sonde.si()->validID = true;
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
// position data
// 0x1C 4 byte
sonde.si()->lat = getint32(data+28) * 1e-6;
si->lat = getint32(data+28) * 1e-6;
//0x20 4 byte
sonde.si()->lon = getint32(data+32) * 1e-6;
si->lon = getint32(data+32) * 1e-6;
//0x08 3 byte
sonde.si()->alt = getint24(data+8) * VMUL_M20;
si->alt = getint24(data+8) * VMUL_M20;
//0x0B 2 byte
//VMUL_M20 specific
float ve = getint16(data+11)*VMUL_M20;
//0x0D 2 byte
float vn = getint16(data+13)*VMUL_M20;
//0x18 2 byte
sonde.si()->vs = getint16(data+24) * VMUL_M20;
sonde.si()->hs = sqrt(ve*ve+vn*vn);
si->vs = getint16(data+24) * VMUL_M20;
si->hs = sqrt(ve*ve+vn*vn);
float dir = atan2(ve, vn)*(1.0/RAD);
if(dir<0) dir+=360;
sonde.si()->dir = dir;
sonde.si()->validPos = 0x3f;
si->dir = dir;
si->validPos = 0x3f;
//0x0F 3 byte
uint32_t tow = getint24(data+15);
uint16_t week = getint16(data+26);
sonde.si()->time = (tow+week*604800+315964800)-18;
si->time = (tow+week*604800+315964800)-18;
si->vframe = sonde.si()->time - 315964800;
sonde.si()->validTime = true;
si->validTime = true;
}
return crcok?1:2;
}

Wyświetl plik

@ -298,6 +298,7 @@ static void getmp3htime(uint8_t *buf) {
}
tt += gpstime;
si->time = tt;
si->vframe = tt - 315964800;
Serial.printf(" mp3h TIMESTAMP: %d\n", tt);
}

Wyświetl plik

@ -686,7 +686,7 @@ int RS41::decode41(byte *data, int maxlen)
Serial.print("#");
uint16_t fnr = data[p]+(data[p+1]<<8);
Serial.print(fnr);
sonde.si()->frame = fnr;
sonde.si()->vframe = sonde.si()->frame = fnr;
Serial.print("; RS41 ID ");
snprintf(buf, 10, "%.8s ", data+p+2);
Serial.print(buf);

Wyświetl plik

@ -626,7 +626,7 @@ int RS92::waitRXcomplete() {
memcpy(si->id, gpx.id, 9);
memcpy(si->ser, gpx.id, 9);
si->validID = true;
si->frame = gpx.frnr;
si->vframe = si->frame = gpx.frnr;
si->sats = gpx.k;
si->time = (gpx.gpssec/1000) + 86382 + gpx.week*604800 + 315878400UL;
si->validTime = true;

Wyświetl plik

@ -21,7 +21,10 @@ const char *evstring[]={"NONE", "KEY1S", "KEY1D", "KEY1M", "KEY1L", "KEY2S", "KE
const char *RXstr[]={"RX_OK", "RX_TIMEOUT", "RX_ERROR", "RX_UNKNOWN"};
// Dependency to enum SondeType
const char *manufacturer_string[]={"Graw", "Graw", "Vaisala", "Vaisala", "Meteomodem", "Meteomodem", "Graw", "Meteo-Radiy"};
const char *sondeTypeStr[NSondeTypes] = { "DFM ", "RS41", "RS92", "M10 ", "M20 ", "MP3H" };
const char *sondeTypeLongStr[NSondeTypes] = { "DFM (all)", "RS41", "RS92", "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"};
int fingerprintValue[]={ 17, 31, 64, 4, 55, 48, 23, 128+23, 119, 128+119, -1 };
const char *fingerprintText[]={
@ -526,8 +529,6 @@ void Sonde::setup() {
case STYPE_RS41:
rs41.setup(sondeList[rxtask.currentSonde].freq * 1000000);
break;
case STYPE_DFM06_OLD:
case STYPE_DFM09_OLD:
case STYPE_DFM:
dfm.setup( sondeList[rxtask.currentSonde].freq * 1000000, sondeList[rxtask.currentSonde].type );
break;
@ -568,8 +569,6 @@ void Sonde::receive() {
case STYPE_M20:
res = m10m20.receive();
break;
case STYPE_DFM06_OLD:
case STYPE_DFM09_OLD:
case STYPE_DFM:
res = dfm.receive();
break;
@ -668,8 +667,6 @@ rxloop:
case STYPE_M20:
m10m20.waitRXcomplete();
break;
case STYPE_DFM06_OLD:
case STYPE_DFM09_OLD:
case STYPE_DFM:
dfm.waitRXcomplete();
break;

Wyświetl plik

@ -53,14 +53,14 @@ extern const char *RXstr[];
// 01000000 => goto sonde -1
// 01000001 => goto sonde +1
#define NSondeTypes 8
enum SondeType { STYPE_DFM, STYPE_DFM09_OLD, STYPE_RS41, STYPE_RS92, STYPE_M10, STYPE_M20, STYPE_DFM06_OLD, STYPE_MP3H };
#define NSondeTypes 6
enum SondeType { STYPE_DFM, STYPE_RS41, STYPE_RS92, STYPE_M10, STYPE_M20, STYPE_MP3H };
extern const char *sondeTypeStr[NSondeTypes];
extern const char *sondeTypeLongStr[NSondeTypes];
extern const char sondeTypeChar[NSondeTypes];
extern const char *manufacturer_string[NSondeTypes];
#define TYPE_IS_DFM(t) ( (t)==STYPE_DFM || (t)==STYPE_DFM09_OLD || (t)==STYPE_DFM06_OLD )
#define TYPE_IS_DFM(t) ( (t)==STYPE_DFM )
#define TYPE_IS_METEO(t) ( (t)==STYPE_M10 || (t)==STYPE_M20 )
typedef struct st_sondeinfo {
@ -86,8 +86,8 @@ typedef struct st_sondeinfo {
uint8_t validPos; // bit pattern for validity of above 7 fields; 0x80: position is old
// decoded GPS time
uint32_t time;
uint16_t sec;
uint32_t frame;
uint32_t vframe; // vframe==frame if frame is unique/continous, otherweise vframe is derived from gps time
bool validTime;
// RSSI from receiver
int rssi; // signal strength

Wyświetl plik

@ -74,7 +74,6 @@ void MQTT::publishPacket(SondeInfo *s)
"\"sats\": %d,"
"\"validPos\": %d,"
"\"time\": %d,"
"\"sec\": %d,"
"\"frame\": %d,"
"\"validTime\": %d,"
"\"rssi\": %d,"
@ -104,7 +103,6 @@ void MQTT::publishPacket(SondeInfo *s)
s->sats,
s->validPos,
s->time,
s->sec,
s->frame,
(int)s->validTime,
s->rssi,