Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
LuisMiCa committed Jan 30, 2022
2 parents cc1781a + 9714f47 commit bfe80d3
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 57 deletions.
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -383,72 +383,72 @@ Although my main goals are functionality and small size, I believe this library
<tbody>
<tr>
<td>NEC</td>
<td>FALLING</td>
<td>11.4 &#181;s</td>
<td>RISING</td>
<td>11.35 &#181;s</td>
<td>13 &#181;s</td>
<td>34</td>
<td>67.5ms</td>
</tr>
<tr>
<td>NECx</td>
<td>FALLING</td>
<td>10.9 &#181;s</td>
<td>RISING</td>
<td>10.90 &#181;s</td>
<td>13 &#181;s</td>
<td>34</td>
<td>67.5ms</td>
</tr>
<tr>
<td>RC5</td>
<td>CHANGE</td>
<td>10.4 &#181;s</td>
<td>10.44 &#181;s</td>
<td>17 &#181;s</td>
<td>14 to 28</td>
<td>24.9ms</td>
</tr>
<tr>
<td>SIRC12</td>
<td>RISING</td>
<td>10.3 &#181;s</td>
<td>10.44 &#181;s</td>
<td>13 &#181;s</td>
<td>3*13</td>
<td>3*(17.4 to 24.6)ms</td>
</tr>
<tr>
<td>SIRC15</td>
<td>RISING</td>
<td>10.5 &#181;s</td>
<td>10.51 &#181;s</td>
<td>12 &#181;s</td>
<td>3*16</td>
<td>3*(21 to 30)ms</td>
</tr>
<tr>
<td>SIRC20</td>
<td>RISING</td>
<td>11.1 &#181;s</td>
<td>11.10 &#181;s</td>
<td>15 &#181;s</td>
<td>3*21</td>
<td>3*(27 to 39)ms</td>
</tr>
<tr>
<td>SIRC</td>
<td>RISING</td>
<td>11.7 &#181;s</td>
<td>11.70 &#181;s</td>
<td>17 &#181;s</td>
<td>39, 48 or 63</td>
<td>3*(17.4 to 39)ms</td>
</tr>
<tr>
<td>SAMSUNG</td>
<td>FALLING</td>
<td>11.0 &#181;s</td>
<td>10.99 &#181;s</td>
<td>13 &#181;s</td>
<td>2*22</td>
<td>2*(32.1 to 54.6)ms</td>
</tr>
<tr>
<td>SAMSUNG32</td>
<td>FALLING</td>
<td>11.0 &#181;s</td>
<td>10.97 &#181;s</td>
<td>14 &#181;s</td>
<td>34</td>
<td>(54.6 to 72.6)ms</td>
Expand Down
7 changes: 7 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
IRsmallDecoder
==============

v1.2.1 (2022-01-30)
-------------------
* Increased the NEC/NECx decoder tolerances (issue #6)
* Added NEC protocol timing graphs to extras folder
* Improved the debugging features


v1.2.0 (2022-01-16)
-------------------
* Added the dataAvailable() overload method
Expand Down
Binary file modified extras/README.pdf
Binary file not shown.
1 change: 1 addition & 0 deletions extras/Timings/NEC_timings.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=IRsmallDecoder
version=1.2.0
version=1.2.1
author=Luis Carvalho <lumica@outlook.com>
maintainer=Luis Carvalho <lumica@outlook.com>
sentence=Allows the reception and decoding of infrared signals from remote controls.
Expand Down
56 changes: 43 additions & 13 deletions src/IRsmallDDebug.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,72 @@
*
* Debug options:
* IRSMALLD_DEBUG_STATE - Prints FSM states
* IRSMALLD_DEBUG_DURATION - Prints pulse/space/mark intervals' duration
* IRSMALLD_DEBUG_TIME - Prints ISR execution time
* IRSMALLD_DEBUG_INTERVAL - Prints interval's duration between consecutive interrupts (in µs)
* IRSMALLD_DEBUG_ISRTIME - Prints ISR execution time (in µs)
* IRSMALLD_DEBUG_ISRAVG - Prints the average of the ISR execution time (in µs)
*
* NOTES:
* - The usage of debuging functionalities requires a Serial.begin in the setup;
* - The serial communication speed must be high, to avoid timing errors;
* A Baud Rate of 250000 seems to work;
* - The usage of Serial communications inside an interrupt is not recommended, but
* in this case, it's just a few prints for debuging purposes.
* - IRSMALLD_DEBUG_TIME mode uses AVR 328p Timer1 hardware specific code;
* Results are in micro seconds, assuming a 16MHz clock (Clk Count is divided by 16 to get µs);
* - IRSMALLD_DEBUG_ISRTIME mode uses AVR 328p Timer1 hardware specific code;
* Results are in microseconds, assuming a 16MHz clock (Clk Count is divided by 16 to get µs);
* - IRSMALLD_DEBUG_ISRAVG shows the average of all ISR execution times since the last reset.
* To restart the average calculation you'll need to reset the Arduino or restart the serial monitor.
* You need to accumulator and counter used to calculate the average, you need to reset the Arduino.
*/


#ifndef IRsmallD_Debug_h
#define IRsmallD_Debug_h
// Check Debug incompatibilities:
#if defined(IRSMALLD_DEBUG_INTERVAL) && (defined(IRSMALLD_DEBUG_ISRTIME) || defined(IRSMALLD_DEBUG_ISRAVG))
#error Do not use IRSMALLD_DEBUG_ISRTIME or IRSMALLD_DEBUG_ISRAVG with IRSMALLD_DEBUG_INTERVAL, the ISR execution time is significantly affected by the print(uint32_t)
#elif defined(IRSMALLD_DEBUG_STATE) && (defined(IRSMALLD_DEBUG_ISRTIME) || defined(IRSMALLD_DEBUG_ISRAVG))
#warning Do not use IRSMALLD_DEBUG_ISRTIME or IRSMALLD_DEBUG_ISRAVG with IRSMALLD_DEBUG_STATE if you want accurate measurements of execution time
#endif

// FSM states debug:
#ifdef IRSMALLD_DEBUG_STATE
#define DBG_PRINT_STATE(...) Serial.print(__VA_ARGS__);
#else
#define DBG_PRINT_STATE(...) //nothing
#endif

#ifdef IRSMALLD_DEBUG_DURATION
#define DBG_PRINTLN_DUR(...) {Serial.print("d="); Serial.print(__VA_ARGS__); Serial.println("µ");}
// Signals' intervals' duration:
#ifdef IRSMALLD_DEBUG_INTERVAL
#if defined(IRSMALLD_DEBUG_ISRTIME) || defined(IRSMALLD_DEBUG_ISRAVG)
#define DBG_PRINTLN_DUR(...) {Serial.print(" i"); Serial.print(__VA_ARGS__);}
#else
#define DBG_PRINTLN_DUR(...) {Serial.print(" i"); Serial.println(__VA_ARGS__);}
#endif
#else
#define DBG_PRINTLN_DUR(...) //nothing
#endif

#ifdef IRSMALLD_DEBUG_TIME
#if defined(IRSMALLD_DEBUG_STATE) || defined(IRSMALLD_DEBUG_DURATION)
#warning Do not use IRSMALLD_DEBUG_TIME with IRSMALLD_DEBUG_STATE or IRSMALLD_DEBUG_DURATION if you want accurate measurements of execution time
#endif
#define DBG_RESTART_TIMER() { TCCR1A = 0; TCCR1B = 1; TCNT1=0; } //set mode to count clock cycles and reset
#define DBG_PRINTLN_TIMER() { uint16_t elapsedTime=TCNT1; Serial.print("t="); Serial.print(elapsedTime>>4); Serial.println("µ");}
#else
// ISR Execution Time and Average:
#if defined(IRSMALLD_DEBUG_ISRTIME) && defined(IRSMALLD_DEBUG_ISRAVG) // Time and Average
#define DBG_RESTART_TIMER() TCCR1A = 0; TCCR1B = 1; TCNT1=0; \
static uint16_t dbg_isrCallsCount=0; \
static uint16_t dbg_isrTimeAccum=0;
#define DBG_PRINTLN_TIMER() uint16_t dbg_elapsedTime=TCNT1>>4; Serial.print(" t"); Serial.print(dbg_elapsedTime); \
dbg_isrTimeAccum += dbg_elapsedTime; dbg_isrCallsCount += 1; Serial.print(" a"); \
Serial.println((float)dbg_isrTimeAccum / dbg_isrCallsCount);

#elif defined(IRSMALLD_DEBUG_ISRTIME) // just Time, no Average
#define DBG_RESTART_TIMER() TCCR1A = 0; TCCR1B = 1; TCNT1=0;
#define DBG_PRINTLN_TIMER() uint16_t dbg_elapsedTime=TCNT1>>4; Serial.print(" t"); Serial.println(dbg_elapsedTime);

#elif defined(IRSMALLD_DEBUG_ISRAVG) // just Average, no Time
#define DBG_RESTART_TIMER() TCCR1A = 0; TCCR1B = 1; TCNT1=0; \
static uint16_t dbg_isrCallsCount=0; \
static uint16_t dbg_isrTimeAccum=0;
#define DBG_PRINTLN_TIMER() dbg_isrTimeAccum += TCNT1>>4; dbg_isrCallsCount += 1; Serial.print(" a"); \
Serial.println((float)dbg_isrTimeAccum / dbg_isrCallsCount);
#else // no Time and no Average
#define DBG_RESTART_TIMER() //nothing
#define DBG_PRINTLN_TIMER() //nothing
#endif
Expand Down
10 changes: 5 additions & 5 deletions src/IRsmallDProtocolStructs.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,34 @@
#ifndef IRsmallD_ProtocolStructs_h
#define IRsmallD_ProtocolStructs_h

#if IR_SMALLD_NEC || IR_SMALLD_RC5 || IR_SMALLD_SAMSUNG32
#if defined(IR_SMALLD_NEC) || defined(IR_SMALLD_RC5) || defined(IR_SMALLD_SAMSUNG32)
struct irSmallD_t {
uint8_t addr;
uint8_t cmd;
bool keyHeld;
};

#elif IR_SMALLD_NECx || IR_SMALLD_SAMSUNG
#elif defined(IR_SMALLD_NECx) || defined(IR_SMALLD_SAMSUNG)
struct irSmallD_t {
uint16_t addr;
uint8_t cmd;
bool keyHeld;
};

#elif IR_SMALLD_SIRC12 || IR_SMALLD_SIRC15
#elif defined(IR_SMALLD_SIRC12) || defined(IR_SMALLD_SIRC15)
struct irSmallD_t {
uint8_t addr;
uint8_t cmd;
};

#elif IR_SMALLD_SIRC20
#elif defined(IR_SMALLD_SIRC20)
struct irSmallD_t {
uint8_t ext; //extended data
uint8_t addr;
uint8_t cmd;
};

#elif IR_SMALLD_SIRC
#elif defined(IR_SMALLD_SIRC)
struct irSmallD_t {
uint8_t ext;
uint8_t addr;
Expand Down
45 changes: 25 additions & 20 deletions src/IRsmallD_NEC.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,31 @@
*/


void IRsmallDecoder::irISR() { //executed every time the IR signal goes up (but it's actually FALLING @ ReceiverOutput)
// NEC timings in micro seconds:
// Minimum Gap length = repeatPeriod - SignalFrame = 108000 - 67500 = 40500
const uint16_t c_GapMin = 32400; // = 40500 * 0.8 (20% less)
// Leading Mark Length = Leading pulse + leading space = 9000 + 4500 = 13500
// Repeat Mark Length = Repeat Pulse + Repeat Space = 9000 + 2250 = 11250
// max tolerance = (13500 - 11250)/2 = 1125
const uint16_t c_LMmax = 14625; // = 13500 + 1125 (it could be more)
const uint16_t c_LMmin = 12375; // = 13500 - 1125
const uint16_t c_RMmax = 12374; // = 11250 + 1125 - 1
const uint16_t c_RMmin = 10125; // = 11250 - 1125 (it could be less)
//Bit 0 Mark length = 562.5µs pulse + 562.5µs space = 1125
//Bit 1 Mark length = 562.5µs pulse + 3 * 562.5µs space = 2250
//max tolerance = (2250 - 1125)/2 = 562.5 = bit pulse
const uint16_t c_M1max = 2812; // = 2250 + 562 (it could be more)
const uint16_t c_M1min = 1688; // = 2250 - 562
//const uint16_t c_M0max = 1687; // = 1125 + 562 //not needed...
const uint16_t c_M0min = 563; // = 1125 - 562 (it could be less)
const uint32_t c_GapMax = 106425; //= (108000-11250) * 1.1; // 10% above gap between 2 consecutive repeat marks
//number of initial repeats to be ignored:
// NEC/NECx timings in microseconds:
#define NEC_L_MARK 5062.5 /* Leading Mark */
#define NEC_R_MARK 2812.5 /* Repeat Mark */
#define NEC_R_TOL 803.6 /* Repeat Mark tolerance (µs) */
#define NEC_MARK_0 1125 /* Bit 0 Mark */
#define NEC_MARK_1 2250 /* Bit 1 Mark */
#define NEC_GAP_1 48937.5 /* Gap1 (before first repeat mark) */
#define NEC_GAP_2 105187.5 /* Gap2 (between repeat marks */
// For more information about these timings, go to:
// https://github.com/LuisMiCa/IRsmallDecoder/blob/master/extras/Timings/NEC_timings.svg


void IRsmallDecoder::irISR() { //executed every time the IR signal goes down (but it's actually RISING @ ReceiverOutput)
const uint16_t c_GapMin = NEC_GAP_1 * 0.7; // 34256
const uint32_t c_GapMax = NEC_GAP_2 * 1.3; //136743
const uint16_t c_RMmin = NEC_R_MARK * 0.7; // 1968
const uint16_t c_RMmax = NEC_R_MARK + NEC_R_TOL; // 3616
const uint16_t c_LMmin = c_RMmax + 1; // 3617
const uint16_t c_LMmax = NEC_L_MARK * 1.3; // 6581
const uint16_t c_M1min = NEC_MARK_1 * 0.7; // 1575
const uint16_t c_M1max = NEC_MARK_1 * 1.3; // 2925
const uint16_t c_M0min = NEC_MARK_0 * 0.7; // 787
const uint16_t c_M0max = NEC_MARK_0 * 1.3; // 1462

//number of initial repetition marks to be ignored:
const uint8_t c_RptCount = 2;

// FSM variables:
Expand Down
6 changes: 3 additions & 3 deletions src/IRsmallD_SIRC_basic.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void IRsmallDecoder::irISR() { //executed every time the IR signal goes down (bu
static uint8_t bitCount;
static unsigned long startTime = -1; //FFFF...
static union { //received bits are stored in reversed order (11000101... -> ...10100011)
#if (IR_SMALLD_SIRC12 || IR_SMALLD_SIRC15)
#if defined(IR_SMALLD_SIRC12) || defined(IR_SMALLD_SIRC15)
uint16_t all = 0; //Arduino uses Little Endian so, if all=ABCD then in memory it's CDAB (hex format)
uint8_t byt[2]; //then we get byt[0]=CD and byt[1]=AB (type punning with a union...)
#else //it must be IR_SMALLD_SIRC20
Expand Down Expand Up @@ -101,7 +101,7 @@ void IRsmallDecoder::irISR() { //executed every time the IR signal goes down (bu
irSignal.all >>= 1; //push a 0 from left to right (will be left at 0 if it's M0)
bitCount++;
if (duration >= c_M1min) { //it's a bit 1 mark, change Most Significant bit to 1
#if (IR_SMALLD_SIRC12 || IR_SMALLD_SIRC15)
#if defined(IR_SMALLD_SIRC12) || defined(IR_SMALLD_SIRC15)
irSignal.byt[1] |= 0x80;
#else //IR_SMALLD_SIRC20 uses 4 bytes
irSignal.byt[3] |= 0x80;
Expand All @@ -112,7 +112,7 @@ void IRsmallDecoder::irISR() { //executed every time the IR signal goes down (bu
#if defined(IR_SMALLD_SIRC12)
irSignal.all >>= 3; //adjust address in the high byte (SIRC15/20 don't need this)
#endif
#if (IR_SMALLD_SIRC12 || IR_SMALLD_SIRC15)
#if defined(IR_SMALLD_SIRC12) || defined(IR_SMALLD_SIRC15)
irSignal.byt[0] >>= 1; //adjust command in the low byte
_irData.addr = irSignal.byt[1]; //Little-Endian puts high byte in the array's second position
_irData.cmd = irSignal.byt[0];
Expand Down
9 changes: 5 additions & 4 deletions src/IRsmallDecoder.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* IRsmallDecoder v1.2.0
/* IRsmallDecoder v1.2.1
*
* This is a Library for Arduino and it allows the reception and decoding of infrared signals from remote controls.
* It uses small, fast and reliable decoders that don't require timers.
Expand Down Expand Up @@ -46,9 +46,10 @@

// ****************************************************************************
// IR_ISR_MODE definition based on protocol:
#if IR_SMALLD_NEC || IR_SMALLD_NECx || IR_SMALLD_SAMSUNG || IR_SMALLD_SAMSUNG32
#if defined(IR_SMALLD_SAMSUNG) || defined(IR_SMALLD_SAMSUNG32)
#define IR_ISR_MODE FALLING
#elif IR_SMALLD_SIRC || IR_SMALLD_SIRC12 || IR_SMALLD_SIRC15 || IR_SMALLD_SIRC20
#elif defined(IR_SMALLD_SIRC12) || defined(IR_SMALLD_SIRC15) || defined(IR_SMALLD_SIRC20) || \
defined(IR_SMALLD_SIRC) || defined(IR_SMALLD_NEC) || defined(IR_SMALLD_NECx)
#define IR_ISR_MODE RISING
#elif IR_SMALLD_RC5
#define IR_ISR_MODE CHANGE
Expand Down Expand Up @@ -163,7 +164,7 @@ bool IRsmallDecoder::dataAvailable() {

// ----------------------------------------------------------------------------
// Conditional inclusion of protocol specific ISR implementations:
#if IR_SMALLD_NEC || IR_SMALLD_NECx
#if defined(IR_SMALLD_NEC) || defined(IR_SMALLD_NECx)
#include "IRsmallD_NEC.h"
#elif IR_SMALLD_RC5
#include "IRsmallD_RC5.h"
Expand Down

0 comments on commit bfe80d3

Please sign in to comment.