Experimental: Modified DFM handling (DFM17 vs DFM09P for 0xC), untested
This commit is contained in:
parent
7a1b97cacf
commit
40f1ab731a
|
|
@ -19,14 +19,18 @@
|
|||
#include "src/Display.h"
|
||||
#include "src/Scanner.h"
|
||||
#include "src/geteph.h"
|
||||
#ifdef FEATURE_RS92
|
||||
#include "src/rs92gps.h"
|
||||
#endif
|
||||
#include "src/aprs.h"
|
||||
#include "src/ShFreqImport.h"
|
||||
#include "src/RS41.h"
|
||||
#include "src/DFM.h"
|
||||
#include "src/json.h"
|
||||
#if FEATURE_CHASEMAPPER
|
||||
#include "src/Chasemapper.h"
|
||||
#endif
|
||||
//#include "NimBLEDevice.h"
|
||||
|
||||
#if FEATURE_MQTT
|
||||
#include "src/mqtt.h"
|
||||
|
|
@ -67,6 +71,9 @@ WiFiClient client;
|
|||
|
||||
/* Sonde.h: enum SondeType { STYPE_DFM,, STYPE_RS41, STYPE_RS92, STYPE_M10M20, STYPE_M10, STYPE_M20, STYPE_MP3H }; */
|
||||
const char *sondeTypeStrSH[NSondeTypes] = { "DFM", "RS41", "RS92", "Mxx"/*never sent*/, "M10", "M20", "MRZ" };
|
||||
|
||||
#if 0
|
||||
// not used any more
|
||||
const char *dfmSubtypeStrSH[16] = { NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
"DFM06", // 0x06
|
||||
"PS15", // 0x07
|
||||
|
|
@ -77,6 +84,7 @@ const char *dfmSubtypeStrSH[16] = { NULL, NULL, NULL, NULL, NULL, NULL,
|
|||
"DFM17", // 0x0D
|
||||
NULL, NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
// Times in ms, i.e. station: 10 minutes, mobile: 20 seconds
|
||||
#define APRS_STATION_UPDATE_TIME (10*60*1000)
|
||||
|
|
@ -1878,12 +1886,17 @@ void heap_caps_alloc_failed_hook(size_t requested_size, uint32_t caps, const cha
|
|||
void setup()
|
||||
{
|
||||
char buf[12];
|
||||
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(/*921600 */115200);
|
||||
for (int i = 0; i < 39; i++) {
|
||||
int v = gpio_get_level((gpio_num_t)i);
|
||||
Serial.printf("%d:%d ", i, v);
|
||||
}
|
||||
|
||||
//NimBLEDevice::init("NimBLE-Arduino");
|
||||
//NimBLEServer* pServer = NimBLEDevice::createServer();;
|
||||
|
||||
Serial.println("");
|
||||
#ifdef ESP_MEM_DEBUG
|
||||
esp_err_t error = heap_caps_register_failed_alloc_callback(heap_caps_alloc_failed_hook);
|
||||
|
|
@ -2960,6 +2973,7 @@ void loopWifiScan() {
|
|||
sonde.setIP(localIPstr.c_str(), false);
|
||||
sonde.updateDisplayIP();
|
||||
wifi_state = WIFI_CONNECTED;
|
||||
#if FEATURE_RS92
|
||||
bool hasRS92 = false;
|
||||
for (int i = 0; i < MAXSONDE; i++) {
|
||||
if (sonde.sondeList[i].type == STYPE_RS92) hasRS92 = true;
|
||||
|
|
@ -2969,6 +2983,7 @@ void loopWifiScan() {
|
|||
if (ephstate == EPH_PENDING) ephstate = EPH_ERROR;
|
||||
get_eph("/brdc");
|
||||
}
|
||||
#endif
|
||||
delay(3000);
|
||||
}
|
||||
enableNetwork(true);
|
||||
|
|
@ -3639,11 +3654,14 @@ void sondehub_send_data(WiFiClient * client, SondeInfo * s, struct st_sondehub *
|
|||
}
|
||||
|
||||
/* if there is a subtype (DFM only) */
|
||||
if ( TYPE_IS_DFM(s->type) && s->d.subtype > 0 && s->d.subtype < 16 ) {
|
||||
const char *t = dfmSubtypeStrSH[s->d.subtype];
|
||||
// as in https://github.com/projecthorus/radiosonde_auto_rx/blob/e680221f69a568e1fdb24e76db679233f32cb027/auto_rx/autorx/sonde_specific.py#L84
|
||||
if (t) sprintf(w, "\"subtype\": \"%s\",", t);
|
||||
else sprintf(w, "\"subtype\": \"DFMx%X\",", s->d.subtype); // Unknown subtype
|
||||
if ( TYPE_IS_DFM(s->type) && s->d.subtype > 0 ) {
|
||||
if( (s->d.subtype&0xF) != DFM_UNK) {
|
||||
const char *t = dfmSubtypeLong[s->d.subtype&0xF];
|
||||
sprintf(w, "\"subtype\": \"%s\",", t);
|
||||
}
|
||||
else {
|
||||
sprintf(w, "\"subtype\": \"DFMx%X\",", s->d.subtype>>4); // Unknown subtype
|
||||
}
|
||||
w += strlen(w);
|
||||
} else if ( s->type == STYPE_RS41 ) {
|
||||
char buf[11];
|
||||
|
|
|
|||
|
|
@ -16,6 +16,13 @@
|
|||
|
||||
#define MAXIDAGE 1800
|
||||
|
||||
|
||||
const char *dfmSubtypeLong[] = { "", "DFMxx", "DFM06", "DFM06P", "PS15",
|
||||
"DFM09", "DFM09P", "DFM17", "DFM17P"};
|
||||
const char *dfmSubtypeShort[] = { "", "DFMx", "DFM6", "DF6P", "PS15",
|
||||
"DFM9", "DF9P", "DF17", "D17P"};
|
||||
|
||||
|
||||
/*
|
||||
* observed DAT patterns for DFM-9:
|
||||
* A: 0+1; 2+3; 4+5; 6+7; 8+0 => keep frame in shadowFrame
|
||||
|
|
@ -44,7 +51,10 @@ static struct st_dfmstat {
|
|||
uint8_t nameregtop;
|
||||
uint8_t lastdat;
|
||||
uint8_t cycledone; // 0=no; 1=OK, 2=partially/with errors
|
||||
float meas[5+2];
|
||||
float meas[9];
|
||||
uint16_t measok; // Bit-mask showing which meas entries have been received
|
||||
uint8_t ptu_chan; // always the max channel. used as subtype before, but 0xC can be DFM09 (with P) or DFM17 (w/o P)
|
||||
uint8_t sensP; // P channel in data (0xC DMF09 (but not 0xC DFM17), 0xD DFM17P, 0x8 DFM6P (but not PS15) (0 or 1)
|
||||
} dfmstate;
|
||||
|
||||
decoderSetupCfg DFMSetupCfg {
|
||||
|
|
@ -280,8 +290,12 @@ void DFM::finddfname(uint8_t *b)
|
|||
snprintf(sd->id, 10, "D%x ", id);
|
||||
memcpy(sd->ser, sd->id+1, 9);
|
||||
sd->validID = true;
|
||||
sd->subtype = (st>>4)&0x0F;
|
||||
strncpy(sd->typestr, typestr[ (st>>4)&0x0F ], 5);
|
||||
//sd->subtype = (st>>4)&0x0F;
|
||||
//strncpy(sd->typestr, typestr[ (st>>4)&0x0F ], 5);
|
||||
// Subtype is set later, as we need more data to distingish 0xC DFM09P and DFM17
|
||||
sd->subtype = 0;
|
||||
dfmstate.ptu_chan = (st>>4)&0x0F;
|
||||
strcpy(sd->typestr, "DFM");
|
||||
return;
|
||||
}
|
||||
dfmstate.lastfrcnt = 0;
|
||||
|
|
@ -332,8 +346,12 @@ void DFM::finddfname(uint8_t *b)
|
|||
Serial.println(sd->id);
|
||||
memcpy(sd->ser, sd->id+1, 9);
|
||||
sd->validID = true;
|
||||
sd->subtype = (st>>4)&0x0F;
|
||||
strncpy(sd->typestr, typestr[ (st>>4)&0x0F ], 5);
|
||||
//sd->subtype = (st>>4)&0x0F;
|
||||
//strncpy(sd->typestr, typestr[ (st>>4)&0x0F ], 5);
|
||||
// Subtype is set later, as we need more data to distingish 0xC DFM09P and DFM17
|
||||
sd->subtype = 0;
|
||||
dfmstate.ptu_chan = (st>>4)&0x0F;
|
||||
strcpy(sd->typestr, "DFM");
|
||||
}
|
||||
if(dfmstate.nameregok==i) {
|
||||
Serial.print(" ID OK");
|
||||
|
|
@ -361,13 +379,13 @@ void DFM::finddfname(uint8_t *b)
|
|||
|
||||
static float get_Temp() {
|
||||
SondeData *si = &(sonde.si()->d);
|
||||
if(!si->validID) { // type not yet known, so don't try to decode
|
||||
if(!si->subtype) { // type not yet known, so don't try to decode
|
||||
return NAN;
|
||||
}
|
||||
float f = dfmstate.meas[0],
|
||||
f1 = dfmstate.meas[3],
|
||||
f2 = dfmstate.meas[4];
|
||||
if(si->subtype >= 0x0C) {
|
||||
if(dfmstate.sensP) {
|
||||
f = dfmstate.meas[1];
|
||||
f1 = dfmstate.meas[5];
|
||||
f2 = dfmstate.meas[6];
|
||||
|
|
@ -377,7 +395,8 @@ static float get_Temp() {
|
|||
float BB0 = 3260.0; // B/Kelvin, fit -55C..+40C
|
||||
float T0 = 25 + 273.15; // t0=25C
|
||||
float R0 = 5.0e3; // R0=R25=5k
|
||||
float Rf = 220e3; // Rf = 220k
|
||||
float Rf = 220e3; // Rf = 220k, for DFM17: 332k
|
||||
if( si->subtype==DFM_17 || si->subtype==DFM_17P ) Rf = 332e3;
|
||||
float g = f2/Rf;
|
||||
float R = (f-f1) / g; // meas[0,3,4] > 0 ?
|
||||
float T = 0; // T/Kelvin
|
||||
|
|
@ -398,16 +417,41 @@ void DFM::decodeCFG(uint8_t *cfg)
|
|||
finddfname(cfg);
|
||||
// get meas
|
||||
uint8_t conf_id = (*cfg)>>4;
|
||||
if(conf_id<=6) {
|
||||
if(conf_id<=8) {
|
||||
uint32_t val = (cfg[1]<<12) | (cfg[2]<<4) | cfg[3];
|
||||
uint8_t exp = cfg[0] & 0xF;
|
||||
dfmstate.meas[conf_id] = val / (float)(1<<exp);
|
||||
dfmstate.measok |= (1 << conf_id);
|
||||
Serial.printf("meas %d is %f (%d,%d)\n", conf_id, dfmstate.meas[conf_id], val, exp);
|
||||
}
|
||||
|
||||
// get type (if we have an ID, but no type yet, and (needed only for 0xC), meas[6])
|
||||
if( si->validID && si->subtype==0 && (dfmstate.measok & (1<<6)) ) {
|
||||
switch(dfmstate.ptu_chan) {
|
||||
case 0x6: si->subtype = DFM_06; break;
|
||||
case 0x7: case 0x8:
|
||||
si->subtype = DFM_06P; dfmstate.sensP = 1; break; // (TODO: OR PS15)
|
||||
case 0xA: si->subtype = DFM_09; break;
|
||||
case 0xB: si->subtype = DFM_17; break;
|
||||
case 0xC: // DFM-09P or DFM-17
|
||||
if(dfmstate.meas[6]<220e3) { si->subtype = DFM_09P; dfmstate.sensP = 1; }
|
||||
else si->subtype = DFM_17;
|
||||
break;
|
||||
case 0xD: si->subtype = DFM_17P; dfmstate.sensP = 1; break;
|
||||
default: si->subtype = DFM_UNK;
|
||||
}
|
||||
if( si->subtype == DFM_UNK ) {
|
||||
snprintf(si->typestr, 5, "DFx%x", dfmstate.ptu_chan);
|
||||
si->subtype |= (dfmstate.ptu_chan<<4);
|
||||
} else {
|
||||
strcpy(si->typestr, dfmSubtypeShort[si->subtype]);
|
||||
}
|
||||
}
|
||||
|
||||
// get batt
|
||||
if(si->validID && si->subtype>=0x0A) {
|
||||
if(si->validID && dfmstate.ptu_chan>=0x0A && si->subtype>0 ) {
|
||||
// otherwise don't try, as we might not have the right type yet...
|
||||
int cid = (si->subtype >= 0x0C) ? 0x7 : 0x5;
|
||||
int cid = (dfmstate.sensP) ? 0x7 : 0x5;
|
||||
if(conf_id == cid) {
|
||||
uint16_t val = cfg[1]<<8 | cfg[2];
|
||||
si->batteryVoltage = val / 1000.0;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@
|
|||
#define DFM_NORMAL 0
|
||||
#define DFM_INVERSE 1
|
||||
|
||||
enum DFMSubtype { DFM_UNDEF, DFM_UNK, DFM_06, DFM_06P, DFM_PS15, DFM_09, DFM_09P, DFM_17, DFM_17P };
|
||||
|
||||
extern const char *dfmSubtypeLong[];
|
||||
extern const char *dfmSubtypeShort[];
|
||||
|
||||
/* Main class */
|
||||
class DFM : public DecoderBase
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
#include "Sonde.h"
|
||||
#include "RS41.h"
|
||||
#if FEATURE_RS92
|
||||
#include "RS92.h"
|
||||
#endif
|
||||
#include "DFM.h"
|
||||
#include "M10M20.h"
|
||||
#include "MP3H.h"
|
||||
|
|
@ -431,7 +433,9 @@ void Sonde::setup() {
|
|||
dfm.setup( sondeList[rxtask.currentSonde].freq * 1000000, sondeList[rxtask.currentSonde].type );
|
||||
break;
|
||||
case STYPE_RS92:
|
||||
#ifdef FEATURE_RS92
|
||||
rs92.setup( sondeList[rxtask.currentSonde].freq * 1000000);
|
||||
#endif
|
||||
break;
|
||||
case STYPE_M10:
|
||||
case STYPE_M20:
|
||||
|
|
@ -462,7 +466,9 @@ void Sonde::receive() {
|
|||
res = rs41.receive();
|
||||
break;
|
||||
case STYPE_RS92:
|
||||
#ifdef FEATURE_RS92
|
||||
res = rs92.receive();
|
||||
#endif
|
||||
break;
|
||||
case STYPE_M10:
|
||||
case STYPE_M20:
|
||||
|
|
@ -562,7 +568,9 @@ rxloop:
|
|||
rs41.waitRXcomplete();
|
||||
break;
|
||||
case STYPE_RS92:
|
||||
#ifdef FEATURE_RS92
|
||||
rs92.waitRXcomplete();
|
||||
#endif
|
||||
break;
|
||||
case STYPE_M10:
|
||||
case STYPE_M20:
|
||||
|
|
|
|||
|
|
@ -1,19 +1,22 @@
|
|||
#include "json.h"
|
||||
#include "RS41.h"
|
||||
#include "DFM.h"
|
||||
|
||||
extern const char *sondeTypeStrSH[];
|
||||
extern const char *dfmSubtypeStrSH[];
|
||||
//extern const char *dfmSubtypeStrSH[];
|
||||
|
||||
static char typestr[11];
|
||||
|
||||
const char *getType(SondeInfo *si) {
|
||||
if( si->type == STYPE_RS41 ) {
|
||||
if ( RS41::getSubtype(typestr, 11, si) == 0 ) return typestr;
|
||||
} else if ( TYPE_IS_DFM(si->type) && si->d.subtype > 0 && si->d.subtype < 16 ) {
|
||||
const char *t = dfmSubtypeStrSH[si->d.subtype];
|
||||
if(t) return t;
|
||||
sprintf(typestr, "DFMx%X", si->d.subtype);
|
||||
return typestr;
|
||||
} else if ( TYPE_IS_DFM(si->type) && si->d.subtype > 0 ) {
|
||||
const char *t = dfmSubtypeLong[si->d.subtype & 0xf];
|
||||
if( (si->d.subtype & 0xf) == DFM_UNK) {
|
||||
sprintf(typestr, "DFMx%X", si->d.subtype>>4);
|
||||
return typestr;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
return sondeTypeStrSH[sonde.realType(si)];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
const char *version_name = "rdzTTGOsonde";
|
||||
const char *version_id = "devel20230104";
|
||||
const char *version_id = "devel20230413";
|
||||
const int SPIFFS_MAJOR=2;
|
||||
const int SPIFFS_MINOR=17;
|
||||
|
|
|
|||
Loading…
Reference in New Issue