Convert oil_watchman to bitbuffer_search() + bitbuffer_manchester_decode()
It turns out the framing in pulse_demod_manchester_framed() is not done by the RFM01/Si4320 modules themselves; it's device-specific. See discussion in issue #224. So convert to use FSK_PULSE_PCM and then look for the preamble/postamble, and do the Manchester decoding, in the bitbuffer domain.
This commit is contained in:
parent
ba621888ca
commit
29cda5b7f5
1 changed files with 55 additions and 28 deletions
|
@ -14,9 +14,15 @@
|
|||
#include "pulse_demod.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
// Start of frame preamble is 111000xx
|
||||
static const unsigned char preamble_pattern = 0xe0;
|
||||
|
||||
// End of frame is 00xxxxxx or 11xxxxxx depending on final data bit
|
||||
static const unsigned char postamble_pattern[2] = { 0x00, 0xc0 };
|
||||
|
||||
static int oil_watchman_callback(bitbuffer_t *bitbuffer) {
|
||||
bitrow_t *bb = bitbuffer->bb;
|
||||
uint8_t *b = bb[0];
|
||||
uint8_t *b;
|
||||
uint32_t unit_id;
|
||||
uint16_t depth = 0;
|
||||
uint16_t binding_countdown = 0;
|
||||
|
@ -25,48 +31,67 @@ static int oil_watchman_callback(bitbuffer_t *bitbuffer) {
|
|||
time_t time_now;
|
||||
char time_str[LOCAL_TIME_BUFLEN];
|
||||
data_t *data;
|
||||
|
||||
if (bitbuffer->bits_per_row[0] != 64 ||
|
||||
b[0] != 0x28 || b[7] != crc8le(b, 7, 0x31, 0))
|
||||
return 0;
|
||||
unsigned bitpos = 0;
|
||||
bitbuffer_t databits = {0};
|
||||
|
||||
time(&time_now);
|
||||
local_time_str(time_now, time_str);
|
||||
|
||||
// The unit ID changes when you rebind by holding a magnet to the
|
||||
// sensor for long enough; it seems to be time-based.
|
||||
unit_id = (b[1] << 16) | (b[2] << 8) | b[3];
|
||||
// Find a preamble with enough bits after it that it could be a complete packet
|
||||
while ((bitpos = bitbuffer_search(bitbuffer, 0, bitpos, &preamble_pattern, 6)) + 136 <=
|
||||
bitbuffer->bits_per_row[0]) {
|
||||
|
||||
// 0x01: Rebinding (magnet held to sensor)
|
||||
// 0x08: Leak/theft alarm
|
||||
flags = b[4];
|
||||
// Skip the matched preamble bits to point to the data
|
||||
bitpos += 6;
|
||||
|
||||
// Not entirely sure what this is but it might be inversely
|
||||
// proportional to temperature.
|
||||
maybetemp = b[5] >> 2;
|
||||
bitpos = bitbuffer_manchester_decode(bitbuffer, 0, bitpos, &databits, 64);
|
||||
if (databits.bits_per_row[0] != 64)
|
||||
continue;
|
||||
|
||||
if (flags & 1)
|
||||
b = databits.bb[0];
|
||||
|
||||
// Check for postamble, depending on last data bit
|
||||
if (bitbuffer_search(bitbuffer, 0, bitpos, &postamble_pattern[b[7] & 1], 2) != bitpos)
|
||||
continue;
|
||||
|
||||
if (b[0] != 0x28 || b[7] != crc8le(b, 7, 0x31, 0))
|
||||
continue;
|
||||
|
||||
// The unit ID changes when you rebind by holding a magnet to the
|
||||
// sensor for long enough; it seems to be time-based.
|
||||
unit_id = (b[1] << 16) | (b[2] << 8) | b[3];
|
||||
|
||||
// 0x01: Rebinding (magnet held to sensor)
|
||||
// 0x08: Leak/theft alarm
|
||||
// top three bits seem also to vary with temperature (independently of maybetemp)
|
||||
flags = b[4];
|
||||
|
||||
// Not entirely sure what this is but it might be inversely
|
||||
// proportional to temperature.
|
||||
maybetemp = b[5] >> 2;
|
||||
|
||||
if (flags & 1)
|
||||
// When binding, the countdown counts up from 0x51 to 0x5a
|
||||
// (as long as you hold the magnet to it for long enough)
|
||||
// before the device ID changes. The receiver unit needs
|
||||
// to receive this *strongly* in order to change its
|
||||
// allegiance.
|
||||
binding_countdown = b[6];
|
||||
else
|
||||
else
|
||||
// A depth reading of zero indicates no reading. Even with
|
||||
// the sensor flat down on a table, it still reads about 13.
|
||||
depth = b[6] | ((((uint16_t)b[5]) & 3) << 8);
|
||||
|
||||
data = data_make("time", "", DATA_STRING, time_str,
|
||||
"model", "", DATA_STRING, "Oil Watchman",
|
||||
"id", "", DATA_FORMAT, "%06x", DATA_INT, unit_id,
|
||||
"flags", "", DATA_FORMAT, "%02x", DATA_INT, flags,
|
||||
"maybetemp", "", DATA_INT, maybetemp,
|
||||
"binding_countdown", "", DATA_INT, binding_countdown,
|
||||
"depth", "", DATA_INT, depth,
|
||||
NULL);
|
||||
data_acquired_handler(data);
|
||||
|
||||
data = data_make("time", "", DATA_STRING, time_str,
|
||||
"model", "", DATA_STRING, "Oil Watchman",
|
||||
"id", "", DATA_FORMAT, "%06x", DATA_INT, unit_id,
|
||||
"flags", "", DATA_FORMAT, "%02x", DATA_INT, flags,
|
||||
"maybetemp", "", DATA_INT, maybetemp,
|
||||
"binding_countdown", "", DATA_INT, binding_countdown,
|
||||
"depth", "", DATA_INT, depth,
|
||||
NULL);
|
||||
data_acquired_handler(data);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
@ -83,8 +108,10 @@ static char *output_fields[] = {
|
|||
|
||||
r_device oil_watchman = {
|
||||
.name = "Ultrasonic oil monitor",
|
||||
.modulation = FSK_PULSE_MANCHESTER_FRAMED,
|
||||
.modulation = FSK_PULSE_PCM,
|
||||
.short_limit = 250,
|
||||
.long_limit = 250, // NRZ
|
||||
.reset_limit = 1000,
|
||||
.json_callback = &oil_watchman_callback,
|
||||
.disabled = 0,
|
||||
.fields = output_fields,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue