Portisch / RF-Bridge-EFM8BB1

Alternative Firmware for the Sonoff RF Bridge EFM8BB1 chip
293 stars 124 forks source link

Help with Lacrosse temperature & humidity sensors #111

Closed thermseekr closed 4 years ago

thermseekr commented 5 years ago

Latest firmware used?

Yes running latest available today April 02 2019.

Information

Lacrosse temperature and humidity sensor model TX141TH-BCH

Hello,

I'm trying to figure what this sensor puts out and I found this:

https://forum.arduino.cc/index.php?topic=390843.0

My sensor is -BCH version, the difference from -B is that BCH has a switch selector for channels 1-2-3 so the weather station can identify the sensor. The weather station can receive data from 3 different sensors plus its own "local" embedded sensor.

In the link you'll read that apparently the -B version sends 44 bits 6 times every minute. The timings for headers, zeroes and ones are there too.

I tried sniffing with 0xB1 but I'm not sure if I'm getting valid data because it doesn't show the same data structure all the time. Besides transmitting every minute (50 seconds actually) the sensor also has a button to trigger a transmission. Either way the transmission is very brief so I can't follow the recommendation of keeping the button pressed for 2-5 seconds as it just bursts data out for a brief moment and stops transmitting even if I keep the button pressed.

Here's what I managed to collect in both keypresses and regular transmissions. I could't decode using BitBucketConverter.py as I seem to be missing pycurl and wasn't able to get it installed on my MacBook during the short time I have available.

Can someone help me figuring this out? Does the provided link help in any way?

Thanks in advance, all the best for everyone. Tales

Single normal TX
20:52:18 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 0082 0230 015E 0226 3818181A28 55"}}
20:52:18 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 00AA 01EA 0122 0208 3818181928 55"}}
20:52:18 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 00B4 0208 0172 0208 3818181A28 55"}}

Single button press
20:58:46 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00C8 01F4 01EA 281908 55"}}
20:58:46 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 00A0 0226 015E 0212 381A28 55"}}
20:58:46 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 00BE 0208 0136 01EA 381928 55"}}
20:58:46 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00D2 01E0 01E0 281908 55"}}

Single normal TX
21:00:37 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00FA 01C2 01C2 281908 55"}}
21:00:37 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 00A0 0212 0168 021C 3818181A2818 55"}}
21:00:37 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00BE 01EA 01E0 281908 55"}}

Single normal TX
21:02:17 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 017C 00AA 01EA 28090909 55"}}
21:02:17 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 017C 00AA 021C 280909080909 55"}}
21:02:17 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 0186 00AA 0118 01FE 380909082909 55"}}

Several button presses - here I got one line per TX
22:21:04 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00FA 01B8 01D6 281818 55"}}
22:21:14 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00F0 01CC 01CC 281818 55"}}
22:21:25 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00DC 01CC 01E0 281818 55"}}
22:21:27 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00C8 01EA 01D6 281818 55"}}
22:21:31 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00D2 01CC 01E0 281818 55"}}
22:21:37 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00C8 01D6 01E0 281818 55"}}
22:21:43 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00E6 01CC 01CC 281818 55"}}
22:21:49 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00F0 01CC 01CC 281818 55"}}
22:21:54 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00DC 01CC 01E0 281818 55"}}
22:21:59 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00E6 01CC 01CC 281818 55"}}
22:22:04 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00D2 01D6 01CC 281818 55"}}
22:22:09 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00D2 01CC 01D6 281818 55"}}

Several button presses, usually 3 lines per TX
22:25:16 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00E6 01CC 01E0 281818 55"}}
22:25:16 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 05 0078 0230 03C0 0168 023A 4818192929292B38 55"}}
22:25:16 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00BE 01F4 01EA 281818 55"}}
22:25:16 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 00BE 01F4 0320 01E0 38181A292A292908 55"}}
22:25:20 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 0226 0848 0096 0EEC 381A1818 55"}}
22:25:20 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 00DC 01D6 033E 01CC 38181A2A2A2A2908 55"}}
22:25:21 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 0082 023A 0230 281818 55"}}
22:25:21 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 00D2 01EA 0320 01F4 38181A2A2A2A2908 55"}}
22:25:21 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00DC 01E0 01D6 281818 55"}}
22:25:25 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00E6 01D6 01CC 281818 55"}}
22:25:25 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 05 00AA 0208 035C 0118 01FE 4818192929292938 55"}}
22:25:25 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 00BE 01FE 0352 01F4 3818192929292908 55"}}
22:25:25 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00BE 01F4 01F4 281818 55"}}
22:25:25 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 00DC 01E0 0334 01E0 38181A2A2A2A2908 55"}}
22:25:28 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 00D2 01F4 033E 01EA 38181A2A2A2A2908 55"}}
22:25:29 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 0096 0212 0208 281818 55"}}
22:25:29 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 05 00B4 0208 0384 0172 01FE 4818192929292B38 55"}}
22:25:29 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00BE 01FE 01FE 281818 55"}}
22:25:29 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 00D2 01EA 0320 01E0 38181A2A2A2A2908 55"}}
22:25:29 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00BE 01EA 01EA 281818 55"}}
22:25:29 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 00DC 01E0 0320 01D6 38181A2A2A2A2908 55"}}
22:25:32 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00D2 01E0 01CC 281818 55"}}
22:25:32 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 00C8 01E0 0316 01E0 38181A2A2A2A2908 55"}}
22:25:35 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 00DC 01D6 01CC 281818 55"}}
22:25:37 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 01A4 0104 01CC 2819090819 55"}}
22:25:37 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 04 0186 0118 00C8 0208 381A0A080A 55"}}
22:25:37 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 03 019A 0104 01CC 2819090819 55"}}
22:25:55 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AA B1 05 0226 0F00 00C8 0758 0EF6 48181A0818383838 55"}}
Portisch commented 5 years ago
H (header bits), consisting of pulses of 950us followed by delays of 1650us;
0 (zeros), pulses of 300 us followed by delays of 700us;
1 (ones), pulses of 500 us followed by delays of 700us.

This looks like a tolerance issue. I never had so "short" header buckets. I will try to simulate the signal for testing next week.

thermseekr commented 5 years ago

Hello @Portisch have you managed to spend some time looking into this? Thanks!

thermseekr commented 5 years ago

Found a way to get data from my sensors. Used a $10 SDL-RTL dongle (software defined radio) plugged into a RPi3 running rtl_433. I was lucky that rtl_433 already knew the protocol from my Lacrosse sensors. Piped the output to moskitto_pub and voila got my data in json format in a MQTT topic.

Next step will be to use SDR-RTL with Universal Radio Hacker software to get the exact timings and try to teach Portisch how to decode it.

thermseekr commented 5 years ago

Hello!

Reopening the issue as I found relevant information.

As I had mentioned above rtl_433 knows the protocol for the Lacrosse TX141TH-BV2 temperature & humidity sensores. My sensors are -BCH instead of -BV2 but with the help of Universal Radio Hacker I could confirm that they share the exact same protocol.

Complete information is here: https://github.com/merbanan/rtl_433/blob/master/src/devices/lacrosse_TX141TH_Bv2.c

From the link:

 * The TX141TH-Bv2 protocol is OOK modulated PWM with fixed period of 625 us
 * for data bits, preambled by four long startbit pulses of fixed period equal
 * to ~1666 us. Hence, it is similar to Bresser Thermo-/Hygro-Sensor 3CH.
 *
 * A single data packet looks as follows:
 * 1) preamble - 833 us high followed by 833 us low, repeated 4 times:
 *  ----      ----      ----      ----
 * |    |    |    |    |    |    |    |
 *       ----      ----      ----      ----
 * 2) a train of 40 data pulses with fixed 625 us period follows immediately:
 *  ---    --     --     ---    ---    --     ---
 * |   |  |  |   |  |   |   |  |   |  |  |   |   |
 *      --    ---    ---     --     --    ---     -- ....
 * A logical 1 is 417 us of high followed by 208 us of low.
 * A logical 0 is 208 us of high followed by 417 us of low.
 * Thus, in the example pictured above the bits are 1 0 0 1 1 0 1 ....
 *
 * The TX141TH-Bv2 sensor sends 12 of identical packets, one immediately following
 * the other, in a single burst. These 12-packet bursts repeat every 50 seconds. At
 * the end of the last packet there are two 833 us pulses ("post-amble"?).
 *
 * The data is grouped in 5 bytes / 10 nybbles
 * [id] [id] [flags] [temp] [temp] [temp] [humi] [humi] [chk] [chk]

With that information in hand, do you think you could generate an hex file for my sensors? Updating the protocol definitions and compiling the code myself has proven to be beyond my current skill level.

Thanks a lot. Tales Maschio - thermseeker

thermseekr commented 5 years ago

Hello @Portisch

I made progress: managed to compile the project from the master branch and I'm receiving valid data. What I need to sort out:

--> I'm receiving only two out of three sensors --> I'm not receiving all transmission events from these two sensors --> Very ocasionally a few bits may not be received correctly (I noticed a 1 instead of 0 twice after many hours, both in the same location inside the data stream)

I wonder if the problems are related to the way I defined the protocol, or if I must configure some sort of timing tolerance for the buckets somewhere.

I'm not sure I fully understood the process of defining new protocols, but here's what I did:

From the protocol description I conclude it uses 3 buckets: 208, 417 and 833us:

Preamble is 833 high and 833 low - repeated 4 times
Bit 0 is 208 high and 417 low
Bit 1 is 417 high and 208 low
Data is 40 bits
All of the above gets transmitted 12 times.
Transmission ends with 2 repetitions of 833 high and 833 low.

I configured PROTOCOL_START as a high and a low of the same bucket. I don't know if I can do that. Also, I don't know how to inform that the start is repeated 4 times.

/*
 * Lacrosse TX141-Bv2, TX141TH-Bv2, TX141-Bv3, TX141TH-BCH sensors
 */
#if EFM8BB1_SUPPORT_LACROSSE_1_PROTOCOL == 1
#define LACROSSE_1
SI_SEGMENT_VARIABLE(PROTOCOL_BUCKETS(LACROSSE_1)[], static uint16_t, SI_SEG_CODE) = { 208, 417, 833 };
SI_SEGMENT_VARIABLE(PROTOCOL_START(LACROSSE_1)[], static uint8_t, SI_SEG_CODE) = { HIGH(2), LOW(2) };
SI_SEGMENT_VARIABLE(PROTOCOL_BIT0(LACROSSE_1)[], static uint8_t, SI_SEG_CODE) = { HIGH(0), LOW(1) };
SI_SEGMENT_VARIABLE(PROTOCOL_BIT1(LACROSSE_1)[], static uint8_t, SI_SEG_CODE) = { HIGH(1), LOW(0) };
#endif

I left PROTOCOL_END out, should I configure the same 833 high 833 low as in PROTOCOL_START?

#if EFM8BB1_SUPPORT_LACROSSE_1_PROTOCOL == 1
        /*
         * Lacrosse TX141-Bv2, TX141TH-Bv2, TX141-Bv3, TX141TH-BCH sensors
         */
        {
            { &PROTOCOL_BUCKETS(LACROSSE_1), ARRAY_LENGTH(PROTOCOL_BUCKETS(LACROSSE_1)) },
            { &PROTOCOL_START(LACROSSE_1), ARRAY_LENGTH(PROTOCOL_START(LACROSSE_1)) },
            { &PROTOCOL_BIT0(LACROSSE_1), ARRAY_LENGTH(PROTOCOL_BIT0(LACROSSE_1)) },
            { &PROTOCOL_BIT1(LACROSSE_1), ARRAY_LENGTH(PROTOCOL_BIT1(LACROSSE_1)) },
            { NULL, 0 },
            40
        },
#endif

Examples of received data:

21:27:11 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AAA606035012E449BF55"}}
21:27:48 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AAA606035102DD51C455"}}
21:28:57 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AAA606035012E449BF55"}}
21:29:50 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AAA606035012E449BF55"}}
21:32:29 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AAA606035012E449BF55"}}
21:33:38 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AAA606035102DD51C455"}}
21:34:15 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AAA606035012E449BF55"}}
21:35:18 MQT: tthome/tele/sonoff121/RESULT = {"RfRaw":{"Data":"AAA606035102DD51C455"}}

At 21:32:29:
AAA6 - command 0xA6
0603 - not sure what this is, maybe 1539us? More or less 833 high + 833 low? This is very consistent, never changes.
50 - sensor ID
1 - some flags
2E4 - temperature
49 - humidity
BF - checksum
55 - command end

Do you think you can offer some insight on why I'm not receiving all 3 sensors, and why I'm losing some of the transmission events? Or, if I'm doing it all wrong defining the protocol, can you point me in the right direction?

Any reply will be greatly appreciated.

Thanks a lot.

Tales

bkenobi commented 5 years ago

I didn't make any progress on my sensors despite knowing all relevant signal and decoding details. Hopefully you get your sensors included so I can follow your template.

thermseekr commented 4 years ago

Hello @bkenobi

Given the lack of replies to my posts and also lack of time to keep researching I kinda gave up using Portisch firmware. I got back to a Raspberry Pi with a $10 SDR receiver. The setup is not very complicated, I flashed Raspbian on a SD card and then followed an online guide by Andreas Spier on how to compile/build rtl_433. The last versions of rtl_433 can output the information directly over MQTT so it essencially does the same as the Sonoff Bridge + Portisch with the benefit of being muuuuuuch more flexible and documented. And with the disadvantage of being mor expensive.

I'm ok with the extra cost because my setup is working beautifully, hasn't missed a single transmission since I started it. The Pi is hidden, only the antenna shows but it it very discreet. Mine is connected by cable to a network switch but you can also use WiFi.

I would suggest you verify if rtl_433 already knows your protocol. If it doesn't there's plenty of documentation on how to teach new ones. If as you said you know details about your protocol I think you could easily do it.

It's important to say that I understand this is an open source project and the owner may not have time or interest on giving support. This is how it is, and it's ok.