From faeba887594e2365fb83bfc423cdc2f26d812d71 Mon Sep 17 00:00:00 2001 From: Tommy Vestermark Date: Wed, 17 Jun 2015 01:09:21 +0200 Subject: [PATCH] Added a pulse analyzer function --- include/pulse_detect.h | 5 ++ src/pulse_detect.c | 114 +++++++++++++++++++++++++++++++++++++++++ src/rtl_433.c | 3 +- 3 files changed, 121 insertions(+), 1 deletion(-) diff --git a/include/pulse_detect.h b/include/pulse_detect.h index 1d45bf4e..e3bf4b23 100644 --- a/include/pulse_detect.h +++ b/include/pulse_detect.h @@ -47,5 +47,10 @@ void pulse_data_print(const pulse_data_t *data); int detect_pulse_package(const int16_t *envelope_data, uint32_t len, int16_t level_limit, pulse_data_t *pulses); +/** + * Analyze and print result + */ +void pulse_analyzer(const pulse_data_t *data); + #endif /* INCLUDE_PULSE_DETECT_H_ */ diff --git a/src/pulse_detect.c b/src/pulse_detect.c index f47bd107..967b58a6 100644 --- a/src/pulse_detect.c +++ b/src/pulse_detect.c @@ -138,4 +138,118 @@ int detect_pulse_package(const int16_t *envelope_data, uint32_t len, int16_t lev return 0; // Out of data } +#define MAX_HIST_BINS 16 + +typedef struct { + unsigned count; + unsigned sum; + unsigned mean; + unsigned min; + unsigned max; +} hist_bin_t; + +typedef struct { + unsigned bins_count; + hist_bin_t bins[MAX_HIST_BINS]; +} histogram_t; + +/** + * Generate a histogram (unsorted) + */ +void histogram_sum(const unsigned *data, unsigned len, float tolerance, histogram_t *hist) { + unsigned bin; // Iterator will be used outside for! + float t_upper = 1.0 + tolerance; + float t_lower = 1.0 - tolerance; + + for(unsigned n = 0; n < len; ++n) { + for(bin = 0; bin < hist->bins_count; ++bin) { + if((data[n] > (t_lower * hist->bins[bin].mean)) + && (data[n] < (t_upper * hist->bins[bin].mean)) + ) { + hist->bins[bin].count++; + hist->bins[bin].sum += data[n]; + hist->bins[bin].mean = hist->bins[bin].sum / hist->bins[bin].count; + hist->bins[bin].min = (data[n] < hist->bins[bin].min ? data[n] : hist->bins[bin].min); + hist->bins[bin].max = (data[n] > hist->bins[bin].max ? data[n] : hist->bins[bin].max); + break; // Match found! + } + } + // No match found? + if(bin == hist->bins_count && bin < MAX_HIST_BINS) { + hist->bins[bin].count = 1; + hist->bins[bin].sum = data[n]; + hist->bins[bin].mean = data[n]; + hist->bins[bin].min = data[n]; + hist->bins[bin].max = data[n]; + hist->bins_count++; + } // for bin + } // for data +} + + +/** + * Print a histogram + */ +void histogram_print(const histogram_t *hist) { + for(unsigned n = 0; n < hist->bins_count; ++n) { + fprintf(stderr, " [%2u] mean: %4u (%u/%u),\t count: %3u\n", n, + hist->bins[n].mean, + hist->bins[n].min, + hist->bins[n].max, + hist->bins[n].count); + } +} + + +#define TOLERANCE (0.2) // 20% tolerance should still discern between the pulse widths: 0.33, 0.66, 1.0 + +/** + * Analyze and print result + */ +void pulse_analyzer(const pulse_data_t *data) +{ + // Generate pulse period data + pulse_data_t pulse_periods = {0}; + pulse_periods.num_pulses = data->num_pulses; + for(unsigned n = 0; n < pulse_periods.num_pulses; ++n) { + pulse_periods.pulse[n] = data->pulse[n] + data->gap[n]; + } + + histogram_t hist_pulses = {0}; + histogram_t hist_gaps = {0}; + histogram_t hist_periods = {0}; + + histogram_sum(data->pulse, data->num_pulses, 0.2, &hist_pulses); + histogram_sum(data->gap, data->num_pulses-1, 0.2, &hist_gaps); // Leave out last gap (end) + histogram_sum(pulse_periods.pulse, pulse_periods.num_pulses-1, 0.1, &hist_periods); // Leave out last gap (end) + + fprintf(stderr, "\nAnalyzing pulses...\n"); + fprintf(stderr, "Total number of pulses: %u\n", data->num_pulses); + fprintf(stderr, "Pulse width distribution:\n"); + histogram_print(&hist_pulses); + fprintf(stderr, "Gap width distribution:\n"); + histogram_print(&hist_gaps); + fprintf(stderr, "Pulse period distribution:\n"); + histogram_print(&hist_periods); + + fprintf(stderr, "Guessing modulation: "); + if(data->num_pulses == 1) { + fprintf(stderr, "Single pulse detected. Probably Frequency Shift Keying or just noise...\n"); + } else if(hist_pulses.bins_count == 1 && hist_gaps.bins_count == 2 && hist_periods.bins_count == 2) { + fprintf(stderr, "Pulse Position Modulation with fixed pulse width\n"); + } else if(hist_pulses.bins_count == 2 && hist_gaps.bins_count == 2 && hist_periods.bins_count == 1) { + fprintf(stderr, "Pulse Width Modulation with fixed period\n"); + } else if(hist_pulses.bins_count == 2 && hist_gaps.bins_count == 1 && hist_periods.bins_count == 2) { + fprintf(stderr, "Pulse Width Modulation with fixed gap\n"); + } else if(hist_pulses.bins_count == 2 && hist_gaps.bins_count == 2 && hist_periods.bins_count == 3) { + fprintf(stderr, "Manchester coding\n"); + } else if(hist_pulses.bins_count == 3 && hist_gaps.bins_count == 3 && hist_periods.bins_count == 1) { + fprintf(stderr, "Pulse Width Modulation with startbit/delimiter\n"); + } else { + fprintf(stderr, "No clue...\n"); + } + + + fprintf(stderr, "\n"); +} diff --git a/src/rtl_433.c b/src/rtl_433.c index 9791bc6d..6582a070 100644 --- a/src/rtl_433.c +++ b/src/rtl_433.c @@ -944,7 +944,8 @@ static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx) { } } while(detect_pulse_package(demod->f_buf, len/2, demod->level_limit, &demod->pulse_data)) { - if(debug_output) pulse_data_print(&demod->pulse_data); +// if(debug_output) pulse_data_print(&demod->pulse_data); + if(debug_output) pulse_analyzer(&demod->pulse_data); pulse_data_clear(&demod->pulse_data); } }