diff --git a/.gitignore b/.gitignore
index e65b455d37175fea3a23b738210eb01d59537980..2b887021851aeec6774761e894d1304d4dd90cb7 100644
Binary files a/.gitignore and b/.gitignore differ
diff --git a/Vaillant_decode_bitstuff.c b/Vaillant_decode_bitstuff.c
new file mode 100644
index 0000000000000000000000000000000000000000..321a89e83227ab2446dcc2631356e0deee8bad0b
--- /dev/null
+++ b/Vaillant_decode_bitstuff.c
@@ -0,0 +1,138 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+#include <math.h>
+
+// Vaillant_decode_bitstuff.c Copyright 2017 Reinhold Kainhofer
+// License: GNU GPL 3.0
+// 
+//
+// Compile with:
+//     gcc Vaillant_decode_bitstuff.c -o Vaillant_decode_bitstuff
+// 
+// Reads a string of 0 and 1 from STDIN, tries to decode it as Vaillant-encoded
+// applies bit-unstaffing (i.e. if 5 consecutive one bits are followed by a 
+// zero bit, the zero bit is discarded and prints the converted result to 
+// STDOUT (prefixed with current date/time).
+// Decoding errors (i.e. no amplitude switch at the pulse mid-point) are
+// indicated by a ?
+//
+// This app is purely pipe-through, i.e. its usage is:
+//
+//     cat signalfile.txt | Vaillant_decode_bitstuff > decoded_signalfile.txt
+//
+// To process an output file while it is still written to, you can use tail. This 
+// will print the proper timestamps for the signals:
+//
+//     tail -n +1 -f signalfile.txt | ./Vaillant_decode_bitstuff
+
+typedef int bool;
+#define true 1
+#define false 0
+
+void main(int argc, char *argv[])
+{
+	setbuf(stdout, NULL);
+
+	bool insideZeroes = true;
+	int zeroes = 0;
+	
+	int ones = 0; // Count the number of consecutive ones in the output (for bit-unstuffing)
+	int pos = 0;  // Current output count in octet (to space bytes)
+	
+	int validPos = 0;
+	int comment = 0;
+
+	char ch, prev;
+	while(read(STDIN_FILENO, &ch, 1) > 0) {
+		// Everything starting with # is a comment until the end of line
+		if (ch == '#') {
+			comment = true;
+			if (!insideZeroes) printf("\n");
+			insideZeroes = 1;
+			continue;
+		}
+		// Ignore all line breaks and spaces (so output can be formatted before running through this app):
+		if (ch == '\n' || ch == '\r') {
+			comment = false;
+			continue;
+		}
+		// Ignore all spaces (so output can be formatted before running through this app) and comments:
+		if (comment || ch == ' ') {
+			continue;
+		}
+
+		// Keep track of how many zeroes we have (count at most up to 1000!)
+		if (ch == '0') {
+			if (zeroes++ > 1000) zeroes = 1000;
+		} else {
+			zeroes = 0;
+		}
+		// We have zeroes, so jump to the next char if we have another 0, reset otherwise
+		if (insideZeroes) {
+			if (ch == '0') {
+				prev = ch;
+				continue;
+			} else {
+				insideZeroes = false;
+				validPos = 0;
+				// A '1' after a long sequence of '0' means some kind of signal
+				// (valid or invalid), so print the current date/time to start
+				// a new line:
+				struct timeval  tv;
+				gettimeofday(&tv, NULL);
+				int millisec = tv.tv_usec/1000;
+
+				char fmt[64], s[64];
+				struct tm       *tm;
+				if((tm = localtime(&tv.tv_sec)) != NULL) {
+					strftime(fmt, sizeof fmt, "%F %T", tm);
+					snprintf(s, sizeof s, "%s.%03d", fmt, millisec);
+					printf("%s  ", s); 
+				}
+			}
+		}
+		if (ch != '0' && ch != '1') {
+			fwrite(&ch, 1, 1, stdout);
+		}
+		
+		// Inside the pulse => if state changed, it's a 1, if it stayed, it's a 0
+		if (validPos == 1) {
+			// bit-unstuffing: Ignore a 0 after exactly five consecutive 1 bits:
+			if (ch != prev) { // a transition indicates a one
+				ones++;
+				printf("1");
+				pos++;
+			} else { // no transition indicates a zero
+				if (ones!=5) {
+					printf("0");
+					pos++;
+				}
+				ones = 0;
+			}
+		} else { // validPos == 0
+			// If 0/1 does not change => INVALID, unless it stays 0, which indicates end of signal
+			if (ch == prev) {
+				if (ch == '0') {
+					insideZeroes = true;
+					zeroes = true;
+					printf("\n");
+					pos = 0;
+				} else {
+					printf("?");
+					pos++;
+				}
+			}
+		}
+		if (pos == 8) { // A full byte was printed, so add a space
+			pos = 0;
+			printf(" ");
+		}
+		// Switch validPos:
+		validPos = (validPos + 1) % 2;
+		prev = ch;
+	}
+	printf("\r\n");
+}