Skip to content

Commit

Permalink
Remove the use of USECPERTICKs from the library.
Browse files Browse the repository at this point in the history
Store and measure everything in usecs to similify things and improve timing accuracy.
Reduce excess to 50us from 100us.
Adjustments to RC-MM decoding to handle small measurements better.
Remove calcTick(s) as it is pretty redundant now.
  • Loading branch information
crankyoldgit committed Jul 26, 2017
1 parent 6bb9b59 commit dce5e6c
Show file tree
Hide file tree
Showing 21 changed files with 99 additions and 129 deletions.
4 changes: 2 additions & 2 deletions examples/IRrecvDump/IRrecvDump.ino
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ void dump(decode_results *results) {
if (i % 100 == 0)
yield(); // Preemptive yield every 100th entry to feed the WDT.
if (i & 1) {
Serial.print(results->rawbuf[i] * USECPERTICK, DEC);
Serial.print(results->rawbuf[i], DEC);
} else {
Serial.write('-');
Serial.print((uint32_t) results->rawbuf[i] * USECPERTICK, DEC);
Serial.print((uint32_t) results->rawbuf[i], DEC);
}
Serial.print(" ");
}
Expand Down
4 changes: 2 additions & 2 deletions examples/IRrecvDumpV2/IRrecvDumpV2.ino
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ void dumpRaw(decode_results *results) {
for (uint16_t i = 1; i < results->rawlen; i++) {
if (i % 100 == 0)
yield(); // Preemptive yield every 100th entry to feed the WDT.
uint32_t x = results->rawbuf[i] * USECPERTICK;
uint32_t x = results->rawbuf[i];
if (!(i & 1)) { // even
Serial.print("-");
if (x < 1000) Serial.print(" ");
Expand Down Expand Up @@ -127,7 +127,7 @@ void dumpCode(decode_results *results) {

// Dump data
for (uint16_t i = 1; i < results->rawlen; i++) {
Serial.print(results->rawbuf[i] * USECPERTICK, DEC);
Serial.print(results->rawbuf[i], DEC);
if (i < results->rawlen - 1)
Serial.print(","); // ',' not needed on last one
if (!(i & 1)) Serial.print(" ");
Expand Down
83 changes: 43 additions & 40 deletions src/IRrecv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ static void ICACHE_RAM_ATTR gpio_intr() {
irparams.rawbuf[rawlen] = 1;
} else {
if (now < start)
irparams.rawbuf[rawlen] = (0xFFFFFFFF - start + now) / USECPERTICK + 1;
irparams.rawbuf[rawlen] = 0xFFFFFFFF - start + now;
else
irparams.rawbuf[rawlen] = (now - start) / USECPERTICK + 1;
irparams.rawbuf[rawlen] = now - start;
}
irparams.rawlen++;

Expand Down Expand Up @@ -349,8 +349,7 @@ bool IRrecv::decode(decode_results *results, irparams_t *save) {
// Nr. of ticks.
uint32_t IRrecv::ticksLow(uint32_t usecs, uint8_t tolerance) {
// max() used to ensure the result can't drop below 0 before the cast.
return((uint32_t) std::max((int32_t) (
usecs * (1.0 - tolerance/100.0) / USECPERTICK), 0));
return((uint32_t) std::max((int32_t) (usecs * (1.0 - tolerance / 100.0)), 0));
}

// Calculate the upper bound of the nr. of ticks.
Expand All @@ -361,104 +360,108 @@ uint32_t IRrecv::ticksLow(uint32_t usecs, uint8_t tolerance) {
// Returns:
// Nr. of ticks.
uint32_t IRrecv::ticksHigh(uint32_t usecs, uint8_t tolerance) {
return((uint32_t) usecs * (1.0 + tolerance/100.0) / USECPERTICK + 1);
return((uint32_t) (usecs * (1.0 + tolerance / 100.0)) + 1);
}

// Check if we match a pulse(measured_ticks) with the desired_us within
// Check if we match a pulse(measured) with the desired within
// +/-tolerance percent.
//
// Args:
// measured_ticks: The recorded period of the signal pulse.
// desired_us: The expected period (in useconds) we are matching against.
// measured: The recorded period of the signal pulse.
// desired: The expected period (in useconds) we are matching against.
// tolerance: A percentage expressed as an integer. e.g. 10 is 10%.
//
// Returns:
// Boolean: true if it matches, false if it doesn't.
bool IRrecv::match(uint32_t measured_ticks, uint32_t desired_us,
bool IRrecv::match(uint32_t measured, uint32_t desired,
uint8_t tolerance) {
DPRINT("Matching: ");
DPRINT(ticksLow(desired_us, tolerance));
DPRINT(ticksLow(desired, tolerance));
DPRINT(" <= ");
DPRINT(measured_ticks);
DPRINT(measured);
DPRINT(" <= ");
DPRINTLN(ticksHigh(desired_us, tolerance));
return (measured_ticks >= ticksLow(desired_us, tolerance) &&
measured_ticks <= ticksHigh(desired_us, tolerance));
DPRINTLN(ticksHigh(desired, tolerance));
return (measured >= ticksLow(desired, tolerance) &&
measured <= ticksHigh(desired, tolerance));
}


// Check if we match a pulse(measured_ticks) of at least desired_us within
// Check if we match a pulse(measured) of at least desired within
// +/-tolerance percent.
//
// Args:
// measured_ticks: The recorded period of the signal pulse.
// desired_us: The expected period (in useconds) we are matching against.
// measured: The recorded period of the signal pulse.
// desired: The expected period (in useconds) we are matching against.
// tolerance: A percentage expressed as an integer. e.g. 10 is 10%.
//
// Returns:
// Boolean: true if it matches, false if it doesn't.
bool IRrecv::matchAtLeast(uint32_t measured_ticks, uint32_t desired_us,
bool IRrecv::matchAtLeast(uint32_t measured, uint32_t desired,
uint8_t tolerance) {
DPRINT("Matching ATLEAST ");
DPRINT(measured_ticks * USECPERTICK);
DPRINT(measured);
DPRINT(" vs ");
DPRINT(desired_us);
DPRINT(desired);
DPRINT(". Matching: ");
DPRINT(measured_ticks);
DPRINT(measured);
DPRINT(" >= ");
DPRINT(ticksLow(std::min(desired_us, TIMEOUT_MS * 1000), tolerance));
DPRINT(ticksLow(std::min(desired, TIMEOUT_MS * 1000), tolerance));
DPRINT(" [min(");
DPRINT(ticksLow(desired_us, tolerance));
DPRINT(ticksLow(desired, tolerance));
DPRINT(", ");
DPRINT(ticksLow(TIMEOUT_MS * 1000, 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_ticks == 0) return true;
return measured_ticks >= ticksLow(std::min(desired_us, TIMEOUT_MS * 1000),
tolerance);
if (measured == 0) return true;
return measured >= ticksLow(std::min(desired, TIMEOUT_MS * 1000),
tolerance);
}

// Check if we match a mark signal(measured_ticks) with the desired_us within
// Check if we match a mark signal(measured) with the desired within
// +/-tolerance percent, after an expected is excess is added.
//
// Args:
// measured_ticks: The recorded period of the signal pulse.
// desired_us: The expected period (in useconds) we are matching against.
// measured: The recorded period of the signal pulse.
// desired: The expected period (in useconds) we are matching against.
// tolerance: A percentage expressed as an integer. e.g. 10 is 10%.
// excess: Nr. of useconds.
//
// Returns:
// Boolean: true if it matches, false if it doesn't.
bool IRrecv::matchMark(uint32_t measured_ticks, uint32_t desired_us,
bool IRrecv::matchMark(uint32_t measured, uint32_t desired,
uint8_t tolerance, int16_t excess) {
DPRINT("Matching MARK ");
DPRINT(measured_ticks * USECPERTICK);
DPRINT(measured);
DPRINT(" vs ");
DPRINT(desired_us);
DPRINT(desired);
DPRINT(" + ");
DPRINT(excess);
DPRINT(". ");
return match(measured_ticks, desired_us + excess, tolerance);
return match(measured, desired + excess, tolerance);
}

// Check if we match a space signal(measured_ticks) with the desired_us within
// Check if we match a space signal(measured) with the desired within
// +/-tolerance percent, after an expected is excess is removed.
//
// Args:
// measured_ticks: The recorded period of the signal pulse.
// desired_us: The expected period (in useconds) we are matching against.
// measured: The recorded period of the signal pulse.
// desired: The expected period (in useconds) we are matching against.
// tolerance: A percentage expressed as an integer. e.g. 10 is 10%.
// excess: Nr. of useconds.
//
// Returns:
// Boolean: true if it matches, false if it doesn't.
bool IRrecv::matchSpace(uint32_t measured_ticks, uint32_t desired_us,
bool IRrecv::matchSpace(uint32_t measured, uint32_t desired,
uint8_t tolerance, int16_t excess) {
DPRINT("Matching SPACE ");
DPRINT(measured_ticks * USECPERTICK);
DPRINT(measured);
DPRINT(" vs ");
DPRINT(desired_us);
DPRINT(desired);
DPRINT(" - ");
DPRINT(excess);
DPRINT(". ");
return match(measured_ticks, desired_us - excess, tolerance);
return match(measured, desired - excess, tolerance);
}

/* -----------------------------------------------------------------------
Expand Down
16 changes: 9 additions & 7 deletions src/IRrecv.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#define OFFSET_START 1U // Usual rawbuf entry to start processing from.
// Marks tend to be 100us too long, and spaces 100us too short
// when received due to sensor lag.
#define MARK_EXCESS 100U
#define MARK_EXCESS 50U
#define RAWBUF 100U // Default length of raw capture buffer
#define REPEAT UINT64_MAX
// receiver states
Expand All @@ -29,8 +29,10 @@
#define STATE_SPACE 4U
#define STATE_STOP 5U
#define TOLERANCE 25U // default percent tolerance in measurements
#define USECPERTICK 50U // microseconds per clock interrupt tick
#define TIMEOUT_MS 15U // How long before we give up wait for more data.
// How long (ms) before we give up wait for more data?
// Don't exceed 65ms without a good reason.
// That is the capture buffers maximum value size. (uint16_t)
#define TIMEOUT_MS 15U

// Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
#define FNV_PRIME_32 16777619UL
Expand Down Expand Up @@ -92,13 +94,13 @@ class IRrecv {
int16_t compare(uint16_t oldval, uint16_t newval);
uint32_t ticksLow(uint32_t usecs, uint8_t tolerance = TOLERANCE);
uint32_t ticksHigh(uint32_t usecs, uint8_t tolerance = TOLERANCE);
bool match(uint32_t measured_ticks, uint32_t desired_us,
bool match(uint32_t measured, uint32_t desired,
uint8_t tolerance = TOLERANCE);
bool matchAtLeast(uint32_t measured_ticks, uint32_t desired_us,
bool matchAtLeast(uint32_t measured, uint32_t desired,
uint8_t tolerance = TOLERANCE);
bool matchMark(uint32_t measured_ticks, uint32_t desired_us,
bool matchMark(uint32_t measured, uint32_t desired,
uint8_t tolerance = TOLERANCE, int16_t excess = MARK_EXCESS);
bool matchSpace(uint32_t measured_ticks, uint32_t desired_us,
bool matchSpace(uint32_t measured, uint32_t desired,
uint8_t tolerance = TOLERANCE, int16_t excess = MARK_EXCESS);
match_result_t matchData(volatile uint16_t *data_ptr, uint16_t nbits,
uint16_t onemark, uint32_t onespace,
Expand Down
11 changes: 0 additions & 11 deletions src/IRutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,3 @@ void serialPrintUint64(uint64_t input, uint8_t base) {
Serial.print(str);
#endif
}

// Calculate the tick time in uSeconds based on the input time & factor.
//
// Args:
// input: Nr. of capture ticks.
// factor: Nr. of multiples of the common tick divisor the input should be.
// Returns:
// A uint32_t containing the common tick time in uSeconds.
uint32_t calcTickTime(uint16_t input, uint16_t factor) {
return (input * USECPERTICK) / factor;
}
1 change: 0 additions & 1 deletion src/IRutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@

uint64_t reverseBits(uint64_t input, uint16_t nbits);
void serialPrintUint64(uint64_t input, uint8_t base);
uint32_t calcTickTime(uint16_t input, uint16_t factor);

#endif // IRUTILS_H_
6 changes: 2 additions & 4 deletions src/ir_Coolix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,10 @@ bool IRrecv::decodeCOOLIX(decode_results *results, uint16_t nbits,
// Header
if (!matchMark(results->rawbuf[offset], COOLIX_HDR_MARK)) return false;
// Calculate how long the common tick time is based on the header mark.
uint32_t m_tick = calcTickTime(results->rawbuf[offset++],
COOLIX_HDR_MARK_TICKS);
uint32_t m_tick = results->rawbuf[offset++] / COOLIX_HDR_MARK_TICKS;
if (!matchSpace(results->rawbuf[offset], COOLIX_HDR_SPACE)) return false;
// Calculate how long the common tick time is based on the header space.
uint32_t s_tick = calcTickTime(results->rawbuf[offset++],
COOLIX_HDR_SPACE_TICKS);
uint32_t s_tick = results->rawbuf[offset++] / COOLIX_HDR_SPACE_TICKS;

// Data
// Twice as many bits as there are normal plus inverted bits.
Expand Down
6 changes: 2 additions & 4 deletions src/ir_Denon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,9 @@ bool IRrecv::decodeDenon(decode_results *results, uint16_t nbits, bool strict) {
// Header
if (!matchMark(results->rawbuf[offset], DENON_HDR_MARK)) return false;
// Calculate how long the common tick time is based on the header mark.
uint32_t m_tick = calcTickTime(results->rawbuf[offset++],
DENON_HDR_MARK_TICKS);
uint32_t m_tick = results->rawbuf[offset++] / DENON_HDR_MARK_TICKS;
if (!matchSpace(results->rawbuf[offset], DENON_HDR_SPACE)) return false;
uint32_t s_tick = calcTickTime(results->rawbuf[offset++],
DENON_HDR_SPACE_TICKS);
uint32_t s_tick = results->rawbuf[offset++] / DENON_HDR_SPACE_TICKS;

// Data
match_result_t data_result = matchData(&(results->rawbuf[offset]), nbits,
Expand Down
6 changes: 2 additions & 4 deletions src/ir_Dish.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,10 @@ bool IRrecv::decodeDISH(decode_results *results, uint16_t nbits, bool strict) {
// Header
if (!match(results->rawbuf[offset], DISH_HDR_MARK)) return false;
// Calculate how long the common tick time is based on the header mark.
uint32_t m_tick = calcTickTime(results->rawbuf[offset++],
DISH_HDR_MARK_TICKS);
uint32_t m_tick = results->rawbuf[offset++] / DISH_HDR_MARK_TICKS;
if (!matchSpace(results->rawbuf[offset], DISH_HDR_SPACE)) return false;
// Calculate how long the common tick time is based on the header space.
uint32_t s_tick = calcTickTime(results->rawbuf[offset++],
DISH_HDR_SPACE_TICKS);
uint32_t s_tick = results->rawbuf[offset++] / DISH_HDR_SPACE_TICKS;

// Data
match_result_t data_result = matchData(&(results->rawbuf[offset]), nbits,
Expand Down
4 changes: 2 additions & 2 deletions src/ir_JVC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,12 @@ bool IRrecv::decodeJVC(decode_results *results, uint16_t nbits, bool strict) {
// (Optional as repeat codes don't have the header)
if (matchMark(results->rawbuf[offset], JVC_HDR_MARK)) {
isRepeat = false;
m_tick = calcTickTime(results->rawbuf[offset++], JVC_HDR_MARK_TICKS);
m_tick = results->rawbuf[offset++] / JVC_HDR_MARK_TICKS;
if (results->rawlen < 2 * nbits + 4)
return false; // Can't possibly be a valid JVC message with a header.
if (!matchSpace(results->rawbuf[offset], JVC_HDR_SPACE))
return false;
s_tick = calcTickTime(results->rawbuf[offset++], JVC_HDR_SPACE_TICKS);
s_tick = results->rawbuf[offset++] / JVC_HDR_SPACE_TICKS;
} else {
// We can't easily auto-calibrate as there is no header, so assume
// the default tick time.
Expand Down
8 changes: 4 additions & 4 deletions src/ir_LG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,16 +163,16 @@ bool IRrecv::decodeLG(decode_results *results, uint16_t nbits, bool strict) {
!matchMark(results->rawbuf[offset], LG32_HDR_MARK)) return false;
uint32_t m_tick;
if (matchMark(results->rawbuf[offset], LG_HDR_MARK))
m_tick = calcTickTime(results->rawbuf[offset++], LG_HDR_MARK_TICKS);
m_tick = results->rawbuf[offset++] / LG_HDR_MARK_TICKS;
else
m_tick = calcTickTime(results->rawbuf[offset++], LG32_HDR_MARK_TICKS);
m_tick = results->rawbuf[offset++] / LG32_HDR_MARK_TICKS;
if (!matchSpace(results->rawbuf[offset], LG_HDR_SPACE) &&
!matchSpace(results->rawbuf[offset], LG32_HDR_SPACE)) return false;
uint32_t s_tick;
if (matchSpace(results->rawbuf[offset], LG_HDR_SPACE))
s_tick = calcTickTime(results->rawbuf[offset++], LG_HDR_SPACE_TICKS);
s_tick = results->rawbuf[offset++] / LG_HDR_SPACE_TICKS;
else
s_tick = calcTickTime(results->rawbuf[offset++], LG32_HDR_SPACE_TICKS);
s_tick = results->rawbuf[offset++] / LG32_HDR_SPACE_TICKS;

// Data
match_result_t data_result = matchData(&(results->rawbuf[offset]), nbits,
Expand Down
3 changes: 1 addition & 2 deletions src/ir_Mitsubishi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,7 @@ bool IRrecv::decodeMitsubishi(decode_results *results, uint16_t nbits,
if (!matchMark(results->rawbuf[offset], MITSUBISHI_BIT_MARK, 30))
return false;
// Calculate how long the common tick time is based on the initial mark.
uint32_t tick = calcTickTime(results->rawbuf[offset],
MITSUBISHI_BIT_MARK_TICKS);
uint32_t tick = results->rawbuf[offset] / MITSUBISHI_BIT_MARK_TICKS;

// Data
match_result_t data_result = matchData(&(results->rawbuf[offset]), nbits,
Expand Down
6 changes: 2 additions & 4 deletions src/ir_NEC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,7 @@ bool IRrecv::decodeNEC(decode_results *results, uint16_t nbits, bool strict) {
// Header
if (!matchMark(results->rawbuf[offset], NEC_HDR_MARK)) return false;
// Calculate how long the lowest tick time is based on the header mark.
uint32_t mark_tick = calcTickTime(results->rawbuf[offset++],
NEC_HDR_MARK_TICKS);
uint32_t mark_tick = results->rawbuf[offset++] / NEC_HDR_MARK_TICKS;
// Check if it is a repeat code.
if (results->rawlen == NEC_RPT_LENGTH &&
matchSpace(results->rawbuf[offset], NEC_RPT_SPACE) &&
Expand All @@ -161,8 +160,7 @@ bool IRrecv::decodeNEC(decode_results *results, uint16_t nbits, bool strict) {
// Header (cont.)
if (!matchSpace(results->rawbuf[offset], NEC_HDR_SPACE)) return false;
// Calculate how long the common tick time is based on the header space.
uint32_t space_tick = calcTickTime(results->rawbuf[offset++],
NEC_HDR_SPACE_TICKS);
uint32_t space_tick = results->rawbuf[offset++] / NEC_HDR_SPACE_TICKS;
// Data
match_result_t data_result = matchData(&(results->rawbuf[offset]), nbits,
NEC_BIT_MARK_TICKS * mark_tick,
Expand Down
6 changes: 2 additions & 4 deletions src/ir_Panasonic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,10 @@ bool IRrecv::decodePanasonic(decode_results *results, uint16_t nbits,
// Header
if (!matchMark(results->rawbuf[offset], PANASONIC_HDR_MARK)) return false;
// Calculate how long the common tick time is based on the header mark.
uint32_t m_tick = calcTickTime(results->rawbuf[offset++],
PANASONIC_HDR_MARK_TICKS);
uint32_t m_tick = results->rawbuf[offset++] / PANASONIC_HDR_MARK_TICKS;
if (!matchSpace(results->rawbuf[offset], PANASONIC_HDR_SPACE)) return false;
// Calculate how long the common tick time is based on the header space.
uint32_t s_tick = calcTickTime(results->rawbuf[offset++],
PANASONIC_HDR_SPACE_TICKS);
uint32_t s_tick = results->rawbuf[offset++] / PANASONIC_HDR_SPACE_TICKS;

// Data
match_result_t data_result = matchData(&(results->rawbuf[offset]), nbits,
Expand Down
Loading

0 comments on commit dce5e6c

Please sign in to comment.