From b5c41d7a1d9d32063375bf33f313f0005077aa85 Mon Sep 17 00:00:00 2001 From: ProfBoc75 Date: Sat, 13 Apr 2024 15:09:01 +0200 Subject: [PATCH 1/5] Add Support BMW Gen3 TPMS --- README.md | 1 + include/rtl_433_devices.h | 1 + src/CMakeLists.txt | 1 + src/devices/tpms_bmw_g3.c | 132 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+) create mode 100644 src/devices/tpms_bmw_g3.c diff --git a/README.md b/README.md index ef20e51f0..709fa7c21 100644 --- a/README.md +++ b/README.md @@ -342,6 +342,7 @@ See [CONTRIBUTING.md](./docs/CONTRIBUTING.md). [254] Thermor DG950 weather station [255] Mueller Hot Rod water meter [256] ThermoPro TP28b Super Long Range Wireless Meat Thermometer for Smoker BBQ Grill + [257] BMW Gen3 TPMS * Disabled by default, use -R n or a conf file to enable diff --git a/include/rtl_433_devices.h b/include/rtl_433_devices.h index 27b267ed8..5a050f9b5 100644 --- a/include/rtl_433_devices.h +++ b/include/rtl_433_devices.h @@ -264,6 +264,7 @@ DECL(thermor) \ DECL(mueller_hotrod) \ DECL(thermopro_tp28b) \ + DECL(tpms_bmwg3) \ /* Add new decoders here. */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b82ce865f..d37a302dd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -236,6 +236,7 @@ add_library(r_433 STATIC devices/tpms_abarth124.c devices/tpms_ave.c devices/tpms_bmw.c + devices/tpms_bmw_g3.c devices/tpms_citroen.c devices/tpms_eezrv.c devices/tpms_elantra2012.c diff --git a/src/devices/tpms_bmw_g3.c b/src/devices/tpms_bmw_g3.c new file mode 100644 index 000000000..f175f2662 --- /dev/null +++ b/src/devices/tpms_bmw_g3.c @@ -0,0 +1,132 @@ +/** @file + BMW Gen3 TPMS sensor. + + Copyright (C) 2024 Bruno OCTAU (ProfBoc75) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ +/** +BMW Gen3 TPMS sensor. + +issue #xxxx BMW Gen3 TPMS support open by \@xxxxxx + +Last progress based on this: + + rtl_433 -Y autolevel -Y minmax -X "n=BMW_G3,m=FSK_PCM,s=52,l=52,r=1000,preamble=cccd,decode_dm,bits>=190" *.cs8 2>&1 | grep "\{89\}" + codes : {89}1c50f1758545f8020373428 + +RF signal: + + FSK, PCM, s=l=52 µs, Differential Manchester + +Data layout{89} 11 x 8: + + Byte Position 0 1 2 3 4 5 6 7 8 9 10 11 + Data Layout [II II II II PP TT F1 F2 F3]CC CC 8 + Sample 1c 50 f1 75 85 45 f8 02 03 73 42 8 + +- II:{32} ID, hexa 0x1c50f175 or decimal value 475066741 +- PP:{8}: Tire pressure, PSI = (PP - 43) * 0.363 or kPa = ( PP - 43 ) * 2.5 +- TT:{8}: Temp +- F1, F2, F3: Flags that could contain battery information, flat tire, lost of pressure ... +- CC: CRC-16 bits, poly 0x1021, init 0x0000 [from previous 9 bytes]. +- 8: useless trailing bit + +*/ + +#include "decoder.h" + +static int tpms_bmwg3_decode(r_device *decoder, bitbuffer_t *bitbuffer) +{ + bitbuffer_t decoded = { 0 }; + uint8_t *b; + // preamble = 0xcccd + uint8_t const preamble_pattern[] = {0xcc, 0xcd}; + + if (bitbuffer->num_rows != 1) { + decoder_logf(decoder, 2, __func__, "row error"); + return DECODE_ABORT_EARLY; + } + + int pos = 0; + pos = bitbuffer_search(bitbuffer, 0, 0, preamble_pattern, 16); + if (pos >= bitbuffer->bits_per_row[0]) { + decoder_logf(decoder, 1, __func__, "Preamble not found"); + return DECODE_ABORT_EARLY; + } + + decoder_log_bitrow(decoder, 1, __func__, bitbuffer->bb[0], bitbuffer->bits_per_row[0], "MSG"); + + bitbuffer_differential_manchester_decode(bitbuffer, 0, pos + sizeof(preamble_pattern) * 8, &decoded, 88); // 11 * 8 + + decoder_log_bitrow(decoder, 2, __func__, decoded.bb[0], decoded.bits_per_row[0], "DMC"); + + if (decoded.bits_per_row[0] < 88) { + decoder_logf(decoder, 2, __func__, "Too short"); + return DECODE_ABORT_LENGTH; + } + + b = decoded.bb[0]; + + if (crc16(b, 11, 0x1021, 0x0000)) { + decoder_logf(decoder, 1, __func__, "crc error, expected %02x%02x, calculated %04x", b[9], b[10], crc16(b, 11, 0x1021, 0x0000)); + return DECODE_FAIL_MIC; // crc mismatch + } + decoder_log(decoder, 1, __func__, "BMW G3 found"); + float pressure_kPa = (b[4] - 43) * 2.5f; + float temperature_C = (b[5] - 50); + int flags1 = b[6]; // fixed value to 0xf8 could be Brand ID ? + int flags2 = b[7]; // Battery , pressure warning ? + int flags3 = b[8]; // fixed value to 0x03 could be Brand ID ? + + uint32_t id = ((uint32_t)b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]); + + char msg_str[23]; + snprintf(msg_str, sizeof(msg_str), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10]); + + /* clang-format off */ + data_t *data = data_make( + "model", "", DATA_STRING, "BMW-GEN3", + "type", "", DATA_STRING, "TPMS", + //"id", "", DATA_FORMAT, "%08x", DATA_INT, id, + "id", "", DATA_INT, id, + "pressure_kPa", "Pressure", DATA_FORMAT, "%.1f kPa", DATA_DOUBLE, (double)pressure_kPa, + "temperature_C", "Temperature", DATA_FORMAT, "%.1f C", DATA_DOUBLE, temperature_C, + "flags1", "", DATA_FORMAT, "%08b", DATA_INT, flags1, + "flags2", "", DATA_FORMAT, "%08b", DATA_INT, flags2, + "flags3", "", DATA_FORMAT, "%08b", DATA_INT, flags3, + "msg", "msg", DATA_STRING, msg_str, // To remove after guess all tags + "mic", "Integrity", DATA_STRING, "CRC", + NULL); + /* clang-format on */ + + decoder_output_data(decoder, data); + return 1; +} + +static char const *const output_fields[] = { + "model", + "type", + "id", + "battery_ok", + "pressure_kPa", + "flags1", + "flags2", + "flags3", + "msg", + "mic", + NULL, +}; + +r_device const tpms_bmwg3 = { + .name = "BMW Gen3 TPMS", + .modulation = FSK_PULSE_PCM, + .short_width = 52, + .long_width = 52, + .reset_limit = 160, + .decode_fn = &tpms_bmwg3_decode, + .fields = output_fields, +}; From ffd6b9ac43d46d8708a0724e4abb3ce09ba5e1e5 Mon Sep 17 00:00:00 2001 From: ProfBoc75 Date: Sat, 13 Apr 2024 15:15:43 +0200 Subject: [PATCH 2/5] Minor Fix issue number --- src/devices/tpms_bmw_g3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devices/tpms_bmw_g3.c b/src/devices/tpms_bmw_g3.c index f175f2662..8ad5a0f38 100644 --- a/src/devices/tpms_bmw_g3.c +++ b/src/devices/tpms_bmw_g3.c @@ -1,7 +1,7 @@ /** @file BMW Gen3 TPMS sensor. - Copyright (C) 2024 Bruno OCTAU (ProfBoc75) + Copyright (C) 2024 Bruno OCTAU (ProfBoc75), \@Billymazze This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ /** BMW Gen3 TPMS sensor. -issue #xxxx BMW Gen3 TPMS support open by \@xxxxxx +issue #2893 BMW Gen3 TPMS support open by \@Billymazze Last progress based on this: From 2d11450717418de64d9c98a038c5bcbbf27b54f1 Mon Sep 17 00:00:00 2001 From: ProfBoc75 Date: Sat, 13 Apr 2024 15:21:40 +0200 Subject: [PATCH 3/5] Minor Fix Docs --- src/devices/tpms_bmw_g3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices/tpms_bmw_g3.c b/src/devices/tpms_bmw_g3.c index 8ad5a0f38..9c70ebca4 100644 --- a/src/devices/tpms_bmw_g3.c +++ b/src/devices/tpms_bmw_g3.c @@ -30,7 +30,7 @@ Data layout{89} 11 x 8: - II:{32} ID, hexa 0x1c50f175 or decimal value 475066741 - PP:{8}: Tire pressure, PSI = (PP - 43) * 0.363 or kPa = ( PP - 43 ) * 2.5 -- TT:{8}: Temp +- TT:{8}: Temperature in C offset 50 - F1, F2, F3: Flags that could contain battery information, flat tire, lost of pressure ... - CC: CRC-16 bits, poly 0x1021, init 0x0000 [from previous 9 bytes]. - 8: useless trailing bit From a1d8570a1d1f620e6ecbd9adcac8ce36524e0d30 Mon Sep 17 00:00:00 2001 From: ProfBoc75 Date: Sat, 13 Apr 2024 15:27:56 +0200 Subject: [PATCH 4/5] Minor Fix Docs --- src/devices/tpms_bmw_g3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices/tpms_bmw_g3.c b/src/devices/tpms_bmw_g3.c index 9c70ebca4..87e954881 100644 --- a/src/devices/tpms_bmw_g3.c +++ b/src/devices/tpms_bmw_g3.c @@ -30,7 +30,7 @@ Data layout{89} 11 x 8: - II:{32} ID, hexa 0x1c50f175 or decimal value 475066741 - PP:{8}: Tire pressure, PSI = (PP - 43) * 0.363 or kPa = ( PP - 43 ) * 2.5 -- TT:{8}: Temperature in C offset 50 +- TT:{8}: Temperature in C offset 50 - F1, F2, F3: Flags that could contain battery information, flat tire, lost of pressure ... - CC: CRC-16 bits, poly 0x1021, init 0x0000 [from previous 9 bytes]. - 8: useless trailing bit From a625cbe3b65ff3a7dc690697d03341147564c277 Mon Sep 17 00:00:00 2001 From: Bruno OCTAU <62882637+ProfBoc75@users.noreply.github.com> Date: Mon, 15 Apr 2024 19:34:29 +0200 Subject: [PATCH 5/5] Fix BMW Gen3 Temperature offset 40 --- src/devices/tpms_bmw_g3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devices/tpms_bmw_g3.c b/src/devices/tpms_bmw_g3.c index 87e954881..a217348f9 100644 --- a/src/devices/tpms_bmw_g3.c +++ b/src/devices/tpms_bmw_g3.c @@ -30,7 +30,7 @@ Data layout{89} 11 x 8: - II:{32} ID, hexa 0x1c50f175 or decimal value 475066741 - PP:{8}: Tire pressure, PSI = (PP - 43) * 0.363 or kPa = ( PP - 43 ) * 2.5 -- TT:{8}: Temperature in C offset 50 +- TT:{8}: Temperature in C offset 40 - F1, F2, F3: Flags that could contain battery information, flat tire, lost of pressure ... - CC: CRC-16 bits, poly 0x1021, init 0x0000 [from previous 9 bytes]. - 8: useless trailing bit @@ -77,7 +77,7 @@ static int tpms_bmwg3_decode(r_device *decoder, bitbuffer_t *bitbuffer) } decoder_log(decoder, 1, __func__, "BMW G3 found"); float pressure_kPa = (b[4] - 43) * 2.5f; - float temperature_C = (b[5] - 50); + float temperature_C = (b[5] - 40); int flags1 = b[6]; // fixed value to 0xf8 could be Brand ID ? int flags2 = b[7]; // Battery , pressure warning ? int flags3 = b[8]; // fixed value to 0x03 could be Brand ID ?