MP3-H1 extended data for SondeHub upload: #sats, timestamp (for frame#), rrsi; fix for wrong time check; filtering repeated frames

pull/87/head
Hansi, dl9rdz 2021-06-01 01:50:42 +02:00
rodzic ba680295dc
commit e5b340bd63
6 zmienionych plików z 4088 dodań i 22 usunięć

Wyświetl plik

@ -3016,7 +3016,7 @@ const char *dfmSubtypeStrSH[16] = { NULL, NULL, NULL, NULL, NULL, NULL,
};
// in hours.... max allowed diff UTC <-> sonde time
#define SONDEHUB_TIME_THRESHOLD (3)
#define SONDEHUB_TIME_THRESHOLD (3)
void sondehub_send_data(WiFiClient *client, SondeInfo *s, struct st_sondehub *conf) {
Serial.println("sondehub_send_data()");
@ -3040,7 +3040,7 @@ void sondehub_send_data(WiFiClient *client, SondeInfo *s, struct st_sondehub *co
}
// Check if current sonde data is valid. If not, don't do anything....
if (String(s->ser) == "") return; // Don't send anything without serial number
if (*s->ser == 0) return; // Don't send anything without serial number
if (((int)s->lat == 0) && ((int)s->lon == 0)) return; // Sometimes these values are zeroes. Don't send those to the sondehub
if ((int)s->alt > 50000) return; // If alt is too high don't send to SondeHub
if ((int)s->sats < 4) return; // If not enough sats don't send to SondeHub
@ -3067,15 +3067,17 @@ void sondehub_send_data(WiFiClient *client, SondeInfo *s, struct st_sondehub *co
time_t now;
time(&now);
gmtime_r(&now, &timeinfo);
if(timeinfo.tm_year <= (2016-1900)) {
if (timeinfo.tm_year <= (2016 - 1900)) {
Serial.println("Failed to obtain time");
return;
}
if( abs(now - s->time) > (3600*SONDEHUB_TIME_THRESHOLD) ) {
Serial.println("Sonde time too far from current UTC time");
if ( abs(now - (time_t)s->time) > (3600 * SONDEHUB_TIME_THRESHOLD) ) {
Serial.printf("Sonde time %d too far from current UTC time %ld", s->time, now);
return;
}
// DFM uses UTC. Most of the other radiosondes use GPS time
// SondeHub expect datetime to be the same time sytem as the sonde transmits as time stamp
if ( s->type == STYPE_RS41 || s->type == STYPE_RS92 || s->type == STYPE_M10 || s->type == STYPE_M20 ) {
t += 18; // convert back to GPS time from UTC time +18s
}
@ -3112,8 +3114,12 @@ void sondehub_send_data(WiFiClient *client, SondeInfo *s, struct st_sondehub *co
);
w += strlen(w);
if ( TYPE_IS_DFM(s->type) || TYPE_IS_METEO(s->type) ) { //send frame as unix timestamp for these sonde
sprintf(w, "\"frame\": %d,", int(t));
if ( TYPE_IS_DFM(s->type) || TYPE_IS_METEO(s->type) || s->type == 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.
sprintf(w, "\"frame\": %d,", int(t - 315964800));
} else {
sprintf(w, "\"frame\": %d,", s->frame);
}

Wyświetl plik

@ -1,4 +1,4 @@
const char *version_name = "rdzTTGOsonde";
const char *version_id = "devel20210530";
const char *version_id = "devel20210531";
const int SPIFFS_MAJOR=2;
const int SPIFFS_MINOR=11;

Wyświetl plik

@ -392,7 +392,7 @@ static int bitCount(int x) {
return s1;
}
static uint16_t MON[]={0,0,31,59,90,120,151,181,212,243,273,304,334};
uint16_t MON[]={0,0,31,59,90,120,151,181,212,243,273,304,334};
void DFM::decodeDAT(uint8_t *dat)
{

Wyświetl plik

@ -19,6 +19,7 @@ static struct st_mp3hstate {
uint32_t id1, id2;
uint8_t idok;
uint32_t gpsdate;
uint32_t gpsdatetime;
bool dateok;
} mp3hstate;
@ -32,6 +33,8 @@ static int haveNewFrame = 0;
//static int lastFrame = 0;
static int headerDetected = 0;
extern uint16_t MON[];
int MP3H::setup(float frequency)
{
MP3H_DBG(Serial.println("Setup sx1278 for MP3H sonde"));;
@ -243,9 +246,11 @@ void calcgps(uint8_t *buf) {
double vx = i2(buf+pos_GPSecefV) * 0.01;
double vy = i2(buf+pos_GPSecefV+2) * 0.01;
double vz = i2(buf+pos_GPSecefV+4) * 0.01;
if(wx==0 && wy==0 && wz==0) { if(si->validPos&0x7f) { si->validPos |= 0x80; } return; }
// wgs84r
double lat, lng, alt;
wgs84r(wx, wy, wz, &lat, &lng, &alt);
if(alt<-1000 || alt>80000) { if(si->validPos&0x7f) { si->validPos |= 0x80; } return; }
si->lat = (float)(lat*DEG);
si->lon = (float)(lng*DEG);
si->alt = alt;
@ -262,15 +267,52 @@ void calcgps(uint8_t *buf) {
si->dir = dir;
si->vs = clb;
si->hs = sqrt(vn*vn + ve*ve);
si->sats = buf[pos_GPSnSats];
Serial.printf("Pos: %f %f alt %f dir %f vs %f hs %f\n", si->lat, si->lon, si->alt, si->dir, si->vs, si->hs);
si->validPos = 0x3f; // maybe do some checks first...
Serial.printf("Pos: %f %f alt %f dir %f vs %f hs %f sats %d\n", si->lat, si->lon, si->alt, si->dir, si->vs, si->hs, si->sats);
si->validPos = 0x7f;
}
static uint32_t getgpstime(uint8_t *buf) {
return buf[pos_TIME] * 60*60 + buf[pos_TIME+1] * 60 + buf[pos_TIME+2];
}
// unix time stamp from date and time info in frame.
static void getmp3htime(uint8_t *buf) {
SondeInfo *si = sonde.si();
// gpsdate from CFG frame 15 (0 if not yet received)
uint32_t gpsdate = mp3hstate.gpsdate;
uint32_t gpstime = getgpstime(buf);
int tt = 0;
if(gpsdate) {
uint16_t year = (gpsdate%100)+2000;
gpsdate /= 100;
uint8_t month = gpsdate%100;
gpsdate /= 100;
uint8_t day = gpsdate % 100;
// year-month-day to unix time
tt = (year-1970)*365 + (year-1969)/4; // days since 1970
if(month<=12) { tt += MON[month]; if((year%4)==0 && month>2) tt++; }
tt = (tt+day-1)*(60*60*24);
if(gpstime < mp3hstate.gpsdatetime) tt += 60*60*24; // time wrapped since last date tx
Serial.printf("date: %04d-%02d-%02d t%d ", year, month, day, gpstime);
}
tt += gpstime;
si->time = tt;
Serial.printf(" mp3h TIMESTAMP: %d\n", tt);
}
static uint8_t hex(uint32_t n) {
n = n % 16;
return (n<10) ? (n+'0') : (n-10+'A');
}
static void resetmp3h() {
mp3hstate.id1 = mp3hstate.id2 = 0;
mp3hstate.idok = 0;
mp3hstate.gpsdate = 0;
mp3hstate.dateok = 0;
}
// ret: 1=frame ok; 2=frame with errors; 0=ignored frame (m10dop-alternativ)
int MP3H::decodeframeMP3H(uint8_t *data) {
printRaw(data, MP3H_FRAMELEN);
@ -288,13 +330,16 @@ int MP3H::decodeframeMP3H(uint8_t *data) {
if(cnt==15) {
// date
mp3hstate.gpsdate = cfg;
mp3hstate.gpsdatetime = getgpstime(data);
mp3hstate.dateok = true;
} else if(cnt==13) {
// id2
if(mp3hstate.id2 > 0 && mp3hstate.id2 != cfg) { resetmp3h(); }
mp3hstate.id2 = cfg;
mp3hstate.idok |= 2;
} else if(cnt==12) {
// id1
if(mp3hstate.id1 > 0 && mp3hstate.id1 != cfg) { resetmp3h(); }
mp3hstate.id1 = cfg;
mp3hstate.idok |= 1;
}
@ -313,12 +358,14 @@ int MP3H::decodeframeMP3H(uint8_t *data) {
si->id[7] = hex(n/0x10);
si->id[8] = hex(n);
si->id[9] = 0;
snprintf(si->ser, 12, "MRZ-%d-%d", mp3hstate.id1, mp3hstate.id2);
snprintf(si->ser, 12, "%d-%d", mp3hstate.id1, mp3hstate.id2);
si->validID = true;
}
// position
calcgps(data);
// time
getmp3htime(data);
return 1;
#if 0
int repairstep = 16;
@ -429,13 +476,11 @@ void MP3H::processMP3Hdata(uint8_t dt)
// BF3H => 1011 1111 0011 0101 => 10011010 10101010 01011010 01100110 => 9AAA5A66 // 6555a599
if(rxsearching) {
if( rxdata == 0x9AAA5A66 || rxdata == 0x6555a599 ) {
//if( rxdata == 0x9AAA5A66 || rxdata == 0x6555a599 ) {
rxsearching = false;
rxbitc = 0;
rxp = 0;
headerDetected = 1;
Serial.print("SYNC\n");
#if 0
int rssi=sx1278.getRSSI();
int fei=sx1278.getFEI();
int afc=sx1278.getAFC();
@ -444,7 +489,6 @@ void MP3H::processMP3Hdata(uint8_t dt)
Serial.print(" AFC="); Serial.println(afc);
sonde.si()->rssi = rssi;
sonde.si()->afc = afc;
#endif
}
} else {
rxbitc = (rxbitc+1)%16; // 16;
@ -460,10 +504,16 @@ void MP3H::processMP3Hdata(uint8_t dt)
}
}
#define MAXFRAMES 6
int MP3H::receive() {
// we wait for at most 6 frames or until a new seq nr.
uint8_t nFrames = MAXFRAMES; // MP3H sends every frame 6x
static uint32_t lastFrame = 0;
uint8_t retval = RX_TIMEOUT;
unsigned long t0 = millis();
Serial.printf("MP3H::receive() start at %ld\n",t0);
while( millis() - t0 < 1100 ) {
while( millis() - t0 < 1100 + (retval!=RX_TIMEOUT)?1000:0 ) {
uint8_t value = sx1278.readRegister(REG_IRQ_FLAGS2);
if ( bitRead(value, 7) ) {
Serial.println("FIFO full");
@ -488,18 +538,37 @@ int MP3H::receive() {
if(haveNewFrame) {
Serial.printf("MP3H::receive(): new frame complete after %ldms\n", millis()-t0);
printRaw(dataptr, MP3H_FRAMELEN);
int retval = haveNewFrame==1 ? RX_OK: RX_ERROR;
nFrames--;
// frame with CRC error: just skip and retry (unless we have waited for 6 frames alred)
if(haveNewFrame != 1) {
Serial.printf("hNF: %d (ERROR)\n", haveNewFrame);
retval = RX_ERROR;
} else if (sonde.si()->time == lastFrame) { // same frame number as seen before => skip
Serial.printf("Skipping frame with frame# %d\n", lastFrame);
// nothing, wait for next, "new" frame
} else { // good and new frame, return it.
Serial.println("Good frame");
haveNewFrame = 0;
lastFrame = sonde.si()->time;
return RX_OK;
}
haveNewFrame = 0;
return retval;
#if 0
if(nFrames <= 0) {
// up to 6 old or erronous frames received => break out
Serial.printf("nFrames is %di, giving up\n", nFrames);
break;
}
#endif
}
delay(2);
}
}
int32_t afc = sx1278.getAFC();
int16_t rssi = sx1278.getRSSI();
Serial.printf("receive: AFC is %d, RSSI is %.1f\n", afc, rssi/2.0);
int32_t afc = sx1278.getAFC();
int16_t rssi = sx1278.getRSSI();
Serial.printf("receive: AFC is %d, RSSI is %.1f\n", afc, rssi/2.0);
Serial.printf("MP3H::receive() timed out\n");
return RX_TIMEOUT; // TODO RX_OK;
return retval;
}
int MP3H::waitRXcomplete() {

3969
scripts/esptool.py 100755

Plik diff jest za duży Load Diff

Wyświetl plik

@ -3,9 +3,14 @@ import requests
import sys
import os
import socket
import esptool
ttgohost = "rdzsonde.local"
# usually, rdzsonde.mooo.com should be an alias for that:
# or, more specifically:
updatehost = "https://github.com/dl9rdz/rdz_ttgo_sonde/blob/gh-pages/{}/{}?raw=true"
screens = ("screens1.txt", "screens2.txt", "screens3.txt")
allfiles = ("config.txt", "qrg.txt", "networks.txt") + screens
@ -49,6 +54,7 @@ while len(sys.argv)>=2:
if len(sys.argv)<=2:
print("Usage: ",sys.argv[0]," [--ttgo={ip}] [--print|--dir={dir}] <get|put> <all|config|qrg|networks|screens>");
print("or: ",sys.argv[0]," <get|put> file {filename}");
print("or: ",sys.argv[0]," update <devel-xxx|master-yyy>");
print("\n",
" screens is screens1.txt, screens2.txt, screens3.txt");
print(" networks is networks.txt (Wifi ssid and password)")
@ -56,6 +62,22 @@ if len(sys.argv)<=2:
print(" all is screens + network + qrg")
sys.exit(1)
if sys.argv[1]=="update":
# update to a new version...
what = sys.argv[2]
imgdir = "devel"
if what.startswith("master"):
imgdir = "master"
host = updatehost.format(imgdir, what)
data = requests.get(host)
f = open("firmware.bin", "wb")
f.write(data.content)
f.close()
sys._argv = sys.argv[:]
sys.argv=[sys._argv[0],"--chip", "esp32", "--baud", "921600", "--before", "default_reset", "--after", "hard_reset", "write_flash", "-z", "--flash_mode", "dio", "--flash_freq", "80m", "--flash_size", "detect", "0x1000", "firmware.bin"]
esptool.main()
exit(0)
addrinfo = socket.gethostbyname(ttgohost)
url = "http://"+addrinfo+"/"
print("Using URL ",url)