diff --git a/include/pulse_detect.h b/include/pulse_detect.h
index 501bd886..e82b9292 100644
--- a/include/pulse_detect.h
+++ b/include/pulse_detect.h
@@ -14,6 +14,8 @@
 #include <stdint.h>
 
 #define PD_MAX_PULSES 1000			// Maximum number of pulses before forcing End Of Package
+#define PD_MIN_PULSES 4				// Minimum number of pulses before declaring a proper package
+#define PD_MIN_PULSE_SAMPLES 10		// Minimum number of samples in a pulse for proper detection
 #define PD_MIN_GAP_MS 10			// Minimum gap size in milliseconds to exceed to declare End Of Package
 #define PD_MAX_GAP_MS 100			// Maximum gap size in milliseconds to exceed to declare End Of Package
 #define PD_MAX_GAP_RATIO 10			// Ratio gap/pulse width to exceed to declare End Of Package (heuristic)
@@ -43,14 +45,19 @@ void pulse_data_clear(pulse_data_t *data);		// Clear the struct
 void pulse_data_print(const pulse_data_t *data);
 
 
-/// Demodulate On/Off Keying from an envelope signal
+/// Demodulate On/Off Keying (OOK) and Frequency Shift Keying (FSK) from an envelope signal
 ///
 /// Function is stateful and can be called with chunks of input data
+/// @param envelope_data: Samples with amplitude envelope of carrier 
+/// @param fm_data: Samples with frequency offset from center frequency
+/// @param len: Number of samples in input buffers
 /// @param samp_rate: Sample rate in samples per second
 /// @param *pulses: Will return a pulse_data_t structure
-/// @return 0 if all input data is processed
-/// @return 1 if package is detected (but data is still not completely processed)
-int detect_pulse_package(const int16_t *envelope_data, uint32_t len, int16_t level_limit, uint32_t samp_rate, pulse_data_t *pulses);
+/// @param *fsk_pulses: Will return a pulse_data_t structure for FSK demodulated data
+/// @return 0 if all input sample data is processed
+/// @return 1 if OOK package is detected (but all sample data is still not completely processed)
+/// @return 2 if FSK package is detected (but all sample data is still not completely processed)
+int detect_pulse_package(const int16_t *envelope_data, const int16_t *fm_data, uint32_t len, int16_t level_limit, uint32_t samp_rate, pulse_data_t *pulses, pulse_data_t *fsk_pulses);
 
 
 /// Analyze and print result
diff --git a/src/pulse_detect.c b/src/pulse_detect.c
index 7997dec8..43c42ebd 100644
--- a/src/pulse_detect.c
+++ b/src/pulse_detect.c
@@ -41,11 +41,23 @@ typedef struct {
 	unsigned int max_pulse;			// Size of biggest pulse detected
 
 	unsigned int data_counter;		// Counter for how much of data chunck is processed
+
+	unsigned int fsk_pulse_length;		// Counter for internal pulse detection
+	enum {
+		PD_STATE_FSK_HIGH	= 0,
+		PD_STATE_FSK_LOW	= 1
+	} state_fsk;
+
+	int16_t fm_base_est;			// Estimate for the FM base frequency for 
+	int16_t fm_delta_est;
+
 } pulse_state_t;
 static pulse_state_t pulse_state;
 
+#define FSK_EST_RATIO	32	// Constant for slowness of FSK estimators
+#define FSK_DEFAULT_FM_DELTA	8000	// Default estimate for frequency delta
 
-int detect_pulse_package(const int16_t *envelope_data, uint32_t len, int16_t level_limit, uint32_t samp_rate, pulse_data_t *pulses) {
+int detect_pulse_package(const int16_t *envelope_data, const int16_t *fm_data, uint32_t len, int16_t level_limit, uint32_t samp_rate, pulse_data_t *pulses, pulse_data_t *fsk_pulses) {
 	const unsigned int samples_per_ms = samp_rate / 1000;
 	const int16_t HYSTERESIS = level_limit / 8;	// ±12%
 	pulse_state_t *s = &pulse_state;
@@ -57,6 +69,10 @@ int detect_pulse_package(const int16_t *envelope_data, uint32_t len, int16_t lev
 				s->pulse_length = 0;
 				s->max_pulse = 0;
 				if (envelope_data[s->data_counter] > (level_limit + HYSTERESIS)) {
+					s->fsk_pulse_length = 0;
+					s->fm_base_est = 0;						// FM low frequency may be everywhere
+					s->fm_delta_est = FSK_DEFAULT_FM_DELTA;	// FM delta default estimate
+					s->state_fsk = PD_STATE_FSK_HIGH;		// Base frequency = high pulse
 					s->state = PD_STATE_PULSE;
 				}
 				break;
@@ -68,16 +84,54 @@ int detect_pulse_package(const int16_t *envelope_data, uint32_t len, int16_t lev
 					pulses->pulse[pulses->num_pulses] = s->pulse_length;	// Store pulse width
 					s->max_pulse = max(s->pulse_length, s->max_pulse);	// Find largest pulse
 
-					// EOP if pulse is too long
-					if (s->pulse_length > (PD_MAX_PULSE_MS * samples_per_ms)) {
-						pulses->num_pulses++;	// Store last pulse (with no gap)
+					// EOP if FSK modulation detected within pulse
+					if(fsk_pulses->num_pulses > PD_MIN_PULSES) {
+						if(s->state_fsk == PD_STATE_FSK_HIGH) {
+							fsk_pulses->pulse[fsk_pulses->num_pulses] = s->fsk_pulse_length;	// Store last pulse
+							fsk_pulses->gap[fsk_pulses->num_pulses] = 0;	// Zero gap at end
+						} else {
+							fsk_pulses->gap[fsk_pulses->num_pulses] = s->fsk_pulse_length;	// Store last gap
+						}
+						fsk_pulses->num_pulses++;
 						s->state = PD_STATE_IDLE;
-						return 1;	// End Of Package!!
+						return 2;	// Signal FSK package
+					} else {
+						fsk_pulses->num_pulses = 0;		// Clear pulses (should be more effective...)
 					}
-
 					s->pulse_length = 0;
 					s->state = PD_STATE_GAP;
-				}
+				} else {
+					// FSK demodulation is only relevant when a carrier is present
+					s->fsk_pulse_length++;
+					int16_t fm_n = fm_data[s->data_counter];		// Get current FM sample
+					int16_t fm_delta = abs(fm_n - s->fm_base_est);	// Get delta from base frequency estimate
+					switch(s->state_fsk) {
+						case PD_STATE_FSK_HIGH:
+							if (s->pulse_length < PD_MIN_PULSE_SAMPLES) {		// Initial samples in OOK pulse?
+								s->fm_base_est = s->fm_base_est - s->fm_base_est/2 + fm_n/2;	// Quick initial estimator
+							} else if (fm_delta < s->fm_delta_est/2) {		// Freq offset below delta threshold?
+								s->fm_base_est = s->fm_base_est - s->fm_base_est/FSK_EST_RATIO + fm_n/FSK_EST_RATIO;	// Slow estimator
+							} else {	// Above threshold
+								fsk_pulses->pulse[fsk_pulses->num_pulses] = s->fsk_pulse_length;	// Store pulse width
+								s->fsk_pulse_length = 0;
+								s->state_fsk = PD_STATE_FSK_LOW;
+							}
+							break;
+						case PD_STATE_FSK_LOW:
+							if (fm_delta > s->fm_delta_est/2) {		// Freq offset above delta threshold?
+								s->fm_delta_est = s->fm_delta_est - s->fm_delta_est/FSK_EST_RATIO + fm_delta/FSK_EST_RATIO;	// Slow estimator
+							} else {	// Below threshold
+								fsk_pulses->gap[fsk_pulses->num_pulses] = s->fsk_pulse_length;	// Store gap width
+								fsk_pulses->num_pulses++;
+								s->fsk_pulse_length = 0;
+								s->state_fsk = PD_STATE_FSK_HIGH;
+							}
+							break;
+						default:
+							fprintf(stderr, "pulse_demod(): Unknown FSK state!!\n");
+							s->state_fsk = PD_STATE_FSK_HIGH;
+					} // switch(s->state_fsk)
+				} // if
 				break;
 			case PD_STATE_GAP:
 				s->pulse_length++;
@@ -93,6 +147,10 @@ int detect_pulse_package(const int16_t *envelope_data, uint32_t len, int16_t lev
 					}
 
 					s->pulse_length = 0;
+					s->fsk_pulse_length = 0;
+					s->fm_base_est = 0;						// FM low frequency may be everywhere
+					s->fm_delta_est = FSK_DEFAULT_FM_DELTA;	// FM delta default estimate
+					s->state_fsk = PD_STATE_FSK_HIGH;		// Base frequency = high pulse
 					s->state = PD_STATE_PULSE;
 				}
 
diff --git a/src/rtl_433.c b/src/rtl_433.c
index ea19a163..fda4cbf3 100644
--- a/src/rtl_433.c
+++ b/src/rtl_433.c
@@ -64,6 +64,7 @@ struct dm_state {
     struct protocol_state *r_devs[MAX_PROTOCOLS];
 
 	pulse_data_t	pulse_data;
+	pulse_data_t	fsk_pulse_data;
 };
 
 void usage(r_device *devices) {
@@ -667,35 +668,48 @@ static void rtlsdr_callback(unsigned char *iq_buf, uint32_t len, void *ctx) {
 			}
 		}
 		// Detect a package and loop through demodulators with pulse data
-		while(detect_pulse_package(demod->am_buf, len/2, demod->level_limit, samp_rate, &demod->pulse_data)) {
-			for (i = 0; i < demod->r_dev_num; i++) {
-				switch (demod->r_devs[i]->modulation) {
-					// Old style decoders
-					case OOK_PWM_D:
-					case OOK_PWM_P:
-						break;
-					case OOK_PULSE_PCM_RZ:
-						pulse_demod_pcm_rz(&demod->pulse_data, demod->r_devs[i]);
-						break;
-					case OOK_PULSE_PPM_RAW:
-						pulse_demod_ppm(&demod->pulse_data, demod->r_devs[i]);
-						break;
-					case OOK_PULSE_PWM_RAW:
-						pulse_demod_pwm(&demod->pulse_data, demod->r_devs[i]);
-						break;
-					case OOK_PULSE_PWM_TERNARY:
-						pulse_demod_pwm_ternary(&demod->pulse_data, demod->r_devs[i]);
-						break;
-					case OOK_PULSE_MANCHESTER_ZEROBIT:
-						pulse_demod_manchester_zerobit(&demod->pulse_data, demod->r_devs[i]);
-						break;
-					default:
-						fprintf(stderr, "Unknown modulation %d in protocol!\n", demod->r_devs[i]->modulation);
-				}
-			} // for demodulators
-			if(debug_output > 1) pulse_data_print(&demod->pulse_data);
-			if(debug_output) pulse_analyzer(&demod->pulse_data);
-			pulse_data_clear(&demod->pulse_data);
+		int package_type = 1;	// Just to get us started
+		while(package_type) {
+			package_type = detect_pulse_package(demod->am_buf, demod->fm_buf, len/2, demod->level_limit, samp_rate, &demod->pulse_data, &demod->fsk_pulse_data);
+			if (package_type == 1) {
+				if(debug_output) fprintf(stderr, "Detected OOK package\n");
+				for (i = 0; i < demod->r_dev_num; i++) {
+					switch (demod->r_devs[i]->modulation) {
+						// Old style decoders
+						case OOK_PWM_D:
+						case OOK_PWM_P:
+							break;
+						case OOK_PULSE_PCM_RZ:
+							pulse_demod_pcm_rz(&demod->pulse_data, demod->r_devs[i]);
+							break;
+						case OOK_PULSE_PPM_RAW:
+							pulse_demod_ppm(&demod->pulse_data, demod->r_devs[i]);
+							break;
+						case OOK_PULSE_PWM_RAW:
+							pulse_demod_pwm(&demod->pulse_data, demod->r_devs[i]);
+							break;
+						case OOK_PULSE_PWM_TERNARY:
+							pulse_demod_pwm_ternary(&demod->pulse_data, demod->r_devs[i]);
+							break;
+						case OOK_PULSE_MANCHESTER_ZEROBIT:
+							pulse_demod_manchester_zerobit(&demod->pulse_data, demod->r_devs[i]);
+							break;
+						default:
+							fprintf(stderr, "Unknown modulation %d in protocol!\n", demod->r_devs[i]->modulation);
+					}
+				} // for demodulators
+				if(debug_output > 1) pulse_data_print(&demod->pulse_data);
+				if(debug_output) pulse_analyzer(&demod->pulse_data);
+				pulse_data_clear(&demod->pulse_data);
+				pulse_data_clear(&demod->fsk_pulse_data);
+			} else if (package_type == 2) {
+				if(debug_output) fprintf(stderr, "Detected FSK package\n");
+				if(debug_output > 1) pulse_data_print(&demod->fsk_pulse_data);
+				if(debug_output) pulse_analyzer(&demod->fsk_pulse_data);
+				pulse_data_clear(&demod->pulse_data);
+				pulse_data_clear(&demod->fsk_pulse_data);
+			}
+
 		}
 	}
 
@@ -767,6 +781,7 @@ int main(int argc, char **argv) {
 
     demod->level_limit = DEFAULT_LEVEL_LIMIT;
     pulse_data_clear(&demod->pulse_data);
+    pulse_data_clear(&demod->fsk_pulse_data);
 
     while ((opt = getopt(argc, argv, "x:z:p:Dtam:r:c:l:d:f:g:s:b:n:SR:")) != -1) {
         switch (opt) {