Skip to content

Commit

Permalink
Allow the message timeout value to be set at run-time.
Browse files Browse the repository at this point in the history
Ensure the timeout value won't allow a value larger than we can store.
  • Loading branch information
crankyoldgit committed Aug 5, 2017
1 parent 8dd05c0 commit 48168c2
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 9 deletions.
9 changes: 8 additions & 1 deletion examples/IRrecvDumpV2/IRrecvDumpV2.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
15 changes: 10 additions & 5 deletions src/IRrecv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -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);
}

Expand Down
12 changes: 9 additions & 3 deletions src/IRrecv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 48168c2

Please sign in to comment.