M20: PTU v0.3, rel. humidity following DF9DQ

pull/43/head
Zilog80 2021-12-02 21:26:40 +01:00
rodzic b15ca44a4a
commit 633615a8e5
1 zmienionych plików z 94 dodań i 23 usunięć

Wyświetl plik

@ -102,7 +102,7 @@ typedef struct {
double lat; double lon; double alt;
double vH; double vD; double vV;
double vx; double vy; double vD2;
float T; float _RH; float TH;
float T; float RH; float TH; float P;
ui8_t numSV;
ui8_t utc_ofs;
char SN[12+4];
@ -246,6 +246,7 @@ frame[0x44..0x45]: frame check
#define col_TXT "\x1b[38;5;244m"
#define col_FRTXT "\x1b[38;5;244m"
#define col_CSok "\x1b[38;5;2m"
#define col_CSoo "\x1b[38;5;220m"
#define col_CSno "\x1b[38;5;1m"
#define col_CNST "\x1b[38;5;58m" // 3 byte
@ -592,7 +593,6 @@ static float get_Temp(gpx_t *gpx) {
ui16_t ADC_RT; // ADC12
//ui16_t Tcal[2];
float adc_max = 4095.0; // ADC12 , 4096 = 1<<12
float x, R;
float T = 0; // T/Kelvin
@ -600,6 +600,8 @@ static float get_Temp(gpx_t *gpx) {
//ui8_t sc = gpx->frame_bytes[0x32] & 3; // (frame[0x32]<<8)|frame[0x31]
// frame[0x31..0x32], frame[0x32]: 0x9=0b1001:0, 0xA=0b1010:1, 0x8=0b1000:2
// ? Temp-Calibration depending on range ?
//
// range: 0:0..4095 , 1:4096..8191 , 2:8192..12287
/*
if (sc == 0x1) { scT = 0; }
@ -612,7 +614,8 @@ static float get_Temp(gpx_t *gpx) {
else if (ADC_RT > 4095) { scT = 1; ADC_RT -= 4096; }
else { scT = 0; } // also if (ADC_RT>>12)&3 == 3
x = (adc_max-ADC_RT)/ADC_RT; // (Vcc-Vout)/Vout = Vcc/Vout - 1
// ADC12 , 4096 = 1<<12, max: 4095
x = (4095.0-ADC_RT)/ADC_RT; // (Vcc-Vout)/Vout = Vcc/Vout - 1
R = Rs[scT] /( x - Rs[scT]/Rp[scT] );
if (R > 0) T = 1/( p0 + p1*log(R) + p2*log(R)*log(R) + p3*log(R)*log(R)*log(R) );
@ -647,7 +650,7 @@ static float get_Tntc2(gpx_t *gpx) {
static float get_RHraw(gpx_t *gpx) {
float _rh = -1.0;
float _RH = -1.0;
float ADC_rh;
ui16_t ADC_rh;
ADC_rh = (gpx->frame_bytes[0x03] << 8) | gpx->frame_bytes[0x02];
_rh = ADC_rh / (float)(1<<15);
@ -655,11 +658,56 @@ static float get_RHraw(gpx_t *gpx) {
_RH = -1.0;
if (_rh < 1.05) _RH = _rh*100.0;
// Transfer function ?
// Calibration ?
// (Hyland and Wexler) Tntc2 (T_RH) <-> Tmain ?
return _RH;
}
static float get_RH(gpx_t *gpx) {
// from DF9DQ,
// https://github.com/einergehtnochrein/ra-firmware
//
float TU = get_Tntc2(gpx);
float RH = -1.0f;
float x;
ui16_t humval = (gpx->frame_bytes[0x03] << 8) | gpx->frame_bytes[0x02];
ui16_t rh_cal = (gpx->frame_bytes[0x30] << 8) | gpx->frame_bytes[0x2F];
float humidityCalibration = 6.4e8f / (rh_cal + 80000.0f);
x = (humval + 80000.0f) * humidityCalibration * (1.0f - 5.8e-4f * (TU-25.0f));
x = 4.16e9f / x;
x = 10.087f*x*x*x - 211.62f*x*x + 1388.2f*x - 2797.0f;
RH = -1.0f;
if (humval < 48000)
{
RH = x;
if (RH < 0.0f ) RH = 0.0f;
if (RH > 100.0f) RH = 100.0f;
}
// (Hyland and Wexler) Tntc2 (T_RH) <-> Tmain ?
return RH;
}
static float get_P(gpx_t *gpx) {
// cf. DF9DQ
//
float hPa = 0.0f;
ui16_t val = (gpx->frame_bytes[0x25] << 8) | gpx->frame_bytes[0x24];
if (val > 0) {
hPa = val/16.0f;
}
return hPa;
}
/* -------------------------------------------------------------------------- */
static int print_pos(gpx_t *gpx, int bcOK, int csOK) {
@ -682,9 +730,10 @@ static int print_pos(gpx_t *gpx, int bcOK, int csOK) {
get_SN(gpx);
if (gpx->option.ptu && csOK) {
gpx->T = get_Temp(gpx);
gpx->TH = get_Tntc2(gpx);
gpx->_RH = get_RHraw(gpx);
gpx->T = get_Temp(gpx); // temperature
gpx->TH = get_Tntc2(gpx); // rel. humidity sensor temperature
gpx->RH = get_RH(gpx); // relative humidity
gpx->P = get_P(gpx); // (optional) pressure
}
if ( !gpx->option.slt )
@ -709,16 +758,22 @@ static int print_pos(gpx_t *gpx, int bcOK, int csOK) {
}
if (gpx->option.vbs >= 2) {
fprintf(stdout, " # ");
if (bcOK) fprintf(stdout, " "col_CSok"(ok)"col_TXT);
else fprintf(stdout, " "col_CSno"(no)"col_TXT);
if (bcOK > 0) fprintf(stdout, " "col_CSok"(ok)"col_TXT);
else if (bcOK < 0) fprintf(stdout, " "col_CSoo"(oo)"col_TXT);
else fprintf(stdout, " "col_CSno"(no)"col_TXT);
//
if (csOK) fprintf(stdout, " "col_CSok"[OK]"col_TXT);
else fprintf(stdout, " "col_CSno"[NO]"col_TXT);
}
if (gpx->option.ptu && csOK) {
fprintf(stdout, " ");
if (gpx->T > -273.0) fprintf(stdout, " T:%.1fC", gpx->T);
if (gpx->_RH > -0.5) fprintf(stdout, " (_RH=%.0f%%)", gpx->_RH);
if (gpx->TH > -273.0) fprintf(stdout, " TH:%.1fC", gpx->TH);
if (gpx->T > -273.0f) fprintf(stdout, " T:%.1fC", gpx->T);
if (gpx->RH > -0.5f) fprintf(stdout, " RH=%.0f%%", gpx->RH);
if (gpx->TH > -273.0f) fprintf(stdout, " TH:%.1fC", gpx->TH);
if (gpx->P > 0.0f) {
if (gpx->P < 100.0f) fprintf(stdout, " P=%.2fhPa ", gpx->P);
else fprintf(stdout, " P=%.1fhPa ", gpx->P);
}
}
fprintf(stdout, ANSI_COLOR_RESET"");
}
@ -741,14 +796,22 @@ static int print_pos(gpx_t *gpx, int bcOK, int csOK) {
}
if (gpx->option.vbs >= 2) {
fprintf(stdout, " # ");
if (bcOK) fprintf(stdout, " (ok)"); else fprintf(stdout, " (no)");
//if (bcOK) fprintf(stdout, " (ok)"); else fprintf(stdout, " (no)");
if (bcOK > 0) fprintf(stdout, " (ok)");
else if (bcOK < 0) fprintf(stdout, " (oo)");
else fprintf(stdout, " (no)");
//
if (csOK) fprintf(stdout, " [OK]"); else fprintf(stdout, " [NO]");
}
if (gpx->option.ptu && csOK) {
fprintf(stdout, " ");
if (gpx->T > -273.0) fprintf(stdout, " T:%.1fC", gpx->T);
if (gpx->_RH > -0.5) fprintf(stdout, " (_RH=%.0f%%)", gpx->_RH);
if (gpx->TH > -273.0) fprintf(stdout, " TH:%.1fC", gpx->TH);
if (gpx->T > -273.0f) fprintf(stdout, " T:%.1fC", gpx->T);
if (gpx->RH > -0.5f) fprintf(stdout, " RH=%.0f%%", gpx->RH);
if (gpx->TH > -273.0f) fprintf(stdout, " TH:%.1fC", gpx->TH);
if (gpx->P > 0.0f) {
if (gpx->P < 100.0f) fprintf(stdout, " P=%.2fhPa ", gpx->P);
else fprintf(stdout, " P=%.1fhPa ", gpx->P);
}
}
}
fprintf(stdout, "\n");
@ -770,7 +833,9 @@ static int print_pos(gpx_t *gpx, int bcOK, int csOK) {
fprintf(stdout, "\"id\": \"%s\", \"datetime\": \"%04d-%02d-%02dT%02d:%02d:%06.3fZ\", \"lat\": %.5f, \"lon\": %.5f, \"alt\": %.5f, \"vel_h\": %.5f, \"heading\": %.5f, \"vel_v\": %.5f",
sn_id, gpx->jahr, gpx->monat, gpx->tag, gpx->std, gpx->min, gpx->sek, gpx->lat, gpx->lon, gpx->alt, gpx->vH, gpx->vD, gpx->vV);
if (gpx->option.ptu) { // temperature
if (gpx->T > -273.0) fprintf(stdout, ", \"temp\": %.1f", gpx->T);
if (gpx->T > -273.0f) fprintf(stdout, ", \"temp\": %.1f", gpx->T );
if (gpx->RH > -0.5f) fprintf(stdout, ", \"humidity\": %.1f", gpx->RH );
if (gpx->P > 0.0f) fprintf(stdout, ", \"pressure\": %.2f", gpx->P );
}
fprintf(stdout, ", \"rawid\": \"M20_%02X%02X%02X\"", gpx->frame_bytes[pos_SN], gpx->frame_bytes[pos_SN+1], gpx->frame_bytes[pos_SN+2]); // gpx->type
fprintf(stdout, ", \"subtype\": \"0x%02X\"", gpx->type);
@ -795,7 +860,7 @@ static int print_frame(gpx_t *gpx, int pos, int b2B) {
int i;
ui8_t byte;
int cs1, cs2;
int bc1, bc2;
int bc1, bc2, bc;
int flen = stdFLEN; // stdFLEN=0x64, auxFLEN=0x76; M20:0x45 ?
if (b2B) {
@ -813,6 +878,9 @@ static int print_frame(gpx_t *gpx, int pos, int b2B) {
bc1 = (gpx->frame_bytes[pos_BlkChk] << 8) | gpx->frame_bytes[pos_BlkChk+1];
bc2 = blk_checkM10(len_BlkChk, gpx->frame_bytes+2); // len(essentialBlock+chk16) = 0x16
if (bc1 == bc2) bc = 1;
else if (bc1 == 0) bc = -1;
else bc = 0;
switch (gpx->frame_bytes[1]) {
case 0x8F: gpx->type = t_M2K2; break;
@ -846,8 +914,9 @@ static int print_frame(gpx_t *gpx, int pos, int b2B) {
}
if (gpx->option.vbs) {
fprintf(stdout, " # "col_Check"%04x"col_FRTXT, cs2);
if (bc1 == bc2) fprintf(stdout, " "col_CSok"(ok)"col_TXT);
else fprintf(stdout, " "col_CSno"(no)"col_TXT);
if (bc > 0) fprintf(stdout, " "col_CSok"(ok)"col_TXT);
else if (bc < 0) fprintf(stdout, " "col_CSoo"(oo)"col_TXT);
else fprintf(stdout, " "col_CSno"(no)"col_TXT);
if (cs1 == cs2) fprintf(stdout, " "col_CSok"[OK]"col_TXT);
else fprintf(stdout, " "col_CSno"[NO]"col_TXT);
}
@ -860,13 +929,15 @@ static int print_frame(gpx_t *gpx, int pos, int b2B) {
}
if (gpx->option.vbs) {
fprintf(stdout, " # %04x", cs2);
if (bc1 == bc2) fprintf(stdout, " (ok)"); else fprintf(stdout, " (no)");
if (bc > 0) fprintf(stdout, " (ok)");
else if (bc < 0) fprintf(stdout, " (oo)");
else fprintf(stdout, " (no)");
if (cs1 == cs2) fprintf(stdout, " [OK]"); else fprintf(stdout, " [NO]");
}
fprintf(stdout, "\n");
}
if (gpx->option.slt /*&& gpx->option.jsn*/) {
print_pos(gpx, bc1 == bc2, cs1 == cs2);
print_pos(gpx, bc, cs1 == cs2);
}
}
/*
@ -880,7 +951,7 @@ static int print_frame(gpx_t *gpx, int pos, int b2B) {
}
}
*/
else print_pos(gpx, bc1 == bc2, cs1 == cs2);
else print_pos(gpx, bc, cs1 == cs2);
return (gpx->frame_bytes[0]<<8)|gpx->frame_bytes[1];
}