From 712f97e4ef6c83dca019b8d9c37a9a150a916e56 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 7 Dec 2015 14:31:01 +0000 Subject: [PATCH] Add heuristic for detecting RFM01-framed FSK --- src/pulse_detect.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/pulse_detect.c b/src/pulse_detect.c index 85aa3ed2..c9b58307 100644 --- a/src/pulse_detect.c +++ b/src/pulse_detect.c @@ -335,6 +335,40 @@ void histogram_print(const histogram_t *hist) { #define TOLERANCE (0.2) // 20% tolerance should still discern between the pulse widths: 0.33, 0.66, 1.0 +// Detecting the RFM01/Si4320 framed FSK is non-trivial so do it in a separate function +static int detect_framed_fsk(histogram_t *hist_pulses, histogram_t *hist_gaps, pulse_data_t *data) +{ + unsigned halfbit; + + // It is theoretically possible for a valid data packet to contain + // no double-halfbit pulses, or no single-halfbit pulses, if the + // packet is either *all* zeroes or repeated 010101, respectively. + // As long the actual devices decoders *will* work for this unlikely + // case, it's probably OK for the heuristic not to guess it. This + // function is fun enough already without coping with that... + if (hist_pulses->bins_count < 3 || hist_gaps->bins_count < 3) + return 0; + + // We use the gaps not the pulses because we *consistently* see + // a misdetected pulse of a few (5 or 6) samples, after a frame + // ends with a low frequency (i.e. last data bit is a 0). See + // discussion in Issue #218. + halfbit = min(hist_gaps->bins[0].mean, hist_gaps->bins[1].mean); + + // Start of frame must be 3 halfbits high, followed by 3 or 4 low. + if (data->pulse[0] < halfbit * 5/2 || data->pulse[0] > halfbit * 7/2 || + data->gap[0] < halfbit * 5/2 || data->gap[0] > halfbit * 9/2) + return 0; + + // We could do a lot here, to the extent of a full decoding to check + // the framing. That doesn't seem necessary, as long as we don't have + // too many false positives. This is just a heuristic, after all. + if (hist_gaps->bins[2].mean < halfbit * 5/2) + return 0; + + return 1; +} + /// Analyze the statistics of a pulse data structure and print result void pulse_analyzer(pulse_data_t *data) { @@ -400,6 +434,12 @@ void pulse_analyzer(pulse_data_t *data) device.short_limit = min(hist_pulses.bins[0].mean, hist_pulses.bins[1].mean); // Assume shortest pulse is half period device.long_limit = 0; // Not used device.reset_limit = hist_gaps.bins[hist_gaps.bins_count-1].max + 1; // Set limit above biggest gap + } else if(detect_framed_fsk(&hist_pulses, &hist_gaps, data)) { + fprintf(stderr, "RFM Framed Manchester coding\n"); + device.modulation = FSK_PULSE_MANCHESTER_FRAMED; + device.short_limit = min(hist_gaps.bins[0].mean, hist_gaps.bins[1].mean); // Assume shortest pulse is half period + device.long_limit = 0; // Not used + device.reset_limit = 0; // Not used } else if(hist_pulses.bins_count == 3) { fprintf(stderr, "Pulse Width Modulation with startbit/delimiter\n"); device.modulation = OOK_PULSE_PWM_TERNARY;