You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+17-8Lines changed: 17 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -518,10 +518,10 @@ void setup() {
518
518
}
519
519
520
520
voidloop() {
521
-
if (TinyIRReceiverData.justWritten) {
522
-
TinyIRReceiverData.justWritten = false;
521
+
if (TinyReceiverDecode()) {
523
522
printTinyReceiverResultMinimal(&Serial);
524
523
}
524
+
// No resume() required :-)
525
525
}
526
526
```
527
527
@@ -953,8 +953,11 @@ Since the Arduino `micros()` function has a resolution of 4 µs at 16 MHz,
953
953
## Incompatibilities to other libraries and Arduino commands like tone() and analogWrite()
954
954
If you use a library which requires the same timer as IRremote, you have a problem, since **the timer resource cannot be shared simultaneously** by both libraries.
955
955
956
+
### Use NEC protocol and TinyReceiver
957
+
[TinyReceiver](https://github.com/Arduino-IRremote/Arduino-IRremote?tab=readme-ov-file#tiny-nec-receiver-and-sender) does not require a timer, it relies on interrupts, thus avoiding any timer resource problems.
958
+
956
959
### Change timer
957
-
The best approach is to change the timer used for IRremote, which can be accomplished by specifying the timer before `#include <IRremote.hpp>`.<br/>
960
+
The best approach is to **change the timer** used for IRremote, which can be accomplished by specifying the timer before `#include <IRremote.hpp>`.<br/>
958
961
The timer specifications available for your board can be found in [private/IRTimer.hpp](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/private/IRTimer.hpp).<br/>
959
962
960
963
```c++
@@ -971,14 +974,20 @@ The timer specifications available for your board can be found in [private/IRTim
971
974
Here you see the Arduino Mega board and the available specifications are `IR_USE_AVR_TIMER[1,2,3,4,5]`.<br/>
972
975
You **just have to include a line** e.g. `#define IR_USE_AVR_TIMER3` before `#include <IRremote.hpp>` to enable timer 3.
973
976
974
-
But be aware that the new timer in turn might be incompatible with other libraries or commands.<br/>
975
-
For other boards/platforms you must look for the appropriate section guarded by e.g. `#elif defined(ESP32)`.
977
+
But be aware that the new timer in turn might be again incompatible with other libraries or Arduino functions.<br/>
978
+
For non AVR boards/platforms you must look for the appropriate section guarded by e.g. `#elif defined(ESP32)`.
976
979
977
980
### Stop and start timer
978
981
Another approach can be to share the timer **sequentially** if their functionality is used only for a short period of time like for the **Arduino tone() command**.
979
-
An example can be seen [here](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/21b5747a58e9d47c9e3f1beb056d58c875a92b47/examples/ReceiveDemo/ReceiveDemo.ino#L159-L169), where the timer settings for IR receive are restored after the tone has stopped.
980
-
For this we must call `IrReceiver.restartTimer()` or better `IrReceiver.restartTimer(microsecondsOfToneDuration)`.<br/>
981
-
This only works since each call to` tone()` completely initializes the timer 2 used by the `tone()` command.
982
+
An example can be seen [here](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/21b5747a58e9d47c9e3f1beb056d58c875a92b47/examples/ReceiveDemo/ReceiveDemo.ino#L159-L169), where the IR timer is restarted after the tone has stopped.
983
+
984
+
```c++
985
+
IrReceiver.stopTimer(); // Stop timer consistently before calling tone() or other functions using the timer resource.
986
+
tone(TONE_PIN, 2200, 8);
987
+
delay(8);
988
+
IrReceiver.restartTimer(); // Restart IR timer after timer resource is no longer blocked.
989
+
```
990
+
This works on AVR boards like Uno because each call to` tone()` completely initializes the timer 2 used by the `tone()` command.
982
991
983
992
## Hardware-PWM signal generation for sending
984
993
If you define `SEND_PWM_BY_TIMER`, the send PWM signal is forced to be generated by a hardware timer on most platforms.<br/>
timerConfigForReceive(); // no interrupts enabled here!
379
380
// Timer interrupt is enabled after state machine reset
381
+
if (sMicrosAtLastStopTimer != 0) {
382
+
irparams.TickCounterForISR += (micros() - sMicrosAtLastStopTimer) / MICROS_PER_TICK; // adjust TickCounterForISR for correct gap value, which is used for repeat detection
383
+
sMicrosAtLastStopTimer = 0;
384
+
}
380
385
timerEnableReceiveInterrupt(); // Enables the receive sample timer interrupt which consumes a small amount of CPU every 50 us.
381
386
#ifdef _IR_MEASURE_TIMING
382
387
pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);
@@ -394,33 +399,30 @@ void IRrecv::enableIRIn() {
394
399
* We assume, that timer interrupts are disabled here, otherwise it makes no sense to use this functions.
395
400
* Therefore we do not need to guard the change of the volatile TickCounterForISR here :-).
396
401
* The tick counter value is already at 100 when decode() gets true, because of the 5000 us minimal gap defined in RECORD_GAP_MICROS.
402
+
* If TickCounterForISR is not adjusted with the value of the microseconds, the timer was stopped,
403
+
* it can happen, that a new IR frame is recognized as a repeat, because the value of RECORD_GAP_MICROS
404
+
* was not reached by TickCounterForISR counter before receiving the new IR frame.
397
405
* @param aMicrosecondsToAddToGapCounter To compensate for the amount of microseconds the timer was stopped / disabled.
#defineIR_REC_STATE_IDLE0// Counting the gap time and waiting for the start bit to arrive
121
121
#defineIR_REC_STATE_MARK1// A mark was received and we are counting the duration of it.
@@ -144,6 +144,8 @@ struct irparams_struct {
144
144
IRRawbufType rawbuf[RAW_BUFFER_LENGTH]; ///< raw data / tick counts per mark/space. With 8 bit we can only store up to 12.7 ms. First entry is empty to be backwards compatible.
145
145
};
146
146
147
+
externunsignedlongsMicrosAtLastStopTimer; // Used to adjust TickCounterForISR with uncounted ticks between stopTimer() and restartTimer()
uint8_tFlags; // Bit coded flags. Can contain one of the bits: IRDATA_FLAGS_IS_REPEAT and IRDATA_FLAGS_PARITY_FAILED
246
-
booljustWritten; ///< Is set true if new data is available. Used by the main loop, to avoid multiple evaluations of the same IR frame.
246
+
booljustWritten; ///< Is set true if new data is available. Used by the main loop / TinyReceiverDecode(), to avoid multiple evaluations of the same IR frame.
Copy file name to clipboardExpand all lines: src/TinyIRReceiver.hpp
+12-2Lines changed: 12 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -84,7 +84,6 @@
84
84
//#define USE_ONKYO_PROTOCOL // Like NEC, but take the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value.
85
85
//#define USE_FAST_PROTOCOL // Use FAST protocol instead of NEC / ONKYO.
86
86
//#define ENABLE_NEC2_REPEATS // Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat.
87
-
88
87
#include"TinyIR.h"// If not defined, it defines IR_RECEIVE_PIN, IR_FEEDBACK_LED_PIN and TINY_RECEIVER_USE_ARDUINO_ATTACH_INTERRUPT
0 commit comments