Skip to content
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

Open
tguozden opened this issue Dec 24, 2024 · 4 comments
Open

Missing one every 4 data pulses - WH65B #164

tguozden opened this issue Dec 24, 2024 · 4 comments
Labels
question Further information is requested

Comments

@tguozden
Copy link

tguozden commented Dec 24, 2024

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

when fails:

ambientweather_whx_decode: WH31E/WH31B/WH40 detected, buffer is 137 bits length
ambientweather_whx_decode: unknown message type 24 (expected 0x30/0x40/0x68)
fineoffset_WH51_callback: Msg family unknown: 24
fineoffset_wh1080_callback: Fine Offset WH1080 data  codes {80}ff24ab6e02382c000000
fineoffset_wh31l_decode: WH31L detected, buffer is 122 bits length
fineoffset_wn34_decode:  codes {72}24ab6e02382c000000
honeywell_cm921_decode:  ................






when receives:

ambientweather_whx_decode: WH31E/WH31B/WH40 detected, buffer is 132 bits length
ambientweather_whx_decode: unknown message type 24 (expected 0x30/0x40/0x68)
fineoffset_WH24_callback: Raw @ bit_offset [54] codes {136}24ab6e02382c00000001000000000a36e4
N: Received message : {"model":"Fineoffset-WH65B","id":171,"battery_ok":1,"temperature_C":16.8,"humidity":44,"wind_dir_deg":110,"wind_avg_m_s":0,"wind_max_m_s":0,"rain_mm":0.254,"uv":0,"uvi":0,"light_lux":1,"mic":"CRC","protocol":"Fine Offset Electronics, WH25, WH32, WH32B, WN32B, WH24, WH65B, HP1000, Misol WS2320 Temperature/Humidity/Pressure Sensor","rssi":-40,"duration":11000}

Configuration

[env:esp32_cc1101]
board = esp32dev
build_flags = 
  '-DLOG_LEVEL=LOG_LEVEL_TRACE'
  '-DONBOARD_LED=2'          ; My ESP32 board had this wiring
; *** rtl_433_ESP Options ***
;  '-DRF_MODULE_FREQUENCY=915.00'
  '-DOOK_MODULATION=false'       ; False is FSK, True is OOK
  '-DRTL_DEBUG=1'           ; rtl_433 verbose mode
;  '-DRTL_VERBOSE=58'          ; LaCrosse TX141-Bv2, TX141TH-Bv2, TX141-Bv3, TX141W, TX145wsdth sensor
;  '-DRAW_SIGNAL_DEBUG=true'   ; display raw received messages
;  '-DMEMORY_DEBUG=true'   ; display memory usage information
;  '-DDEMOD_DEBUG=true'  ; display signal debug info
;	'-DMY_DEVICES=true'		; subset of devices
;  '-DPUBLISH_UNPARSED=true'   ; publish unparsed signal details
  '-DMINRSSI=-82'
;  '-DRSSI_THRESHOLD=12'         ; Apply a delta of 12 to average RSSI level
;  '-DAVERAGE_RSSI=5000'     ; Display RSSI floor ( Average of 5000 samples )
;  '-DSIGNAL_RSSI=true'             ; Display during signal receive

; *** RF Module Options ***
  '-DRF_CC1101="CC1101"'  ; CC1101 Transceiver Module
;  '-DRF_MODULE_CS=5'      ; pin to be used as chip select
  '-DRF_MODULE_GDO0=22'   ; CC1101 pin GDO0 - Breadboard is 22 versus 13 on soldered
  '-DRF_MODULE_GDO2=21'    ; CC1101 pin GDO2
;'-DRF_MODULE_INIT_STATUS=false'    ; Display transceiver config during startup
; *** RadioLib Options ***
;  '-DRADIOLIB_DEBUG=true'
;  '-DRADIOLIB_VERBOSE=true'
  ; *** FSK Setting Testing ***
  ;'-DsetBitrate'
  ;'-DsetFreqDev'
  ;'-DsetRxBW'

Environment

  • OS:
  • Software:
  • Node:
  • npm:

Process Supervisor

hb-service

Additional Context

No response

@tguozden tguozden added the question Further information is requested label Dec 24, 2024
@NorthernMan54
Copy link
Owner

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.

@tguozden tguozden reopened this Dec 28, 2024
@tguozden
Copy link
Author

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,
};

@NorthernMan54
Copy link
Owner

Tks for sharing

Should your changes be pushed back to rtl_433 ?

@tguozden
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants