merbanan / rtl_433

Program to decode radio transmissions from devices on the ISM bands (and other frequencies)
GNU General Public License v2.0
5.93k stars 1.3k forks source link

Add support: Cotech FT0203/18-3676 Anemometer #2569

Open GreatAlbatross opened 1 year ago

GreatAlbatross commented 1 year ago

I've been around this sensor for a few years, and finally got around to working out what I think the bits are. However, I'm not quite confident enough to write a proper decoder.

It's a battery+solar powered anemometer. I don't think it supports full degree accuracy, just cardinal and intercardinal (N, NW, W, SW etc.)

Example data: 002938c800001dfffe06 - AVG speed 0.0M/S, GUST speed 0.0M/S, DIR: West 002938c02428b5ffff98 - AVG speed 1.2M/S, GUST speed 1.4M/S, DIR: East

From what I've worked out from observing the receiving station (and a bit of deduction):

Example: 002938c02428b5ffff98
       : AAAAAABCDDEEFFGGGHHH

Flex decoder I wrote to get some info out of the unit:

decoder n=Anemometer,m=OOK_MC_ZEROBIT,s=504 ,l=0 ,r=972,bits=79,
get=battery_ok:@24:{4},get=wind_avg_m_s:@32:{8}:%d,
get=gust_speed_m_s:@40:{8}:%d,
get=direction:@48:{8}:[1:North 91:North-East 181:East 16:South-East 105:South-West 29:West 119:North-West]

BitBench with a rough idea of mapping

If anyone could help adding support, it would be most appreciated, as I think this is as far as I can go! If the data is needed more raw, please let me know. And as mentioned, I'm pretty sure the device only registers to 1/8 of a circle accuracy, so please don't worry too much about decoding the mystery numbers!

zuckschwerdt commented 1 year ago

The "bytes" (8 bit) you list are "nibbles" (4 bit), but it's easy enough to understand as-is.

The wind direction mapping does not seem obvious, what is south? Do they combine with C? Can you put all 8 directions in the BitBench? (e.g. lines of 002938c800001dfffe06 [AVG 0.0 GUST 0.0 West])

Usually we expect a checksum, likely at the end -- could the that last byte(s) be some checksum? Can you report a list of codes (e.g. 20-40 codes)?

GreatAlbatross commented 1 year ago

Oops, sorry. My CS teacher would be giving me a withering look for that. And of course, the day I need some more data, the wind is dead still. I gave someone a cup of coffee, and had them use it as a fidget spinner for 10 minutes.

The wind directions were not obvious. I had to sit looking at the receiver for a while. I couldn't see a correlation other than certain values being certain directions, hence the mapping out in the flex decoder.

I think I may be completely wrong about the last 3 digits being related to angle.

Data: 8 lines where I've verified the direction, 6 lines with direction and speeds, 22 lines just for checksums.

BitBench

The data tagged DIR correlates with direction. South: 69, South-West: C3, West: 1D, North-West: 77, North: 01, North-East: 5B, East: 5B, South-East: 0F WIND and GUST are the decimal conversions of the raw values, which are 20x real value.

Thanks again for taking a look at this.

zuckschwerdt commented 1 year ago

You need to shift on bit left, e.g. try this: ID:24h BATT:4b DIRFLAG:3b AVG:d GUST:d DIR:8d ?:16h CHK?:8h x

GreatAlbatross commented 1 year ago

:open_mouth: Holy cow, you got it!

The windspeed values are now correct. And that lines everything up with the direction flag being equal to 256 West (14) + 256 = 270, which is correct. North-West (59), plus 256 = 315, also correct.

The block of FFFF is now always FFFF too.

Updated bitbench so it's all here

zuckschwerdt commented 1 year ago

The FFFF block might be an optional UV sensor? Is there documentation about such a feature?

The checksum is a CRC-8 with poly 0x31, init is either 0xd4 for the full code (with a 0-bit prepended) or 0xc0 for the code with the leading 7 0-bits skipped.

GreatAlbatross commented 1 year ago

Nothing about a UV sensor I'm afraid. I guess it's possible the board was used for something else? But I have never seen anything other than FFFF. There is no documentation, as far as I know.
The only thing I can add leafing through the manual, is that the resolution of the anemometer is 45 degrees, maximum speed is 50M/S, and the update interval is 16 seconds.

GreatAlbatross commented 10 months ago

Hope this is OK to add here: While I haven't made any progress on writing a full decoder for rtl_433, I have now duct-taped together working integration with HomeAssistant.

The direction values are mapped rather than calculated, and HASS has to handle dividing the speed values by 10, but it is working. https://community.home-assistant.io/t/basic-support-for-cotech-ft0203-18-3676-anemometer/608702

zuckschwerdt commented 10 months ago

If you don't have the time or if writing in C isn't your expertise then I can add the decoder. I will need a few samples (https://triq.org/rtl_433/ANALYZE.html) uploaded here as zip. And it would be helpful if you could test the decoder (from a PR) before merge.

klohner commented 6 months ago

@GreatAlbatross Would you be able to zip up a few .cu8 samples of this signal and attach to this issue?

klohner commented 6 months ago

Figured out another piece of the code. The 29th bit is being used as a 9th bit for the direction. If set, add 256 to what you're getting DIR and you'll get a compass heading in degrees. For example, a heading to the west is DIR "014" in decimal. But this 9th bit is set, so add 256 for 270. 270 degrees is West.

BitBench Format String: ID:24h BATT:4b DIR_BIT_NINE:1b ??:2b AVG:8d GUST:8d DIR:8d FFFF:16h ?:b CHK?:8h

ID:002938 BATT:1100 DIR_BIT_NINE:1 ??:00 AVG:000 GUST:000 DIR:014 FFFF:ffff ?:0 CHK?:06 [West]

BitBench

Here's a reveng to confirm the CRC-8 as @zuckschwerdt mentioned.

reveng -w 8 -s 002938c0000169ffff70 002938c00007c3fffe3a 002938c800001dfffe06 002938c8000077ffff62
width=8  poly=0x31  init=0x99  refin=false  refout=false  xorout=0x00  check=0xd5  residue=0x00  name=(none)
GreatAlbatross commented 3 months ago

@GreatAlbatross Would you be able to zip up a few .cu8 samples of this signal and attach to this issue?

Sorry for the slow reply. If this would still be useful, how do I go about recording?

The battery on my device has recently failed, so I reasoned it was a good time to capture values before and after replacing! (It runs during daylight hours due to the solar panel)

ProfBoc75 commented 3 months ago

@GreatAlbatross Would you be able to zip up a few .cu8 samples of this signal and attach to this issue?

Sorry for the slow reply. If this would still be useful, how do I go about recording?

The battery on my device has recently failed, so I reasoned it was a good time to capture values before and after replacing! (It runs during daylight hours due to the solar panel)

Hi @GreatAlbatross, try this to get some recording with your flex configuration:

rtl_433 -X "n=Anemometer,m=OOK_MC_ZEROBIT,s=504,l=0,r=972,bits>=79" -S unknown

Each time a signal is matching your flex decoder, write down the recording file name and its information from station display, zip few cu8 files and drop here in a comment with the information.

You may have to play with the gain and / or remove the antenna to get good signal. drop cu8 here https://triq.org/pdv/ to see if the signal is good quality.

GreatAlbatross commented 3 months ago

I'm not sure if I managed to get any useful data in the cu8 files, I'm afraid. Any that I looked at, didn't seem to match the data being picked up.

Battery change is done, and it's gone from: 002938c0141a01ffff72 to 00293b600c0eb5fffffa

GreatAlbatross commented 3 months ago

g044_433.92M_250k.cu8.gz Just in case it's any use (I have some other 433 traffic flying around too)

ProfBoc75 commented 3 months ago

The cu8 file is not good, not the anemometer. Try other captures. You can replay the cu8 with the same flex decoder to select good cu8 files. More details Analyze.md

I notice that the wind max speed is 50 m/s , from the user guide, and based on the current bitbench layout one byte is not enough and another 9 bit MSB is required like for wind dir. Not sure about the battery flag also.

My bitbench update and possible MSB

Edit: Therefore we need more code captures and with wind speed above 25.5 m/s, you can try with compressed air during at least 16 seconds. We should identify msb bit for avg wind speed and another msb bit for wind gust. So you may have to try lot of times until you get the good data.

ProfBoc75 commented 3 months ago

Well, looks like we already have a very close decoder handle by rtl_433, cotech_36_7959.c same CRC-8 (0x31, 0xc0) and data layout very close with more information like lux/uv/rain.temp/hum than here.

Assumption that we have the msb in the same order: bitbench

Few remarks:

Raw:

{79}00 29 38 c8 00 00 1d ff fe 06

Left shift 7 bits:

{72}14 9c 64 00 00 0e ff ff 03
    PP[II IM SS GG DD FF FF]CC
         |  |
    /----+  +-----\
     123 4 5 6 7 8  
     III B F MSB_DIR 
               MSB_GUST 
                 MSB_AVG

Data Layout:

All should be confirmed by new captures.

GreatAlbatross commented 3 months ago

Further examples added to bitbench

And a gzipped cu8 which I'm pretty sure is correct. I realised that as I had written a very rudimentary encoder previously, it might have been skipping saving when unknown was specified. g083_433.92M_250k.cu8.gz

gdt commented 1 month ago

Status?

gdt commented 3 weeks ago

@GreatAlbatross Where are we on this? Are you working on a PR to add a flex decoder, or writing a real decoder, or ?

GreatAlbatross commented 3 weeks ago

I don't think my flex decoder is up to contribution quality, and I don't think I have the skills to write a real decoder unfortunately. (at least, not in a sensible timeframe!)

I'm happy to do some additional captures to help things.

klohner commented 3 weeks ago

Some notes I have on this device/decoder FWIW:

image

$ rtl_433 -r g083_433.92M_250k.cu8 -X "n=Cotech-PCM-raw,m=OOK_PCM,s=488,l=488,r=1500,bits>=158" -X "n=Cotech-PCM,m=OOK_PCM,s=488,l=488,r=1500,bits>=158,symbol_zero={2}4,symbol_one={2}8" -X "n=Cotech-ZB,m=OOK_MC_ZEROBIT,s=488,l=0,r=1500,bits>=79"
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
time      : 2024-06-24T13:21:29.067959
model     : Cotech-PCM-raw                         count     : 1
num_rows  : 1            rows      :
len       : 160          data      : aaaa99965a9a695559996596a55aaaaaaaaa6a58
codes     : {160}aaaa99965a9a695559996596a55aaaaaaaaa6a58
Modulation: ASK          Freq      : 433.9 MHz
RSSI      : -0.1 dB      SNR       : 14.8 dB       Noise     : -14.9 dB
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
time      : 2024-06-24T13:21:29.067959
model     : Cotech-PCM   count     : 1             num_rows  : 1
rows      :
len       : 79           data      : ffa93b602a49c3ffff72
codes     : {79}ffa93b602a49c3ffff72
Modulation: ASK          Freq      : 433.9 MHz
RSSI      : -0.1 dB      SNR       : 14.8 dB       Noise     : -14.9 dB
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
time      : 2024-06-24T13:21:29.067959
model     : Cotech-ZB    count     : 1             num_rows  : 1
rows      :
len       : 79           data      : 00293b602a49c3ffff72
codes     : {79}00293b602a49c3ffff72
Modulation: ASK          Freq      : 433.9 MHz
RSSI      : -0.1 dB      SNR       : 14.8 dB       Noise     : -14.9 dB
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
# Cotech FT0203/18-3676
$ reveng -w 8 -s ffd49db01524e1ffffb9 ffd49c6400000effff03 ffd49c6012145affffcc ffd49c600000b4ffffb8 ffd49c600003e1ffff1d
width=8  poly=0x31  init=0xff  refin=false  refout=false  xorout=0x00  check=0xf7  residue=0x00  name="CRC-8/NRSC-5"

# Cotech-367959
$ reveng -w 8 -s ffd4c5400000f10318846d22fffbfbe5 ffd4c54400002b0318846d22fffbfb5b ffd4c54000007e0318846d22fffbfbc5 ffd4c5400107bf0348846d22fffbfb2f
width=8  poly=0x31  init=0xff  refin=false  refout=false  xorout=0x00  check=0xf7  residue=0x00  name="CRC-8/NRSC-5"
# somewhat based on cotech_36_7959.c
# tested on samples in https://github.com/zuckschwerdt/rtl_433_tests/tree/master/tests/cotech/cotech_36-7959/01
# preamble {16}a665 is MC {8}d4
# prefix result with {16}ffd4 and final byte is "CRC-8/NRSC-5" (poly=0x31  init=0xff)
decoder {
  name        = Cotech-367959-Flex,
  modulation  = OOK_PCM,
  short       = 488,
  long        = 488,
  reset       = 5000,
  bits       >= 256,
  bits       <= 272,
  preamble    = {16}a665,
  symbol_zero = {2}4,
  symbol_one  = {2}8,
  get         = model:@0:{4}:%d,
  get         = id:@4:{8}:%d,
  get         = bat:@12:{1}:%d,
  get         = DIR_MSB:@13:{1}:%x,
  get         = AVG m/s x10:@15:{9}:%d,
  get         = CRC:@104:{8}:%02x,
}

# https://github.com/merbanan/rtl_433/issues/2569
decoder {
  name        = Cotech FT0203/18-3676-Flex,
  modulation  = OOK_PCM,
  short       = 488,
  long        = 488,
  reset       = 5000,
  bits       >= 160,
  bits       <= 176,
  preamble    = {16}a665,
  symbol_zero = {2}4,
  symbol_one  = {2}8,
  get         = model:@0:{4}:%d,
  get         = id:@4:{8}:%d,
  get         = bat:@12:{1}:%d,
  get         = DIR_MSB:@13:{1}:%x,
  get         = AVG m/s x10:@15:{9}:%d,
  get         = CRC:@56:{8}:%02x,
}
GreatAlbatross commented 1 week ago

Thankyou for that, I'm afraid I missed this update! I will try to get some more captures and reboots in the near future.