diff --git a/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/examples/IRrecvDumpV2/IRrecvDumpV2.ino
index 0ef680d40..a34aab2a1 100644
--- a/examples/IRrecvDumpV2/IRrecvDumpV2.ino
+++ b/examples/IRrecvDumpV2/IRrecvDumpV2.ino
@@ -24,7 +24,14 @@ uint16_t RECV_PIN = 14;
 // than normal buffer so we can handle Air Conditioner remote codes.
 uint16_t CAPTURE_BUFFER_SIZE = 1024;
 
-IRrecv irrecv(RECV_PIN, CAPTURE_BUFFER_SIZE);
+// Nr. of milli-Seconds of no-more-data before we consider a message ended.
+// NOTE: Don't exceed MAX_TIMEOUT_MS. Typically 130ms.
+#define TIMEOUT 15U  // Suits most messages, while not swallowing repeats.
+// #define TIMEOUT 90U  // Suits messages with big gaps like XMP-1 & some aircon
+                        // units, but can accidently swallow repeated messages
+                        // in the rawData[] output.
+
+IRrecv irrecv(RECV_PIN, CAPTURE_BUFFER_SIZE, TIMEOUT);
 
 decode_results results;  // Somewhere to store the results
 irparams_t save;         // A place to copy the interrupt state while decoding.
diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp
index e6642b77a..5451cdcc2 100644
--- a/src/IRrecv.cpp
+++ b/src/IRrecv.cpp
@@ -75,7 +75,7 @@ static void ICACHE_RAM_ATTR gpio_intr() {
 
   start = now;
   #define ONCE 0
-  os_timer_arm(&timer, TIMEOUT_MS, ONCE);
+  os_timer_arm(&timer, irparams.timeout, ONCE);
 }
 #endif  // UNIT_TEST
 
@@ -85,11 +85,16 @@ static void ICACHE_RAM_ATTR gpio_intr() {
 // Args:
 //   recvpin: GPIO pin the IR receiver module's data pin is connected to.
 //   bufsize: Nr. of entries to have in the capture buffer. (Default: RAWBUF)
+//   timeout: Nr. of milli-Seconds of no signal before we stop capturing data.
+//            (Default: TIMEOUT_MS)
 // Returns:
 //   A IRrecv class object.
-IRrecv::IRrecv(uint16_t recvpin, uint16_t bufsize) {
+IRrecv::IRrecv(uint16_t recvpin, uint16_t bufsize, uint8_t timeout) {
   irparams.recvpin = recvpin;
   irparams.bufsize = bufsize;
+  // Ensure we are going to be able to store all possible values in the
+  // capture buffer.
+  irparams.timeout = std::min(timeout, (uint8_t) MAX_TIMEOUT_MS);
   irparams.rawbuf = new uint16_t[bufsize];
   if (irparams.rawbuf == NULL) {
 #ifndef UNIT_TEST
@@ -427,16 +432,16 @@ bool IRrecv::matchAtLeast(uint32_t measured, uint32_t desired,
   DPRINT(". Matching: ");
   DPRINT(measured);
   DPRINT(" >= ");
-  DPRINT(ticksLow(std::min(desired, TIMEOUT_MS * 1000), tolerance));
+  DPRINT(ticksLow(std::min(desired, MS_TO_USEC(irparams.timeout)), tolerance));
   DPRINT(" [min(");
   DPRINT(ticksLow(desired, tolerance));
   DPRINT(", ");
-  DPRINT(ticksLow(TIMEOUT_MS * 1000, tolerance));
+  DPRINT(ticksLow(MS_TO_USEC(irparams.timeout), tolerance));
   DPRINTLN(")]");
   // We really should never get a value of 0, except as the last value
   // in the buffer. If that is the case, then assume infinity and return true.
   if (measured == 0) return true;
-  return measured >= ticksLow(std::min(desired, TIMEOUT_MS * 1000),
+  return measured >= ticksLow(std::min(desired, MS_TO_USEC(irparams.timeout)),
                               tolerance);
 }
 
diff --git a/src/IRrecv.h b/src/IRrecv.h
index ad4ee45d7..5847dade3 100644
--- a/src/IRrecv.h
+++ b/src/IRrecv.h
@@ -18,6 +18,7 @@
 #define HEADER         2U  // Usual nr. of header entries.
 #define FOOTER         2U  // Usual nr. of footer (stop bits) entries.
 #define OFFSET_START   1U  // Usual rawbuf entry to start processing from.
+#define MS_TO_USEC(x)  (x * 1000U)  // Convert milli-Seconds to micro-Seconds.
 // Marks tend to be 100us too long, and spaces 100us too short
 // when received due to sensor lag.
 #define MARK_EXCESS   50U
@@ -31,12 +32,15 @@
 #define TOLERANCE     25U  // default percent tolerance in measurements
 #define RAWTICK        2U  // Capture tick to uSec factor.
 // How long (ms) before we give up wait for more data?
-// Don't exceed 130ms (RAWTICK * UINT16_MAX uSeconds) without a good reason.
+// Don't exceed MAX_TIMEOUT_MS without a good reason.
 // That is the capture buffers maximum value size. (UINT16_MAX / RAWTICK)
 // Typically messages/protocols tend to repeat around the 100ms timeframe,
 // thus we should timeout before that to give us some time to try to decode
 // before we need to start capturing a possible new message.
-#define TIMEOUT_MS    90U  // In MilliSeconds. (Historic default was 15ms)
+// Typically 15ms suits most applications. However, some protocols demand a
+// higher value. e.g. 90ms for XMP-1 and some aircon units.
+#define TIMEOUT_MS    15U  // In MilliSeconds.
+#define MAX_TIMEOUT_MS (RAWTICK * UINT16_MAX / MS_TO_USEC(1))
 
 // Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
 #define FNV_PRIME_32 16777619UL
@@ -54,6 +58,7 @@ typedef struct {
   // handler. Don't ask why, I don't know. It just does.
   uint16_t rawlen;              // counter of entries in rawbuf.
   uint8_t overflow;             // Buffer overflow indicator.
+  uint8_t timeout;              // Nr. of milliSeconds before we give up.
 } irparams_t;
 
 // results from a data match
@@ -82,7 +87,8 @@ class decode_results {
 // main class for receiving IR
 class IRrecv {
  public:
-  explicit IRrecv(uint16_t recvpin, uint16_t bufsize = RAWBUF);  // Constructor
+  explicit IRrecv(uint16_t recvpin, uint16_t bufsize = RAWBUF,
+                  uint8_t timeout = TIMEOUT_MS);  // Constructor
   ~IRrecv();  // Destructor
   bool decode(decode_results *results, irparams_t *save = NULL);
   void enableIRIn();