From 49348f362ff1cb29f10cb5d02f68cd985415dec2 Mon Sep 17 00:00:00 2001 From: eric Date: Tue, 27 Jan 2015 15:01:48 +0100 Subject: [PATCH 1/5] Add Owl CMR180 support --- src/devices/oregon_scientific.c | 173 ++++++++++++++++++++++---------- 1 file changed, 121 insertions(+), 52 deletions(-) diff --git a/src/devices/oregon_scientific.c b/src/devices/oregon_scientific.c index 717ad6d4..cb399487 100644 --- a/src/devices/oregon_scientific.c +++ b/src/devices/oregon_scientific.c @@ -15,6 +15,32 @@ unsigned int get_os_humidity(unsigned char *message, unsigned int sensor_id) { return humidity; } +unsigned int get_os_rollingcode(unsigned char *message, unsigned int sensor_id){ + int rc = 0; + rc = (message[2]&0x0F) + (message[3]&0xF0); + return rc; +} + +unsigned short int power(const unsigned char* d){ + unsigned short int val = 0; + val += d[4] << 8; + val += d[3]; + //fprintf(stderr, "Power: %x %d", val, val); + return val & 0xFFF0 ; +} + +unsigned long total(const unsigned char* d){ + unsigned long val = 0; + if ( (d[1]&0x0F) == 0 ){ + // Sensor returns total only if nibble#4 == 0 + val = (unsigned long)d[8]<<24; + val += (unsigned long)d[7] << 16; + val += d[6] << 8; + val += d[5]; + } + return val ; +} + static int validate_os_checksum(unsigned char *msg, int checksum_nibble_idx) { // Oregon Scientific v2.1 and v3 checksum is a 1 byte 'sum of nibbles' checksum. // with the 2 nibbles of the checksum byte swapped. @@ -126,7 +152,11 @@ static int oregon_scientific_v2_1_parser(uint8_t bb[BITBUF_ROWS][BITBUF_COLS], i if (channel == 4) channel = 3; // sensor 3 channel number is 0x04 float temp_c = get_os_temperature(msg, sensor_id); - if (sensor_id == 0x1d20) fprintf(stderr, "Weather Sensor THGR122N Channel %d ", channel); + unsigned int rc = get_os_rollingcode(msg, sensor_id); + if (sensor_id == 0x1d20) { + fprintf(stderr, "Weather Sensor THGR122N RC %x Channel %d ", rc, channel); + //fprintf(stderr, "Message: "); for (i=0 ; i<20 ; i++) fprintf(stderr, "%02x ", msg[i]); + } else fprintf(stderr, "Weather Sensor THGR968 Outdoor "); fprintf(stderr, "Temp: %3.1f°C %3.1f°F Humidity: %d%%\n", temp_c, ((temp_c*9)/5)+32,get_os_humidity(msg, sensor_id)); } @@ -192,54 +222,54 @@ fprintf(stderr, "Message: "); for (i=0 ; i<20 ; i++) fprintf(stderr, "%02x ", ms static int oregon_scientific_v3_parser(uint8_t bb[BITBUF_ROWS][BITBUF_COLS], int16_t bits_per_row[BITBUF_ROWS]) { // Check stream for possible Oregon Scientific v3 protocol data (skip part of first and last bytes to get past sync/startup bit errors) - if ((((bb[0][0]&0xf) == 0x0f) && (bb[0][1] == 0xff) && ((bb[0][2]&0xc0) == 0xc0)) || + if ((((bb[0][0]&0xf) == 0x0f) && (bb[0][1] == 0xff) && ((bb[0][2]&0xc0) == 0xc0)) || (((bb[0][0]&0xf) == 0x00) && (bb[0][1] == 0x00) && ((bb[0][2]&0xc0) == 0x00))) { - int i,j; - unsigned char msg[BITBUF_COLS] = {0}; - unsigned int sync_test_val = (bb[0][2]<<24) | (bb[0][3]<<16) | (bb[0][4]<<8); - int dest_bit = 0; - int pattern_index; - // Could be extra/dropped bits in stream. Look for sync byte at expected position +/- some bits in either direction - for(pattern_index=0; pattern_index<16; pattern_index++) { - unsigned int mask = (unsigned int)(0xfff00000>>pattern_index); - unsigned int pattern = (unsigned int)(0xffa00000>>pattern_index); - unsigned int pattern2 = (unsigned int)(0xff500000>>pattern_index); - unsigned int pattern3 = (unsigned int)(0x00500000>>pattern_index); -//fprintf(stderr, "OS v3 Sync nibble search - test_val=%08x pattern=%08x mask=%08x\n", sync_test_val, pattern, mask); - if (((sync_test_val & mask) == pattern) || - ((sync_test_val & mask) == pattern2) || - ((sync_test_val & mask) == pattern3)) { - // Found sync byte - start working on decoding the stream data. - // pattern_index indicates where sync nibble starts, so now we can find the start of the payload - int start_byte = 3 + (pattern_index>>3); - int start_bit = (pattern_index+4) & 0x07; -//fprintf(stderr, "Oregon Scientific v3 Sync test val %08x ok, starting decode at byte index %d bit %d\n", sync_test_val, start_byte, start_bit); - j = start_bit; - for (i=start_byte;i> j)) >> (7-j)); + int i,j; + unsigned char msg[BITBUF_COLS] = {0}; + unsigned int sync_test_val = (bb[0][2]<<24) | (bb[0][3]<<16) | (bb[0][4]<<8); + int dest_bit = 0; + int pattern_index; + // Could be extra/dropped bits in stream. Look for sync byte at expected position +/- some bits in either direction + for(pattern_index=0; pattern_index<16; pattern_index++) { + unsigned int mask = (unsigned int)(0xfff00000>>pattern_index); + unsigned int pattern = (unsigned int)(0xffa00000>>pattern_index); + unsigned int pattern2 = (unsigned int)(0xff500000>>pattern_index); + unsigned int pattern3 = (unsigned int)(0x00500000>>pattern_index); + //fprintf(stderr, "OS v3 Sync nibble search - test_val=%08x pattern=%08x mask=%08x\n", sync_test_val, pattern, mask); + if (((sync_test_val & mask) == pattern) || + ((sync_test_val & mask) == pattern2) || + ((sync_test_val & mask) == pattern3)) { + // Found sync byte - start working on decoding the stream data. + // pattern_index indicates where sync nibble starts, so now we can find the start of the payload + int start_byte = 3 + (pattern_index>>3); + int start_bit = (pattern_index+4) & 0x07; + //fprintf(stderr, "Oregon Scientific v3 Sync test val %08x ok, starting decode at byte index %d bit %d\n", sync_test_val, start_byte, start_bit); + j = start_bit; + for (i=start_byte;i> j)) >> (7-j)); - // copy every bit from source stream to dest packet - msg[dest_bit>>3] |= (((bb[0][i] & (0x80 >> j)) >> (7-j)) << (7-(dest_bit & 0x07))); - -//fprintf(stderr,"i=%d j=%d dest_bit=%02x bb=%02x msg=%02x\n",i, j, dest_bit, bb[0][i], msg[dest_bit>>3]); - if ((dest_bit & 0x07) == 0x07) { - // after assembling each dest byte, flip bits in each nibble to convert from lsb to msb bit ordering - int k = (dest_bit>>3); - unsigned char indata = msg[k]; - // flip the 4 bits in the upper and lower nibbles - msg[k] = ((indata & 0x11) << 3) | ((indata & 0x22) << 1) | - ((indata & 0x44) >> 1) | ((indata & 0x88) >> 3); - } - dest_bit++; - j++; - } - j=0; - } - break; - } - } + // copy every bit from source stream to dest packet + msg[dest_bit>>3] |= (((bb[0][i] & (0x80 >> j)) >> (7-j)) << (7-(dest_bit & 0x07))); + //fprintf(stderr,"i=%d j=%d dest_bit=%02x bb=%02x msg=%02x\n",i, j, dest_bit, bb[0][i], msg[dest_bit>>3]); + if ((dest_bit & 0x07) == 0x07) { + // after assembling each dest byte, flip bits in each nibble to convert from lsb to msb bit ordering + int k = (dest_bit>>3); + unsigned char indata = msg[k]; + // flip the 4 bits in the upper and lower nibbles + msg[k] = ((indata & 0x11) << 3) | ((indata & 0x22) << 1) | + ((indata & 0x44) >> 1) | ((indata & 0x88) >> 3); + } + dest_bit++; + j++; + } + j=0; + } + break; + } + } + if ((msg[0] == 0xf8) && (msg[1] == 0x24)) { if (validate_os_checksum(msg, 15) == 0) { int channel = ((msg[2] >> 4)&0x0f); @@ -247,7 +277,7 @@ static int oregon_scientific_v3_parser(uint8_t bb[BITBUF_ROWS][BITBUF_COLS], int int humidity = get_os_humidity(msg, 0xf824); fprintf(stderr,"Weather Sensor THGR810 Channel %d Temp: %3.1f°C %3.1f°F Humidity: %d%%\n", channel, temp_c, ((temp_c*9)/5)+32, humidity); } - return 1; + return 1; //msg[k] = ((msg[k] & 0x0F) << 4) + ((msg[k] & 0xF0) >> 4); } else if ((msg[0] == 0x19) && (msg[1] == 0x84)) { if (validate_os_checksum(msg, 17) == 0) { float gustWindspeed = (msg[11]+msg[10])/100; @@ -256,11 +286,50 @@ static int oregon_scientific_v3_parser(uint8_t bb[BITBUF_ROWS][BITBUF_COLS], int } return 1; } else if ((msg[0] != 0) && (msg[1]!= 0)) { // sync nibble was found and some data is present... -fprintf(stderr, "Message received from unrecognized Oregon Scientific v3 sensor.\n"); -fprintf(stderr, "Message: "); for (i=0 ; i> j)) >> (7-j)); + + // copy every bit from source stream to dest packet + msg[dest_bit>>3] |= (((bb[0][i] & (0x80 >> j)) >> (7-j)) << (7-(dest_bit & 0x07))); + + //fprintf(stderr,"i=%d j=%d dest_bit=%02x bb=%02x msg=%02x\n",i, j, dest_bit, bb[0][i], msg[dest_bit>>3]); + if ((dest_bit & 0x07) == 0x07) { + // after assembling each dest byte, flip bits in each nibble to convert from lsb to msb bit ordering + int k = (dest_bit>>3); + unsigned char indata = msg[k]; + // flip the 4 bits in the upper and lower nibbles + msg[k] = ((indata & 0x11) << 3) | ((indata & 0x22) << 1) | + ((indata & 0x44) >> 1) | ((indata & 0x88) >> 3); + // Flip nibbles + msg[k] = (msg[k] & 0xF0) >> 4 | (msg[k] & 0x0F) << 4; + } + dest_bit++; + j++; + } + j=0; + } + unsigned short int ipower = power(msg); + unsigned long itotal = total(msg); + float total_energy = itotal/3600/1000.0; + if (itotal) + fprintf(stderr,"Energy Sensor CMR180 Id %x%x power: %dW, total: %luW, Total Energy: %.3fkWh\n", msg[0], msg[1], ipower, itotal, total_energy); + else + fprintf(stderr,"Energy Sensor cmr180 Id %x%x power: %dW\n", msg[0], msg[1], ipower); + + //for (i=0 ; i<15 ; i++) fprintf(stderr, "%02x ", msg[i]);fprintf(stderr,"\n"); + } else if (bb[0][3] != 0 ) { + //fprintf(stderr, "\nPossible Oregon Scientific v3 message, but sync nibble wasn't found\n"); + //fprintf(stderr, "Raw Data: "); for (i=0 ; i Date: Tue, 27 Jan 2015 22:49:45 +0100 Subject: [PATCH 2/5] Update running part --- README.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index dd180f64..33ac53df 100644 --- a/README.md +++ b/README.md @@ -31,15 +31,22 @@ Running: rtl_433 -h - Usage: [-d device_index (default: 0)] - [-g gain (default: 0 for auto)] - [-a analyze mode, print a textual description of the signal] - [-l change the detection level used to determine pulses (0-32000) default 10000] - [-f change the receive frequency, default is 433.92MHz] - [-S force sync output (default: async)] - [-r read data from file instead of from a receiver] - filename (a '-' dumps samples to stdout) - + Usage: [-d device_index (default: 0)] + [-g gain (default: 0 for auto)] + [-a analyze mode, print a textual description of the signal] + [-t signal auto save, use it together with analyze mode (-a -t) + [-l change the detection level used to determine pulses (0-3200) default: 10000] + [-f [-f...] receive frequency[s], default: 433920000 Hz] + [-s samplerate (default: 250000 Hz)] + [-S force sync output (default: async)] + [-r read data from file instead of from a receiver] + [-p ppm_error (default: 0)] + [-r test file name (indata)] + [-m test file mode (0 rtl_sdr data, 1 rtl_433 data)] + [-D print debug info on event + [-z override short value + [-x override long value + filename (a '-' dumps samples to stdout) Examples: From f34225722ea2519bc2af507e7c3c056c40cc6f1d Mon Sep 17 00:00:00 2001 From: Benjamin Larsson Date: Tue, 27 Jan 2015 22:53:32 +0100 Subject: [PATCH 3/5] oregon_scientific: remove utf-8 characters causing bad output under windows --- src/devices/oregon_scientific.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/devices/oregon_scientific.c b/src/devices/oregon_scientific.c index cb399487..f4e0b7dd 100644 --- a/src/devices/oregon_scientific.c +++ b/src/devices/oregon_scientific.c @@ -158,7 +158,7 @@ static int oregon_scientific_v2_1_parser(uint8_t bb[BITBUF_ROWS][BITBUF_COLS], i //fprintf(stderr, "Message: "); for (i=0 ; i<20 ; i++) fprintf(stderr, "%02x ", msg[i]); } else fprintf(stderr, "Weather Sensor THGR968 Outdoor "); - fprintf(stderr, "Temp: %3.1f°C %3.1f°F Humidity: %d%%\n", temp_c, ((temp_c*9)/5)+32,get_os_humidity(msg, sensor_id)); + fprintf(stderr, "Temp: %3.1fC %3.1fF Humidity: %d%%\n", temp_c, ((temp_c*9)/5)+32,get_os_humidity(msg, sensor_id)); } return 1; } else if (sensor_id == 0x5d60) { @@ -174,7 +174,7 @@ static int oregon_scientific_v2_1_parser(uint8_t bb[BITBUF_ROWS][BITBUF_COLS], i else if (forecast == 6) forecast_str = "Partly Cloudy"; else if (forecast == 0xc) forecast_str = "Sunny"; float temp_c = get_os_temperature(msg, 0x5d60); - fprintf(stderr,"Weather Sensor BHTR968 Indoor Temp: %3.1f°C %3.1f°F Humidity: %d%%", temp_c, ((temp_c*9)/5)+32, get_os_humidity(msg, 0x5d60)); + fprintf(stderr,"Weather Sensor BHTR968 Indoor Temp: %3.1fC %3.1fF Humidity: %d%%", temp_c, ((temp_c*9)/5)+32, get_os_humidity(msg, 0x5d60)); fprintf(stderr, " (%s) Pressure: %dmbar (%s)\n", comfort_str, ((msg[7] & 0x0f) | (msg[8] & 0xf0))+856, forecast_str); } return 1; @@ -192,7 +192,7 @@ static int oregon_scientific_v2_1_parser(uint8_t bb[BITBUF_ROWS][BITBUF_COLS], i channel = 3; // sensor 3 channel number is 0x04 float temp_c = get_os_temperature(msg, sensor_id); if (sensor_id == 0xec40) fprintf(stderr, "Thermo Sensor THR228N Channel %d ", channel); - fprintf(stderr, "Temp: %3.1f°C %3.1f°F\n", temp_c, ((temp_c*9)/5)+32); + fprintf(stderr, "Temp: %3.1fC %3.1fF\n", temp_c, ((temp_c*9)/5)+32); } return 1; } else if (sensor_id == 0xec40 && num_valid_v2_bits==129) { @@ -204,7 +204,7 @@ static int oregon_scientific_v2_1_parser(uint8_t bb[BITBUF_ROWS][BITBUF_COLS], i unsigned char rolling_code = ((msg[2] << 4)&0xF0) | ((msg[3] >> 4)&0x0F); float temp_c = get_os_temperature(msg, sensor_id); if (sensor_id == 0xec40) fprintf(stderr, "Thermo Sensor THN132N, Channel %d, Battery: %s, Rolling-code 0x%0X, ", channel, battery_low?"Low":"Ok", rolling_code); - fprintf(stderr, "Temp: %3.1f°C %3.1f°F\n", temp_c, ((temp_c*9)/5)+32); + fprintf(stderr, "Temp: %3.1fC %3.1fF\n", temp_c, ((temp_c*9)/5)+32); } return 1; } else if (num_valid_v2_bits > 16) { @@ -275,7 +275,7 @@ static int oregon_scientific_v3_parser(uint8_t bb[BITBUF_ROWS][BITBUF_COLS], int int channel = ((msg[2] >> 4)&0x0f); float temp_c = get_os_temperature(msg, 0xf824); int humidity = get_os_humidity(msg, 0xf824); - fprintf(stderr,"Weather Sensor THGR810 Channel %d Temp: %3.1f°C %3.1f°F Humidity: %d%%\n", channel, temp_c, ((temp_c*9)/5)+32, humidity); + fprintf(stderr,"Weather Sensor THGR810 Channel %d Temp: %3.1fC %3.1fF Humidity: %d%%\n", channel, temp_c, ((temp_c*9)/5)+32, humidity); } return 1; //msg[k] = ((msg[k] & 0x0F) << 4) + ((msg[k] & 0xF0) >> 4); } else if ((msg[0] == 0x19) && (msg[1] == 0x84)) { From df0217c211f68a12a0c051e04d688bf301321d6f Mon Sep 17 00:00:00 2001 From: Tommy Vestermark Date: Wed, 28 Jan 2015 00:04:17 +0100 Subject: [PATCH 4/5] Added support for Fine Offset Electronics Temp/Humidity sensor --- .gitignore | 1 + include/rtl_433.h | 3 +- include/rtl_433_devices.h | 1 + src/CMakeLists.txt | 3 +- src/devices/fineoffset.c | 110 ++++++++++++++++++++++++++++++++++++++ src/rtl_433.c | 53 ++++++++++++++++++ 6 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 src/devices/fineoffset.c diff --git a/.gitignore b/.gitignore index c95e2551..f611b1eb 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ build/ .project *.orig +*~ diff --git a/include/rtl_433.h b/include/rtl_433.h index 123b8f93..8c54434a 100644 --- a/include/rtl_433.h +++ b/include/rtl_433.h @@ -35,9 +35,10 @@ #define BITBUF_ROWS 50 /* Supported modulation types */ -#define OOK_PWM_D 1 /* Pulses are of the same length, the distance varies */ +#define OOK_PWM_D 1 /* Pulses are of the same length, the distance varies (PPM) */ #define OOK_PWM_P 2 /* The length of the pulses varies */ #define OOK_MANCHESTER 3 /* Manchester code */ +#define OOK_PWM_RAW 4 /* Pulse Width Modulation. No startbit removal. Short pulses = 1, Long = 0 */ typedef struct { unsigned int id; diff --git a/include/rtl_433_devices.h b/include/rtl_433_devices.h index 53cf9170..cf36d65f 100644 --- a/include/rtl_433_devices.h +++ b/include/rtl_433_devices.h @@ -17,5 +17,6 @@ extern r_device mebus433; extern r_device intertechno; extern r_device newkaku; extern r_device alectov1; +extern r_device fineoffset_WH2; #endif /* INCLUDE_RTL_433_DEVICES_H_ */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c573583a..c2197e5b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,7 +30,8 @@ add_executable(rtl_433 devices/mebus.c devices/intertechno.c devices/alecto.c - devices/newkaku.c) + devices/newkaku.c + devices/fineoffset.c) target_link_libraries(rtl_433 ${LIBRTLSDR_LIBRARIES} diff --git a/src/devices/fineoffset.c b/src/devices/fineoffset.c new file mode 100644 index 00000000..e858a12b --- /dev/null +++ b/src/devices/fineoffset.c @@ -0,0 +1,110 @@ +/* Fine Offset Electronics sensor protocol + * + * The protocol is for the wireless Temperature/Humidity sensor + * Fine Offset Electronics WH2 + * aka Agimex Rosenborg 66796 (sold in Denmark) + * aka ClimeMET CM9088 (Sold in UK) + * aka ... + * + * The sensor sends two identical packages of 48 bits each ~50s. The bits are PWM modulated with On Off Keying + * + * The data is grouped in 6 bytes / 12 nibbles + * [pre] [pre] [type] [id] [id] [temp] [temp] [temp] [humi] [humi] [crc] [crc] + * + * pre is always 0xFF + * type is always 0x4 (may be different for different sensor type?) + * id is a random id that is generated when the sensor starts + * temp is 12 bit signed magnitude scaled by 10 celcius + * humi is 8 bit relative humidity percentage + * + * Based on reverse engineering with gnu-radio and the nice article here: + * http://lucsmall.com/2012/04/29/weather-station-hacking-part-2/ + * + * Copyright (C) 2015 Tommy Vestermark + * 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. + */ +#include "rtl_433.h" + + +// Generic CRC-8 +// (Should probably be moved to somewhere common) +// polynomial byte is from x^7 to x^0 (x^8 is implicitly one) +uint8_t crc8(uint8_t const message[], unsigned nBytes, uint8_t polynomial) { + uint8_t remainder = 0; + unsigned byte, bit; + + for (byte = 0; byte < nBytes; ++byte) { + remainder ^= message[byte]; + for (bit = 0; bit < 8; ++bit) { + if (remainder & 0x80) { + remainder = (remainder << 1) ^ polynomial; + } + else { + remainder = (remainder << 1); + } + } + } + return remainder; +} + + +static int fineoffset_WH2_callback(uint8_t bb[BITBUF_ROWS][BITBUF_COLS], int16_t bits_per_row[BITBUF_ROWS]) { + uint8_t ID; + float temperature; + float humidity; + + const uint8_t polynomial = 0x31; // x8 + x5 + x4 + 1 (x8 is implicit) + + // Validate package + if (bits_per_row[0] >= 48 && // Dont waste time on a short package + bb[0][0] == 0xFF && // Preamble + bb[0][5] == crc8(&bb[0][1], 4, polynomial) // CRC (excluding preamble) + ) + { + // Nibble 3,4 contains ID + ID = ((bb[0][1]&0x0F) << 4) | ((bb[0][2]&0xF0) >> 4); + + // Nible 5,6,7 contains 12 bits of temperature + // The temperature is signed magnitude and scaled by 10 + int16_t temp; + temp = bb[0][3]; + temp |= (int16_t)(bb[0][2] & 0x0F) << 8; + if(temp & 0x800) { + temp &= 0x7FF; // remove sign bit + temp = -temp; // reverse magnitude + } + temperature = (float)temp / 10; + + // Nibble 8,9 contains humidity + humidity = bb[0][4]; + + fprintf(stderr, "Fine Offset Electronics, WH2:\n"); + fprintf(stderr, "ID = 0x%2X\n", ID); + fprintf(stderr, "temperature = %.1f C\n", temperature); + fprintf(stderr, "humidity = %2.0f %%\n", humidity); + // fprintf(stderr, "raw = %02x %02x %02x %02x %02x %02x\n",bb[0][0],bb[0][1],bb[0][2],bb[0][3],bb[0][4],bb[0][5]); + + if (debug_output) + debug_callback(bb, bits_per_row); + + return 1; + } + return 0; +} + + +r_device fineoffset_WH2 = { + /* .id = */ 12, + /* .name = */ "Fine Offset Electronics, WH-2 Sensor", + /* .modulation = */ OOK_PWM_RAW, + /* .short_limit = */ 200, // Short pulse 136, long pulse 381, fixed gap 259 + /* .long_limit = */ 700, // Maximum pulse period (long pulse + fixed gap) + /* .reset_limit = */ 700, // We just want 1 package + /* .json_callback = */ &fineoffset_WH2_callback, +}; + + + diff --git a/src/rtl_433.c b/src/rtl_433.c index abd89339..ba75048a 100644 --- a/src/rtl_433.c +++ b/src/rtl_433.c @@ -796,6 +796,55 @@ static void manchester_decode(struct dm_state *demod, struct protocol_state* p, } } + +/* Pulse Width Modulation. No startbit removal */ +static void pwm_raw_decode(struct dm_state *demod, struct protocol_state* p, int16_t *buf, uint32_t len) { + unsigned int i; + for (i = 0; i < len; i++) { + if (p->start_c) p->sample_counter++; + + // Detect Pulse Start (leading edge) + if (!p->pulse_start && (buf[i] > demod->level_limit)) { + p->pulse_start = 1; + p->sample_counter = 0; + // Check for first bit in sequence + if(!p->start_c) { + p->start_c = 1; + } + } + + // Detect Pulse End (trailing edge) + if (p->pulse_start && (buf[i] < demod->level_limit)) { + p->pulse_start = 0; + if (p->sample_counter <= p->short_limit) { + demod_add_bit(p, 1); + } else { + demod_add_bit(p, 0); + } + } + + // Detect Pulse period overrun + if (p->sample_counter == p->long_limit) { + demod_next_bits_packet(p); + } + + // Detect Pulse exceeding reset limit + if (p->sample_counter > p->reset_limit) { + p->sample_counter = 0; + p->start_c = 0; + p->pulse_start = 0; + + if (p->callback) + events+=p->callback(p->bits_buffer, p->bits_per_row); + else + demod_print_bits_packet(p); + + demod_reset_bits_packet(p); + } + } +} + + /** Something that might look like a IIR lowpass filter * * [b,a] = butter(1, 0.01) -> quantizes nicely thus suitable for fixed point @@ -874,6 +923,9 @@ static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx) { case OOK_MANCHESTER: manchester_decode(demod, demod->r_devs[i], demod->f_buf, len/2); break; + case OOK_PWM_RAW: + pwm_raw_decode(demod, demod->r_devs[i], demod->f_buf, len / 2); + break; default: fprintf(stderr, "Unknown modulation %d in protocol!\n", demod->r_devs[i]->modulation); } @@ -1013,6 +1065,7 @@ int main(int argc, char **argv) { register_protocol(demod, &alectov1); register_protocol(demod, &intertechno); register_protocol(demod, &mebus433); + register_protocol(demod, &fineoffset_WH2); if (argc <= optind - 1) { usage(); From af9e55493b95be37560a3cf2b00ecb63b4a8c280 Mon Sep 17 00:00:00 2001 From: Tommy Vestermark Date: Wed, 28 Jan 2015 00:14:54 +0100 Subject: [PATCH 5/5] Corrected tab to space --- include/rtl_433.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/rtl_433.h b/include/rtl_433.h index 8c54434a..1fb8fc28 100644 --- a/include/rtl_433.h +++ b/include/rtl_433.h @@ -38,7 +38,7 @@ #define OOK_PWM_D 1 /* Pulses are of the same length, the distance varies (PPM) */ #define OOK_PWM_P 2 /* The length of the pulses varies */ #define OOK_MANCHESTER 3 /* Manchester code */ -#define OOK_PWM_RAW 4 /* Pulse Width Modulation. No startbit removal. Short pulses = 1, Long = 0 */ +#define OOK_PWM_RAW 4 /* Pulse Width Modulation. No startbit removal. Short pulses = 1, Long = 0 */ typedef struct { unsigned int id;