2 * Pulse demodulation functions
4 * Binary demodulators (PWM/PPM/Manchester/...) using a pulse data structure as input
6 * Copyright (C) 2015 Tommy Vestermark
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
13 #include "pulse_demod.h"
14 #include "bitbuffer.h"
21 int pulse_demod_pcm(const pulse_data_t *pulses, struct protocol_state *device)
24 bitbuffer_t bits = {0};
25 const int MAX_ZEROS = device->reset_limit / device->long_limit;
26 const int TOLERANCE = device->long_limit / 4; // Tolerance is ±25% of a bit period
28 for(unsigned n = 0; n < pulses->num_pulses; ++n) {
29 // Determine number of high bit periods for NRZ coding, where bits may not be separated
30 int highs = (pulses->pulse[n] + device->short_limit/2) / device->short_limit;
31 // Determine number of bit periods in current pulse/gap length (rounded)
32 int periods = (pulses->pulse[n] + pulses->gap[n] + device->long_limit/2) / device->long_limit;
34 // Add run of ones (1 for RZ, many for NRZ)
35 for (int i=0; i < highs; ++i) {
36 bitbuffer_add_bit(&bits, 1);
39 periods -= highs; // Remove 1s from whole period
40 periods = min(periods, MAX_ZEROS); // Dont overflow at end of message
41 for (int i=0; i < periods; ++i) {
42 bitbuffer_add_bit(&bits, 0);
46 if ((device->short_limit != device->long_limit) // Only for RZ coding
47 && (fabsf(pulses->pulse[n] - device->short_limit) > TOLERANCE) // Pulse must be within tolerance
50 if (debug_output > 3) {
51 fprintf(stderr,"bitbuffer cleared at %d: pulse %d, gap %d, period %d\n",
52 n,pulses->pulse[n],pulses->gap[n],
53 pulses->pulse[n] + pulses->gap[n]);
55 bitbuffer_clear(&bits);
59 if (((n == pulses->num_pulses-1) // No more pulses? (FSK)
60 || (pulses->gap[n] > device->reset_limit)) // Loong silence (OOK)
61 && (bits.bits_per_row[0] > 0) // Only if data has been accumulated
63 if (device->callback) {
64 events += device->callback(&bits);
67 if(!device->callback || (debug_output && events > 0)) {
68 fprintf(stderr, "pulse_demod_pcm(): %s \n", device->name);
69 bitbuffer_print(&bits);
71 bitbuffer_clear(&bits);
78 int pulse_demod_ppm(const pulse_data_t *pulses, struct protocol_state *device) {
80 bitbuffer_t bits = {0};
82 for(unsigned n = 0; n < pulses->num_pulses; ++n) {
84 if(pulses->gap[n] < device->short_limit) {
85 bitbuffer_add_bit(&bits, 0);
87 } else if(pulses->gap[n] < device->long_limit) {
88 bitbuffer_add_bit(&bits, 1);
89 // Check for new packet in multipacket
90 } else if(pulses->gap[n] < device->reset_limit) {
91 bitbuffer_add_row(&bits);
94 if (device->callback) {
95 events += device->callback(&bits);
98 if(!device->callback || (debug_output && events > 0)) {
99 fprintf(stderr, "pulse_demod_ppm(): %s \n", device->name);
100 bitbuffer_print(&bits);
102 bitbuffer_clear(&bits);
109 int pulse_demod_pwm(const pulse_data_t *pulses, struct protocol_state *device) {
111 int start_bit_detected = 0;
112 bitbuffer_t bits = {0};
113 int start_bit = device->demod_arg;
115 for(unsigned n = 0; n < pulses->num_pulses; ++n) {
116 // Should we disregard startbit?
117 if(start_bit == 1 && start_bit_detected == 0) {
118 start_bit_detected = 1;
120 // Detect pulse width
121 if(pulses->pulse[n] <= device->short_limit) {
122 bitbuffer_add_bit(&bits, 1);
124 bitbuffer_add_bit(&bits, 0);
128 if (n == pulses->num_pulses - 1 // No more pulses (FSK)
129 || pulses->gap[n] > device->reset_limit) { // Long silence (OOK)
130 if (device->callback) {
131 events += device->callback(&bits);
134 if(!device->callback || (debug_output && events > 0)) {
135 fprintf(stderr, "pulse_demod_pwm(): %s\n", device->name);
136 bitbuffer_print(&bits);
138 bitbuffer_clear(&bits);
139 start_bit_detected = 0;
140 // Check for new packet in multipacket
141 } else if(pulses->gap[n] > device->long_limit) {
142 bitbuffer_add_row(&bits);
143 start_bit_detected = 0;
150 int pulse_demod_pwm_precise(const pulse_data_t *pulses, struct protocol_state *device)
153 bitbuffer_t bits = {0};
154 PWM_Precise_Parameters *p = (PWM_Precise_Parameters *)device->demod_arg;
156 for(unsigned n = 0; n < pulses->num_pulses; ++n) {
158 if (fabsf(pulses->pulse[n] - device->short_limit) < p->pulse_tolerance) {
159 bitbuffer_add_bit(&bits, 1);
161 } else if (fabsf(pulses->pulse[n] - device->long_limit) < p->pulse_tolerance) {
162 bitbuffer_add_bit(&bits, 0);
164 } else if (p->pulse_sync_width && (fabsf(pulses->pulse[n] - p->pulse_sync_width) < p->pulse_tolerance)) {
165 bitbuffer_add_row(&bits);
166 // Ignore spurious short pulses
167 } else if (pulses->pulse[n] < (device->short_limit - p->pulse_tolerance)) {
170 return 0; // Pulse outside specified timing
174 if(pulses->gap[n] > device->reset_limit) {
175 if (device->callback) {
176 events += device->callback(&bits);
179 if(!device->callback || (debug_output && events > 0)) {
180 fprintf(stderr, "pulse_demod_pwm_precise(): %s \n", device->name);
181 bitbuffer_print(&bits);
183 bitbuffer_clear(&bits);
190 int pulse_demod_pwm_ternary(const pulse_data_t *pulses, struct protocol_state *device)
193 bitbuffer_t bits = {0};
194 unsigned sync_bit = device->demod_arg;
196 for(unsigned n = 0; n < pulses->num_pulses; ++n) {
198 if (pulses->pulse[n] < device->short_limit) {
200 bitbuffer_add_row(&bits);
202 bitbuffer_add_bit(&bits, 0);
205 } else if (pulses->pulse[n] < device->long_limit) {
207 bitbuffer_add_bit(&bits, 0);
208 } else if (sync_bit == 1) {
209 bitbuffer_add_row(&bits);
211 bitbuffer_add_bit(&bits, 1);
216 bitbuffer_add_row(&bits);
218 bitbuffer_add_bit(&bits, 1);
223 if(pulses->gap[n] > device->reset_limit) {
224 if (device->callback) {
225 events += device->callback(&bits);
228 if(!device->callback || (debug_output && events > 0)) {
229 fprintf(stderr, "pulse_demod_pwm_ternary(): %s \n", device->name);
230 bitbuffer_print(&bits);
232 bitbuffer_clear(&bits);
239 int pulse_demod_manchester_zerobit(const pulse_data_t *pulses, struct protocol_state *device) {
241 int time_since_last = 0;
242 bitbuffer_t bits = {0};
244 // First rising edge is allways counted as a zero (Seems to be hardcoded policy for the Oregon Scientific sensors...)
245 bitbuffer_add_bit(&bits, 0);
247 for(unsigned n = 0; n < pulses->num_pulses; ++n) {
248 // Falling edge is on end of pulse
249 if(pulses->pulse[n] + time_since_last > (device->short_limit * 1.5)) {
250 // Last bit was recorded more than short_limit*1.5 samples ago
251 // so this pulse start must be a data edge (falling data edge means bit = 1)
252 bitbuffer_add_bit(&bits, 1);
255 time_since_last += pulses->pulse[n];
259 if(pulses->gap[n] > device->reset_limit) {
261 if (device->callback) {
262 events += device->callback(&bits);
265 if(!device->callback || (debug_output && events > 0)) {
266 fprintf(stderr, "pulse_demod_manchester_zerobit(): %s \n", device->name);
267 bitbuffer_print(&bits);
269 bitbuffer_clear(&bits);
270 bitbuffer_add_bit(&bits, 0); // Prepare for new message with hardcoded 0
272 // Rising edge is on end of gap
273 } else if(pulses->gap[n] + time_since_last > (device->short_limit * 1.5)) {
274 // Last bit was recorded more than short_limit*1.5 samples ago
275 // so this pulse end is a data edge (rising data edge means bit = 0)
276 bitbuffer_add_bit(&bits, 0);
279 time_since_last += pulses->gap[n];
285 int pulse_demod_clock_bits(const pulse_data_t *pulses, struct protocol_state *device) {
286 int symbol[PD_MAX_PULSES * 2];
289 PWM_Precise_Parameters *p = (PWM_Precise_Parameters *)device->demod_arg;
290 bitbuffer_t bits = {0};
293 for(n = 0; n < pulses->num_pulses; n++) {
294 symbol[n*2] = pulses->pulse[n];
295 symbol[(n*2)+1] = pulses->gap[n];
298 for(n = 0; n < pulses->num_pulses * 2; ++n) {
299 if ( fabsf(symbol[n] - device->short_limit) < p->pulse_tolerance) {
301 bitbuffer_add_bit(&bits, 1);
302 if ( fabsf(symbol[++n] - device->short_limit) > p->pulse_tolerance) {
303 if (symbol[n] >= device->reset_limit - p->pulse_tolerance ) {
304 // Don't expect another short gap at end of message
308 fprintf(stderr, "Detected error during pulse_demod_clock_bits(): %s\n",
314 } else if ( fabsf(symbol[n] - device->long_limit) < p->pulse_tolerance) {
316 bitbuffer_add_bit(&bits, 0);
317 } else if (symbol[n] >= device->reset_limit - p->pulse_tolerance ) {
319 if (device->callback) {
320 events += device->callback(&bits);
322 if(!device->callback || (debug_output && events > 0)) {
323 fprintf(stderr, "pulse_demod_clock_bits(): %s \n", device->name);
324 bitbuffer_print(&bits);
326 bitbuffer_clear(&bits);
334 * Oregon Scientific V1 Protocol
335 * Starts with a clean preamble of 12 pulses with
336 * consistent timing followed by an out of time Sync pulse.
337 * Data then follows with manchester encoding, but
338 * care must be taken with the gap after the sync pulse since it
339 * is outside of the normal clocking. Because of this a data stream
340 * beginning with a 0 will have data in this gap.
341 * This code looks at pulse and gap width and clocks bits
342 * in from this. Since this is manchester encoded every other
346 int pulse_demod_osv1(const pulse_data_t *pulses, struct protocol_state *device) {
351 bitbuffer_t bits = {0};
354 for(n = 0; n < pulses->num_pulses; ++n) {
355 if(pulses->pulse[n] >= 350 && pulses->gap[n] >= 200) {
357 if(pulses->gap[n] >= 400)
363 if(debug_output) fprintf(stderr, "preamble %d %d %d\n", preamble, pulses->pulse[0], pulses->gap[0]);
369 if(pulses->pulse[n] < 1000 || pulses->gap[n] < 1000) {
373 /* data bits - manchester encoding */
375 /* sync gap could be part of data when the first bit is 0 */
376 if(pulses->gap[n] > pulses->pulse[n]) {
378 if(manbit) bitbuffer_add_bit(&bits, 0);
381 /* remaining data bits */
382 for(n++; n < pulses->num_pulses; ++n) {
384 if(manbit) bitbuffer_add_bit(&bits, 1);
385 if(pulses->pulse[n] > 615) {
387 if(manbit) bitbuffer_add_bit(&bits, 1);
389 if (n == pulses->num_pulses - 1 || pulses->gap[n] > device->reset_limit) {
390 if((bits.bits_per_row[bits.num_rows-1] == 32) && device->callback) {
391 events += device->callback(&bits);
396 if(manbit) bitbuffer_add_bit(&bits, 0);
397 if(pulses->gap[n] > 450) {
399 if(manbit) bitbuffer_add_bit(&bits, 0);