-
-
Notifications
You must be signed in to change notification settings - Fork 135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Missing one every 4 data pulses - WH65B #164
Comments
Is it possibly data from a different device or just RF noise? The code does try every possible decoder with each signal, so it will show failures for data not meant for that decoder. |
Finally reached zero missed packets. Did it by isolating my device, which is WH65B, and iss decoded by fineoffset_WH24_callback, a function inside fineoffset.c. To make things even worst, the code for WH24 is referred as WH25. Sorry for all my previous pointless comments, I deleted them. Here I copy my simplified version of fineoffset.c: #include "decoder.h"
/**
Fine Offset Electronics WH24, WH65B, HP1000 and derivatives Temperature/Humidity/Pressure sensor protocol.
Also: Misol WS2320 (rebranded WH65B, 433MHz)
The sensor sends a package each ~16 s with a width of ~11 ms. The bits are PCM modulated with Frequency Shift Keying.
Example:
[00] {196} d5 55 55 55 55 16 ea 12 5f 85 71 03 27 04 01 00 25 00 00 80 00 00 47 83 9
aligned {199} 1aa aa aa aa aa 2d d4 24 bf 0a e2 06 4e 08 02 00 4a 00 01 00 00 00 8f 07 2
Payload: FF II DD VT TT HH WW GG RR RR UU UU LL LL LL CC BB
Reading: id: 191, temp: 11.8 C, humidity: 78 %, wind_dir 266 deg, wind_speed: 1.12 m/s, gust_speed 2.24 m/s, rainfall: 22.2 mm
The WH65B sends the same data with a slightly longer preamble and postamble
{209} 55 55 55 55 55 51 6e a1 22 83 3f 14 3a 08 00 00 00 08 00 10 00 00 04 60 a1 00 8
aligned {208} a aa aa aa aa aa 2d d4 24 50 67 e2 87 41 00 00 00 01 00 02 00 00 00 8c 14 20 1
Payload: FF II DD VT TT HH WW GG RR RR UU UU LL LL LL CC BB
- Preamble: aa aa aa aa aa
- Sync word: 2d d4
- Payload: FF II DD VT TT HH WW GG RR RR UU UU LL LL LL CC BB
- F: 8 bit Family Code, fixed 0x24
- I: 8 bit Sensor ID, set on battery change
- D: 8 bit Wind direction
- V: 4 bit Various bits, D11S, wind dir 8th bit, wind speed 8th bit
- B: 1 bit low battery indicator
- T: 11 bit Temperature (+40*10), top bit is low battery flag
- H: 8 bit Humidity
- W: 8 bit Wind speed
- G: 8 bit Gust speed
- R: 16 bit rainfall counter
- U: 16 bit UV value
- L: 24 bit light value
- C: 8 bit CRC checksum of the 15 data bytes
- B: 8 bit Bitsum (sum without carry, XOR) of the 16 data bytes
*/
#define MODEL_WH24 24 /* internal identifier for model WH24, family code is always 0x24 */
#define MODEL_WH65B 65 /* internal identifier for model WH65B, family code is always 0x24 */
static int fineoffset_WH24_callback(r_device *decoder, bitbuffer_t *bitbuffer)
{
data_t *data;
uint8_t const preamble[] = {0xAA, 0x2D, 0xD4}; // part of preamble and sync word
uint8_t b[17]; // aligned packet data
unsigned bit_offset;
int type;
// Validate package, WH24 nominal size is 196 bit periods, WH65b is 209 bit periods
// if (bitbuffer->bits_per_row[0] < 190 || bitbuffer->bits_per_row[0] > 215) {
// return DECODE_ABORT_LENGTH;
// }
// Find a data package and extract data buffer
bit_offset = bitbuffer_search(bitbuffer, 0, 0, preamble, sizeof(preamble) * 8) + sizeof(preamble) * 8;
if (bit_offset + sizeof(b) * 8 > bitbuffer->bits_per_row[0]) { // Did not find a big enough package
decoder_logf_bitbuffer(decoder, 1, __func__, bitbuffer, "Fineoffset_WH24: short package. Header index: %u", bit_offset);
return DECODE_ABORT_LENGTH;
}
// Classification heuristics
if (bitbuffer->bits_per_row[0] - bit_offset - sizeof(b) * 8 < 8)
if (bit_offset < 61)
type = MODEL_WH24; // nominal 3 bits postamble
else
type = MODEL_WH65B;
else
type = MODEL_WH65B; // nominal 12 bits postamble
bitbuffer_extract_bytes(bitbuffer, 0, bit_offset, b, sizeof(b) * 8);
decoder_logf_bitrow(decoder, 1, __func__, b, sizeof(b) * 8, "Raw @ bit_offset [%u]", bit_offset);
if (b[0] != 0x24){ // Check for family code 0x24
decoder_logf(decoder, 1, __func__, "Fineoffset_WH24: fail sanity");
return DECODE_FAIL_SANITY;
}
// Verify checksum, same as other FO Stations: Reverse 1Wire CRC (poly 0x131)
uint8_t crc = crc8(b, 15, 0x31, 0x00);
uint8_t checksum = 0;
for (unsigned n = 0; n < 16; ++n) {
checksum += b[n];
}
if (crc != b[15] || checksum != b[16]) {
decoder_logf(decoder, 1, __func__, "Fineoffset_WH24: Checksum error: %02x %02x", crc, checksum);
return DECODE_FAIL_MIC;
}
// Decode data
int id = b[1]; // changes on battery change
int wind_dir = b[2] | (b[3] & 0x80) << 1; // range 0-359 deg, 0x1ff if invalid
int low_battery = (b[3] & 0x08) >> 3;
int temp_raw = (b[3] & 0x07) << 8 | b[4]; // 0x7ff if invalid
float temperature = (temp_raw - 400) * 0.1f; // range -40.0-60.0 C
int humidity = b[5]; // 0xff if invalid
int wind_speed_raw = b[6] | (b[3] & 0x10) << 4; // 0x1ff if invalid
float wind_speed_factor, rain_cup_count;
// Wind speed factor is 1.12 m/s (1.19 per specs?) for WH24, 0.51 m/s for WH65B
// Rain cup each count is 0.3mm for WH24, 0.01inch (0.254mm) for WH65B
if (type == MODEL_WH24) { // WH24
wind_speed_factor = 1.12f;
rain_cup_count = 0.3f;
} else { // WH65B
wind_speed_factor = 0.51f;
rain_cup_count = 0.254f;
}
// Wind speed is scaled by 8, wind speed = raw / 8 * 1.12 m/s (0.51 for WH65B)
float wind_speed_ms = wind_speed_raw * 0.125f * wind_speed_factor;
int gust_speed_raw = b[7]; // 0xff if invalid
// Wind gust is unscaled, multiply by wind speed factor 1.12 m/s
float gust_speed_ms = gust_speed_raw * wind_speed_factor;
int rainfall_raw = b[8] << 8 | b[9]; // rain tip counter
float rainfall_mm = rainfall_raw * rain_cup_count; // each tip is 0.3mm / 0.254mm
int uv_raw = b[10] << 8 | b[11]; // range 0-20000, 0xffff if invalid
int light_raw = b[12] << 16 | b[13] << 8 | b[14]; // 0xffffff if invalid
double light_lux = light_raw * 0.1; // range 0.0-300000.0lux
// Light = value/10 ; Watts/m Sqr. = Light/683 ; Lux to W/m2 = Lux/126
// UV value UVI
// 0-432 0
// 433-851 1
// 852-1210 2
// 1211-1570 3
// 1571-2017 4
// 2018-2450 5
// 2451-2761 6
// 2762-3100 7
// 3101-3512 8
// 3513-3918 9
// 3919-4277 10
// 4278-4650 11
// 4651-5029 12
// >=5230 13
int uvi_upper[] = {432, 851, 1210, 1570, 2017, 2450, 2761, 3100, 3512, 3918, 4277, 4650, 5029};
int uv_index = 0;
while (uv_index < 13 && uvi_upper[uv_index] < uv_raw) ++uv_index;
/* clang-format off */
data = data_make(
"model", "", DATA_STRING, type == MODEL_WH24 ? "Fineoffset-WH24" : "Fineoffset-WH65B",
"id", "ID", DATA_INT, id,
"battery_ok", "Battery", DATA_INT, !low_battery,
"temperature_C", "Temperature", DATA_COND, temp_raw != 0x7ff, DATA_FORMAT, "%.1f C", DATA_DOUBLE, temperature,
"humidity", "Humidity", DATA_COND, humidity != 0xff, DATA_FORMAT, "%u %%", DATA_INT, humidity,
"wind_dir_deg", "Wind direction", DATA_COND, wind_dir != 0x1ff, DATA_INT, wind_dir,
"wind_avg_m_s", "Wind speed", DATA_COND, wind_speed_raw != 0x1ff, DATA_FORMAT, "%.1f m/s", DATA_DOUBLE, wind_speed_ms,
"wind_max_m_s", "Gust speed", DATA_COND, gust_speed_raw != 0xff, DATA_FORMAT, "%.1f m/s", DATA_DOUBLE, gust_speed_ms,
"rain_mm", "Rainfall", DATA_FORMAT, "%.1f mm", DATA_DOUBLE, rainfall_mm,
"uv", "UV", DATA_COND, uv_raw != 0xffff, DATA_INT, uv_raw,
"uvi", "UVI", DATA_COND, uv_raw != 0xffff, DATA_INT, uv_index,
"light_lux", "Light", DATA_COND, light_raw != 0xffffff, DATA_FORMAT, "%.1f lux", DATA_DOUBLE, light_lux,
"mic", "Integrity", DATA_STRING, "CRC",
NULL);
/* clang-format on */
decoder_output_data(decoder, data);
return 1;
}
static char const *const output_fields_WH25[] = {
"model",
"id",
"battery_ok",
"temperature_C",
"humidity",
"pressure_hPa",
// WH24
"wind_dir_deg",
"wind_avg_m_s",
"wind_max_m_s",
"rain_mm",
"uv",
"uvi",
"light_lux",
//WH0290
"pm2_5_ug_m3",
"estimated_pm10_0_ug_m3",
"mic",
NULL,
};
r_device const fineoffset_WH25 = {
.name = "Fine Offset Electronics, WH25, WH32, WH32B, WN32B, WH24, WH65B, HP1000, Misol WS2320 Temperature/Humidity/Pressure Sensor",
.modulation = FSK_PULSE_PCM,
.short_width = 58, // Bit width = 58µs (measured across 580 samples / 40 bits / 250 kHz)
.long_width = 58, // NRZ encoding (bit width = pulse width)
.reset_limit = 20000, // Package starts with a huge gap of ~18900 us
.decode_fn = &fineoffset_WH24_callback,
.fields = output_fields_WH25,
};
|
Tks for sharing Should your changes be pushed back to rtl_433 ? |
Not sure. rtl_433 version 23.11 (2023-11-28) works well with a software defined radio, but in that version file fineoffset.c differed. should check latest rtl_433 with the SDR |
Current Situation
Receiving a finoffset WH65B type weather station with CC1101 (433MHz) and an ESP32 device. Approximately one every 3 -4 packets get lost, don't know why
Any help will be welcomed!
Logs
Configuration
Environment
Process Supervisor
hb-service
Additional Context
No response
The text was updated successfully, but these errors were encountered: