Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow the message timeout value to be set at run-time. #294

Merged
merged 1 commit into from
Aug 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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