Increase sensitivity (#2309)

Increase sensitivity of Weather and SubghzD apps.
This commit is contained in:
Totoo
2024-10-17 10:22:01 +02:00
committed by GitHub
parent cc7123b28d
commit cb3774ad81
9 changed files with 486 additions and 38 deletions

View File

@@ -0,0 +1,197 @@
#ifndef __FPROTO_Bresser3ch_H__
#define __FPROTO_Bresser3ch_H__
#include "weatherbase.hpp"
#define BRESSER_V0_DATA 36
#define BRESSER_V0_DATA_AND_TAIL 52
#define BRESSER_V1_DATA 40
typedef enum {
Bresser3chDecoderStepReset = 0,
Bresser3chDecoderStepV0SaveDuration,
Bresser3chDecoderStepV0CheckDuration,
Bresser3chDecoderStepV0TailCheckDuration,
Bresser3chDecoderStepV1PreambleDn,
Bresser3chDecoderStepV1PreambleUp,
Bresser3chDecoderStepV1SaveDuration,
Bresser3chDecoderStepV1CheckDuration,
} Bresser3chDecoderStepV1;
class FProtoWeatheBresser3CH : public FProtoWeatherBase {
public:
FProtoWeatheBresser3CH() {
sensorType = FPW_Bresser3CH;
}
void feed(bool level, uint32_t duration) {
switch (parser_step) {
case Bresser3chDecoderStepReset:
if (level && DURATION_DIFF(duration, te_short * 3) < te_delta) {
te_last = duration;
parser_step = Bresser3chDecoderStepV1PreambleDn;
decode_data = 0;
decode_count_bit = 0;
} else if ((!level) && duration >= te_long) {
parser_step = Bresser3chDecoderStepV0SaveDuration;
decode_data = 0;
decode_count_bit = 0;
}
break;
case Bresser3chDecoderStepV0SaveDuration:
if (level) {
te_last = duration;
if (decode_count_bit < BRESSER_V0_DATA) {
parser_step = Bresser3chDecoderStepV0CheckDuration;
} else {
parser_step = Bresser3chDecoderStepV0TailCheckDuration;
}
} else {
parser_step = Bresser3chDecoderStepReset;
}
break;
case Bresser3chDecoderStepV0CheckDuration:
if (!level) {
if (DURATION_DIFF(te_last, te_short) < te_delta) {
if (DURATION_DIFF(duration, te_short * 2) < te_delta) {
subghz_protocol_blocks_add_bit(0);
parser_step = Bresser3chDecoderStepV0SaveDuration;
} else if (
DURATION_DIFF(duration, te_short * 4) < te_delta) {
subghz_protocol_blocks_add_bit(1);
parser_step = Bresser3chDecoderStepV0SaveDuration;
} else
parser_step = Bresser3chDecoderStepReset;
} else
parser_step = Bresser3chDecoderStepReset;
} else
parser_step = Bresser3chDecoderStepReset;
break;
case Bresser3chDecoderStepV0TailCheckDuration:
if (!level) {
if (duration >= te_long) {
if (decode_count_bit == BRESSER_V0_DATA_AND_TAIL &&
ws_protocol_bresser_3ch_check_v0()) {
decode_count_bit = BRESSER_V0_DATA;
sensorType = FPW_Bresser3CH;
// ws_protocol_bresser_3ch_extract_data_v0();
if (callback) {
callback(this);
}
}
decode_data = 0;
decode_count_bit = 0;
parser_step = Bresser3chDecoderStepReset;
} else if (
decode_count_bit < BRESSER_V0_DATA_AND_TAIL &&
DURATION_DIFF(te_last, te_short) < te_delta &&
DURATION_DIFF(duration, te_short * 2) < te_delta) {
decode_count_bit++;
parser_step = Bresser3chDecoderStepV0SaveDuration;
} else
parser_step = Bresser3chDecoderStepReset;
} else
parser_step = Bresser3chDecoderStepReset;
break;
case Bresser3chDecoderStepV1PreambleDn:
if ((!level) && DURATION_DIFF(duration, te_short_v1 * 3) < te_delta) {
if (DURATION_DIFF(te_last, te_short_v1 * 12) < te_delta * 2) {
// End of sync after 4*750 (12*250) high values, start reading the message
parser_step = Bresser3chDecoderStepV1SaveDuration;
} else {
parser_step = Bresser3chDecoderStepV1PreambleUp;
}
} else {
parser_step = Bresser3chDecoderStepReset;
}
break;
case Bresser3chDecoderStepV1PreambleUp:
if (level && DURATION_DIFF(duration, te_short_v1 * 3) < te_delta) {
te_last = te_last + duration;
parser_step = Bresser3chDecoderStepV1PreambleDn;
} else {
parser_step = Bresser3chDecoderStepReset;
}
break;
case Bresser3chDecoderStepV1SaveDuration:
if (decode_count_bit == BRESSER_V1_DATA) {
if (ws_protocol_bresser_3ch_check_v1()) {
// ws_protocol_bresser_3ch_extract_data_v1(&instance->generic);
sensorType = FPW_Bresser3CH_V1;
if (callback) {
callback(this);
}
}
decode_data = 0;
decode_count_bit = 0;
parser_step = Bresser3chDecoderStepReset;
} else if (level) {
te_last = duration;
parser_step = Bresser3chDecoderStepV1CheckDuration;
} else {
parser_step = Bresser3chDecoderStepReset;
}
break;
case Bresser3chDecoderStepV1CheckDuration:
if (!level) {
if (DURATION_DIFF(te_last, te_short_v1) < te_delta && DURATION_DIFF(duration, te_long_v1) < te_delta) {
subghz_protocol_blocks_add_bit(0);
parser_step = Bresser3chDecoderStepV1SaveDuration;
} else if (
DURATION_DIFF(te_last, te_long_v1) < te_delta && DURATION_DIFF(duration, te_short_v1) < te_delta) {
subghz_protocol_blocks_add_bit(1);
parser_step = Bresser3chDecoderStepV1SaveDuration;
} else
parser_step = Bresser3chDecoderStepReset;
} else
parser_step = Bresser3chDecoderStepReset;
break;
}
}
protected:
uint32_t te_short = 475;
uint32_t te_long = 3900;
uint32_t te_delta = 150;
uint32_t te_short_v1 = 250;
uint32_t te_long_v1 = 500;
bool ws_protocol_bresser_3ch_check_v0() {
if (!decode_data) return false;
// No CRC, so better sanity checks here
if (((decode_data >> 8) & 0x0f) != 0x0f) return false; // separator not 0xf
if (((decode_data >> 28) & 0xff) == 0xff) return false; // ID only ones?
if (((decode_data >> 28) & 0xff) == 0x00) return false; // ID only zeroes?
if (((decode_data >> 25) & 0x0f) == 0x0f) return false; // flags only ones?
if (((decode_data >> 25) & 0x0f) == 0x00) return false; // flags only zeroes?
if (((decode_data >> 12) & 0x0fff) == 0x0fff)
return false; // temperature maxed out?
if ((decode_data & 0xff) < 20)
return false; // humidity percentage less than 20?
if ((decode_data & 0xff) > 95)
return false; // humidity percentage more than 95?
return true;
}
bool ws_protocol_bresser_3ch_check_v1() {
if (!decode_data) return false;
uint8_t sum = (((decode_data >> 32) & 0xff) +
((decode_data >> 24) & 0xff) +
((decode_data >> 16) & 0xff) +
((decode_data >> 8) & 0xff)) &
0xff;
return (decode_data & 0xff) == sum;
}
};
#endif

View File

@@ -0,0 +1,88 @@
#ifndef __FPROTO_VAUNO_EN8822_H__
#define __FPROTO_VAUNO_EN8822_H__
#include "weatherbase.hpp"
typedef enum {
VaunoEN8822CDecoderStepReset = 0,
VaunoEN8822CDecoderStepSaveDuration,
VaunoEN8822CDecoderStepCheckDuration,
} VaunoEN8822CDecoderStep;
class FProtoWeatherVaunoEN8822 : public FProtoWeatherBase {
public:
FProtoWeatherVaunoEN8822() {
sensorType = FPW_Vauno_EN8822;
}
void feed(bool level, uint32_t duration) override {
switch (parser_step) {
case VaunoEN8822CDecoderStepReset:
if ((!level) && DURATION_DIFF(duration, te_long * 4) < te_delta) {
parser_step = VaunoEN8822CDecoderStepSaveDuration;
decode_data = 0;
decode_count_bit = 0;
}
break;
case VaunoEN8822CDecoderStepSaveDuration:
if (level) {
te_last = duration;
parser_step = VaunoEN8822CDecoderStepCheckDuration;
} else {
parser_step = VaunoEN8822CDecoderStepReset;
}
break;
case VaunoEN8822CDecoderStepCheckDuration:
if (!level) {
if (DURATION_DIFF(te_last, te_short) < te_delta) {
if (DURATION_DIFF(duration, te_long * 2) < te_delta) {
subghz_protocol_blocks_add_bit(1);
parser_step = VaunoEN8822CDecoderStepSaveDuration;
} else if (DURATION_DIFF(duration, te_long) < te_delta) {
subghz_protocol_blocks_add_bit(0);
parser_step = VaunoEN8822CDecoderStepSaveDuration;
} else if (DURATION_DIFF(duration, te_long * 4) < te_delta) {
parser_step = VaunoEN8822CDecoderStepReset;
if (decode_count_bit == min_count_bit_for_found && ws_protocol_vauno_en8822c_check()) {
// ws_protocol_vauno_en8822c_extract_data(&instance->generic);
if (callback) {
callback(this);
}
} else if (decode_count_bit == 1) {
parser_step = VaunoEN8822CDecoderStepSaveDuration;
}
decode_data = 0;
decode_count_bit = 0;
} else
parser_step = VaunoEN8822CDecoderStepReset;
} else
parser_step = VaunoEN8822CDecoderStepReset;
} else
parser_step = VaunoEN8822CDecoderStepReset;
break;
}
}
protected:
// timing values
uint32_t te_short = 500;
uint32_t te_long = 1940;
uint32_t te_delta = 150;
uint32_t min_count_bit_for_found = 42;
bool ws_protocol_vauno_en8822c_check() {
if (!decode_data) return false;
// The sum of all nibbles should match the last 6 bits
uint8_t sum = 0;
for (uint8_t i = 6; i <= 38; i += 4) {
sum += ((decode_data >> i) & 0x0f);
}
return sum != 0 && (sum & 0x3f) == (decode_data & 0x3f);
}
};
#endif

View File

@@ -29,6 +29,8 @@ So include here the .hpp, and add a new element to the protos vector in the cons
#include "w-acurite5in1.hpp"
#include "w-emose601x.hpp"
#include "w-solight_te44.hpp"
#include "w-bresser_3ch.hpp"
#include "w-vauno_en8822.hpp"
#include <vector>
#include <memory>
@@ -66,10 +68,13 @@ class WeatherProtos : public FProtoListGeneral {
protos[FPW_Acurite5in1] = new FProtoWeatherAcurite5in1();
protos[FPW_EmosE601x] = new FProtoWeatherEmosE601x();
protos[FPW_SolightTE44] = new FProtoWeatherSolightTE44();
protos[FPW_Bresser3CH] = new FProtoWeatheBresser3CH();
protos[FPW_Bresser3CH_V1] = nullptr; // done by FProtoWeatheBresser3CH
protos[FPW_Vauno_EN8822] = new FProtoWeatherVaunoEN8822();
// set callback for them
for (uint8_t i = 0; i < FPW_COUNT; ++i) {
protos[i]->setCallback(callbackTarget);
if (protos[i] != NULL) protos[i]->setCallback(callbackTarget);
}
}

View File

@@ -39,6 +39,9 @@ enum FPROTO_WEATHER_SENSOR {
FPW_Acurite5in1 = 21,
FPW_EmosE601x = 22,
FPW_SolightTE44 = 23,
FPW_Bresser3CH = 24,
FPW_Bresser3CH_V1 = 25,
FPW_Vauno_EN8822 = 26,
FPW_COUNT // this must be the last
};