commit
6bcd3b1439
7 changed files with 197 additions and 2 deletions
|
@ -115,5 +115,6 @@ int pulse_demod_pwm_ternary(const pulse_data_t *pulses, struct protocol_state *d
|
|||
/// @return number of events processed
|
||||
int pulse_demod_manchester_zerobit(const pulse_data_t *pulses, struct protocol_state *device);
|
||||
|
||||
int pulse_demod_clock_bits(const pulse_data_t *pulses, struct protocol_state *device);
|
||||
|
||||
#endif /* INCLUDE_PULSE_DEMOD_H_ */
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#define DEFAULT_LEVEL_LIMIT 8000 // Theoretical high level at I/Q saturation is 128x128 = 16384 (above is ripple)
|
||||
#define MINIMAL_BUF_LENGTH 512
|
||||
#define MAXIMAL_BUF_LENGTH (256 * 16384)
|
||||
#define MAX_PROTOCOLS 32
|
||||
#define MAX_PROTOCOLS 33
|
||||
#define SIGNAL_GRABBER_BUFFER (12 * DEFAULT_BUF_LENGTH)
|
||||
|
||||
/* Supported modulation types */
|
||||
|
@ -42,6 +42,7 @@
|
|||
#define OOK_PULSE_PWM_PRECISE 6 // Pulse Width Modulation with precise timing parameters
|
||||
#define OOK_PULSE_PWM_RAW 7 // Pulse Width Modulation. Short pulses = 1, Long = 0
|
||||
#define OOK_PULSE_PWM_TERNARY 8 // Pulse Width Modulation with three widths: Sync, 0, 1. Sync determined by argument
|
||||
#define OOK_PULSE_CLOCK_BITS 9 // Level shift within the clock cycle.
|
||||
|
||||
#define FSK_DEMOD_MIN_VAL 16 // Dummy. FSK demodulation must start at this value
|
||||
#define FSK_PULSE_PCM 16 // FSK, Pulse Code Modulation
|
||||
|
|
|
@ -35,7 +35,8 @@
|
|||
DECL(chuango) \
|
||||
DECL(generic_remote) \
|
||||
DECL(tfa_twin_plus_303049) \
|
||||
DECL(digitech_ws)
|
||||
DECL(digitech_ws) \
|
||||
DECL(wt450)
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -52,6 +52,7 @@ add_executable(rtl_433
|
|||
devices/generic_remote.c
|
||||
devices/tfa_twin_plus_30.3049.c
|
||||
devices/xc0348.c
|
||||
devices/wt450.c
|
||||
)
|
||||
|
||||
target_link_libraries(rtl_433
|
||||
|
|
144
src/devices/wt450.c
Normal file
144
src/devices/wt450.c
Normal file
|
@ -0,0 +1,144 @@
|
|||
/* wt450 wireless weather sensors protocol
|
||||
*
|
||||
* Tested devices:
|
||||
* WT260H
|
||||
* WT405H
|
||||
*
|
||||
* Copyright (C) 2015 Tommy Vestermark
|
||||
* Copyright (C) 2015 Ladislav Foldyna
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
source from:
|
||||
http://ala-paavola.fi/jaakko/doku.php?id=wt450h
|
||||
|
||||
|
||||
The signal is FM encoded with clock cycle around 2000 µs
|
||||
No level shift within the clock cycle translates to a logic 0
|
||||
One level shift within the clock cycle translates to a logic 1
|
||||
Each clock cycle begins with a level shift
|
||||
My timing constants defined below are those observed by my program
|
||||
|
||||
+---+ +---+ +-------+ + high
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
+ +---+ +---+ +-------+ low
|
||||
^ ^ ^ ^ ^ clock cycle
|
||||
| 1 | 1 | 0 | 0 | translates as
|
||||
|
||||
Each transmission is 36 bits long (i.e. 72 ms)
|
||||
|
||||
Data is transmitted in pure binary values, NOT BCD-coded.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Outdoor sensor transmits data temperature, humidity.
|
||||
* Transmissions also include channel code and house code. The sensor transmits
|
||||
* every 60 seconds 3 packets.
|
||||
*
|
||||
* 1100 0001 | 0011 0011 | 1000 0011 | 1011 0011 | 0001
|
||||
* xxxx ssss | ccxx bhhh | hhhh tttt | tttt tttt | tttp
|
||||
*
|
||||
* x - constant
|
||||
* s - House code
|
||||
* c - Channel
|
||||
* b - battery indicator (0=>OK, 1=>LOW)
|
||||
* h - Humidity
|
||||
* t - Temperature
|
||||
* p - parity (xor of all bits should give 0)
|
||||
*/
|
||||
|
||||
#include "rtl_433.h"
|
||||
#include "util.h"
|
||||
#include "pulse_demod.h"
|
||||
|
||||
static int wt450_callback(bitbuffer_t *bitbuffer) {
|
||||
|
||||
bitrow_t *bb = bitbuffer->bb;
|
||||
uint8_t *b = bb[0];
|
||||
|
||||
uint8_t humidity = 0;
|
||||
uint8_t temp_whole = 0;
|
||||
uint8_t temp_fraction = 0;
|
||||
uint8_t house_code = 0;
|
||||
uint8_t channel = 0;
|
||||
uint8_t battery_low = 0;
|
||||
float temp = 0;
|
||||
uint8_t bit;
|
||||
uint8_t parity = 0;
|
||||
|
||||
time_t time_now;
|
||||
char time_str[LOCAL_TIME_BUFLEN];
|
||||
time(&time_now);
|
||||
local_time_str(time_now, time_str);
|
||||
|
||||
//bitbuffer_print(bitbuffer);
|
||||
|
||||
if ( bitbuffer->bits_per_row[0] != 36 )
|
||||
{
|
||||
fprintf(stderr, "wt450_callback: wrong size of bit per row %d\n",
|
||||
bitbuffer->bits_per_row[0] );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( b[0]>>4 != 0xC )
|
||||
{
|
||||
fprintf(stderr, "wt450_callback: wrong preamble\n");
|
||||
bitbuffer_print(bitbuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for ( bit = 0; bit < bitbuffer->bits_per_row[0]; bit++ )
|
||||
{
|
||||
parity ^= b[bit/8] & (0x80 >> (bit % 8));
|
||||
}
|
||||
|
||||
if ( !parity )
|
||||
{
|
||||
fprintf(stderr, "wt450_callback: wrong parity\n");
|
||||
bitbuffer_print(bitbuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
house_code = b[0] & 0xF;
|
||||
channel = (b[1] >> 6) + 1;
|
||||
battery_low = b[1] & 0x8;
|
||||
humidity = ((b[1] & 0x7) << 4) + (b[2] >> 4);
|
||||
temp_whole = (b[2] << 4) + (b[3] >> 4);
|
||||
temp_fraction = ((b[3] & 0xF) << 3) + (b[4] >> 5);
|
||||
temp = (temp_whole - 50) + (temp_fraction/100.0);
|
||||
|
||||
/*
|
||||
fprintf(stdout, "Temperature[%d]\n", temp_whole-50);
|
||||
fprintf(stdout, "temp fraction[%u]\n", temp_fraction);
|
||||
*/
|
||||
fprintf(stdout, "%s WT450 sensor: House Code %u, "
|
||||
"Channel %u, Battery %s, "
|
||||
"Temperature %.02f C, Humidity %u %%\n",
|
||||
time_str, house_code,
|
||||
channel, (battery_low) ? "LOW" : "OK",
|
||||
temp, humidity);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
PWM_Precise_Parameters clock_bits_parameters_generic = {
|
||||
.pulse_tolerance = 20,
|
||||
.pulse_sync_width = 0, // No sync bit used
|
||||
};
|
||||
|
||||
r_device wt450 = {
|
||||
.name = "WT450",
|
||||
.modulation = OOK_PULSE_CLOCK_BITS,
|
||||
.short_limit = 245,
|
||||
.long_limit = 488,
|
||||
.reset_limit = 4500,
|
||||
.json_callback = &wt450_callback,
|
||||
.disabled = 0,
|
||||
.demod_arg = (unsigned long)&clock_bits_parameters_generic,
|
||||
};
|
|
@ -276,3 +276,45 @@ int pulse_demod_manchester_zerobit(const pulse_data_t *pulses, struct protocol_s
|
|||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
int pulse_demod_clock_bits(const pulse_data_t *pulses, struct protocol_state *device) {
|
||||
unsigned int symbol[PD_MAX_PULSES * 2];
|
||||
unsigned int n;
|
||||
|
||||
PWM_Precise_Parameters *p = (PWM_Precise_Parameters *)device->demod_arg;
|
||||
bitbuffer_t bits = {0};
|
||||
int events = 0;
|
||||
|
||||
for(n = 0; n < pulses->num_pulses; n++) {
|
||||
symbol[n*2] = pulses->pulse[n];
|
||||
symbol[(n*2)+1] = pulses->gap[n];
|
||||
}
|
||||
|
||||
for(n = 0; n < pulses->num_pulses * 2; ++n) {
|
||||
if ( abs(symbol[n] - device->short_limit) < p->pulse_tolerance) {
|
||||
// Short - 1
|
||||
bitbuffer_add_bit(&bits, 1);
|
||||
if ( abs(symbol[++n] - device->short_limit) > p->pulse_tolerance) {
|
||||
/* fprintf(stderr, "Detected error during pulse_demod_clock_bits(): %s\n",
|
||||
device->name);
|
||||
*/ return events;
|
||||
}
|
||||
} else if ( abs(symbol[n] - device->long_limit) < p->pulse_tolerance) {
|
||||
// Long - 0
|
||||
bitbuffer_add_bit(&bits, 0);
|
||||
} else if (symbol[n] >= (unsigned int)device->reset_limit - p->pulse_tolerance ) {
|
||||
//END message ?
|
||||
if (device->callback) {
|
||||
events += device->callback(&bits);
|
||||
}
|
||||
if(!device->callback || (debug_output && events > 0)) {
|
||||
fprintf(stderr, "pulse_demod_clock_bits(): %s \n", device->name);
|
||||
bitbuffer_print(&bits);
|
||||
}
|
||||
bitbuffer_clear(&bits);
|
||||
}
|
||||
}
|
||||
|
||||
return events;
|
||||
}
|
||||
|
||||
|
|
|
@ -672,6 +672,7 @@ static void rtlsdr_callback(unsigned char *iq_buf, uint32_t len, void *ctx) {
|
|||
case OOK_PULSE_PWM_RAW:
|
||||
case OOK_PULSE_PWM_TERNARY:
|
||||
case OOK_PULSE_MANCHESTER_ZEROBIT:
|
||||
case OOK_PULSE_CLOCK_BITS:
|
||||
case FSK_PULSE_PCM:
|
||||
break;
|
||||
default:
|
||||
|
@ -708,6 +709,9 @@ static void rtlsdr_callback(unsigned char *iq_buf, uint32_t len, void *ctx) {
|
|||
case OOK_PULSE_MANCHESTER_ZEROBIT:
|
||||
pulse_demod_manchester_zerobit(&demod->pulse_data, demod->r_devs[i]);
|
||||
break;
|
||||
case OOK_PULSE_CLOCK_BITS:
|
||||
pulse_demod_clock_bits(&demod->pulse_data, demod->r_devs[i]);
|
||||
break;
|
||||
// FSK decoders
|
||||
case FSK_PULSE_PCM:
|
||||
break;
|
||||
|
@ -730,6 +734,7 @@ static void rtlsdr_callback(unsigned char *iq_buf, uint32_t len, void *ctx) {
|
|||
case OOK_PULSE_PWM_RAW:
|
||||
case OOK_PULSE_PWM_TERNARY:
|
||||
case OOK_PULSE_MANCHESTER_ZEROBIT:
|
||||
case OOK_PULSE_CLOCK_BITS:
|
||||
break;
|
||||
case FSK_PULSE_PCM:
|
||||
pulse_demod_pcm(&demod->fsk_pulse_data, demod->r_devs[i]);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue