IRremote
IRReceive.hpp
Go to the documentation of this file.
1 /*
2  * IRReceive.hpp
3  * This file is exclusively included by IRremote.h to enable easy configuration of library switches
4  *
5  * Contains all IRrecv class functions as well as other receiver related functions.
6  *
7  * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
8  *
9  ************************************************************************************
10  * MIT License
11  *
12  * Copyright (c) 2009-2023 Ken Shirriff, Rafi Khan, Armin Joachimsmeyer
13  *
14  * Permission is hereby granted, free of charge, to any person obtaining a copy
15  * of this software and associated documentation files (the "Software"), to deal
16  * in the Software without restriction, including without limitation the rights
17  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18  * copies of the Software, and to permit persons to whom the Software is furnished
19  * to do so, subject to the following conditions:
20  *
21  * The above copyright notice and this permission notice shall be included in all
22  * copies or substantial portions of the Software.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
25  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
26  * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
28  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
29  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30  *
31  ************************************************************************************
32  */
33 #ifndef _IR_RECEIVE_HPP
34 #define _IR_RECEIVE_HPP
35 
36 #if defined(DEBUG)
37 //#define LOCAL_DEBUG //
38 #else
39 //#define LOCAL_DEBUG // This enables debug output only for this file
40 #endif
41 
42 #if defined(TRACE) && !defined(LOCAL_TRACE)
43 #define LOCAL_TRACE
44 #else
45 //#define LOCAL_TRACE // This enables debug output only for this file
46 #endif
47 /*
48  * Low level hardware timing measurement
49  */
50 //#define _IR_MEASURE_TIMING // for ISR
51 //#define _IR_TIMING_TEST_PIN 7 // "pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);" is executed at start()
52 //
60 
61 /*
62  * The control structure instance
63  */
64 struct irparams_struct irparams; // the irparams instance
65 unsigned long sMicrosAtLastStopTimer = 0; // Used to adjust TickCounterForISR with uncounted ticks between stopTimer() and restartTimer()
66 
72  decodedIRData.rawDataPtr = &irparams; // for decodePulseDistanceData() etc.
73  setReceivePin(0);
74 #if !defined(NO_LED_FEEDBACK_CODE)
76 #endif
77 }
78 
79 IRrecv::IRrecv(uint_fast8_t aReceivePin) {
80  decodedIRData.rawDataPtr = &irparams; // for decodePulseDistanceData() etc.
81  setReceivePin(aReceivePin);
82 #if !defined(NO_LED_FEEDBACK_CODE)
84 #endif
85 }
86 
92 IRrecv::IRrecv(uint_fast8_t aReceivePin, uint_fast8_t aFeedbackLEDPin) {
93  decodedIRData.rawDataPtr = &irparams; // for decodePulseDistanceData() etc.
94  setReceivePin(aReceivePin);
95 #if !defined(NO_LED_FEEDBACK_CODE)
97 #else
98  (void) aFeedbackLEDPin;
99 #endif
100 }
101 
102 /**********************************************************************************************************************
103  * Interrupt Service Routine - Called every 50 us
104  *
105  * Duration in ticks of 50 us of alternating SPACE, MARK are recorded in irparams.rawbuf array.
106  * 'rawlen' counts the number of entries recorded so far.
107  * First entry is the SPACE between transmissions.
108  *
109  * As soon as one SPACE entry gets longer than RECORD_GAP_TICKS, state switches to STOP (frame received). Timing of SPACE continues.
110  * A call of resume() switches from STOP to IDLE.
111  * As soon as first MARK arrives in IDLE, gap width is recorded and new logging starts.
112  *
113  * With digitalRead and Feedback LED
114  * 15 pushs, 1 in, 1 eor before start of code = 2 us @16MHz + * 7.2 us computation time (6us idle time) + * pop + reti = 2.25 us @16MHz => 10.3 to 11.5 us @16MHz
115  * With portInputRegister and mask and Feedback LED code commented
116  * 9 pushs, 1 in, 1 eor before start of code = 1.25 us @16MHz + * 2.25 us computation time + * pop + reti = 1.5 us @16MHz => 5 us @16MHz
117  * => Minimal CPU frequency is 4 MHz
118  *
119  **********************************************************************************************************************/
120 #if defined(ESP8266) || defined(ESP32)
121 #pragma GCC diagnostic push
122 #pragma GCC diagnostic ignored "-Wvolatile"
123 IRAM_ATTR
124 #endif
126 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
127  digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles
128 #endif
129 // 7 - 8.5 us for ISR body (without pushes and pops) for ATmega328 @16MHz
130 
131 #if defined(TIMER_REQUIRES_RESET_INTR_PENDING)
132  timerResetInterruptPending(); // reset TickCounterForISR interrupt flag if required (currently only for Teensy and ATmega4809)
133 #endif
134 
135 // Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on]
136 #if defined(__AVR__)
137  uint8_t tIRInputLevel = *irparams.IRReceivePinPortInputRegister & irparams.IRReceivePinMask;
138 #else
139  uint_fast8_t tIRInputLevel = (uint_fast8_t) digitalReadFast(irparams.IRReceivePin);
140 #endif
141 
142  /*
143  * Increase TickCounter and clip it at maximum 0xFFFF / 3.2 seconds at 50 us ticks
144  */
145  if (irparams.TickCounterForISR < UINT16_MAX) {
146  irparams.TickCounterForISR++; // One more 50uS tick
147  }
148 
149  /*
150  * Due to a ESP32 compiler bug https://github.com/espressif/esp-idf/issues/1552 no switch statements are possible for ESP32
151  * So we change the code to if / else if
152  */
153 // switch (irparams.StateForISR) {
154 //
156  /*
157  * Here we are just resumed and maybe in the middle of a transmission
158  */
159  if (tIRInputLevel == INPUT_MARK) {
160  // check if we did not start in the middle of a transmission by checking the minimum length of leading space
162 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
163 // digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles
164 #endif
165  /*
166  * Gap between two transmissions just ended; Record gap duration + start recording transmission
167  * Initialize all state machine variables
168  */
169  irparams.OverflowFlag = false;
170  // irparams.rawbuf[0] = irparams.TickCounterForISR;
171  // Usage of initialGapTicks enables usage of 8 bit buffer instead of 16 bit since 4.4,
172  // because the big gap value is not stored in this buffer any more
174  irparams.rawlen = 1;
176  } // otherwise stay in idle state
177  irparams.TickCounterForISR = 0; // reset counter in both cases
178  }
179 
180  } else if (irparams.StateForISR == IR_REC_STATE_MARK) {
181  // Timing mark here, rawlen is even
182  if (tIRInputLevel != INPUT_MARK) {
183  /*
184  * Mark ended here. Record mark time in rawbuf array
185  */
186 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
187 // digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles
188 #endif
191  irparams.TickCounterForISR = 0; // This resets the tick counter also at end of frame :-)
192  }
193 
194  } else if (irparams.StateForISR == IR_REC_STATE_SPACE) {
195  /*
196  * In space receiving here, rawlen is odd
197  * Check for timeout or overflow
198  */
201  // Flag up a read OverflowFlag; Stop the state machine
202  irparams.OverflowFlag = true;
203  }
204  /*
205  * Overflow or maximum space duration reached here.
206  * Current code is ready for processing!
207  * We received a long space, which indicates gap between codes.
208  * Switch to IR_REC_STATE_STOP
209  * Don't reset TickCounterForISR; keep counting width of next leading space
210  */
211  /*
212  * These 2 variables allow to call resume() directly after decode.
213  * After resume(), decodedIRData.rawDataPtr->initialGapTicks and decodedIRData.rawDataPtr->rawlen are
214  * the first variables, which are overwritten by the next received frame.
215  * since 4.3.0.
216  * For backward compatibility, there are the same 2 statements in decode() if IrReceiver is not used.
217  */
220 
221  irparams.StateForISR = IR_REC_STATE_STOP; // This signals the decode(), that a complete frame was received
222 #if !defined(IR_REMOTE_DISABLE_RECEIVE_COMPLETE_CALLBACK)
223  /*
224  * Call callback if registered (not nullptr)
225  */
226  if (irparams.ReceiveCompleteCallbackFunction != nullptr) {
228  }
229 #endif
230  } else if (tIRInputLevel == INPUT_MARK) {
231  /*
232  * Space ended here.
233  */
234 
235 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
236 // digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles
237 #endif
241  }
242  } else if (irparams.StateForISR == IR_REC_STATE_STOP) {
243  /*
244  * Complete command received
245  * stay here until resume() is called, which switches state to IR_REC_STATE_IDLE
246  */
247 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
248 // digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles
249 #endif
250  if (tIRInputLevel == INPUT_MARK) {
251  // Reset gap TickCounterForISR, to prepare for detection if we are in the middle of a transmission after call of resume()
253  }
254  }
255 
256 #if !defined(NO_LED_FEEDBACK_CODE)
258  setFeedbackLED(tIRInputLevel == INPUT_MARK);
259  }
260 #endif
261 
262 #ifdef _IR_MEASURE_TIMING
263  digitalWriteFast(_IR_TIMING_TEST_PIN, LOW); // 2 clock cycles
264 #endif
265 
266 }
267 
268 /*
269  * The ISR, which calls the interrupt handler
270  */
271 #if defined(TIMER_INTR_NAME) || defined(ISR)
272 # if defined(TIMER_INTR_NAME)
273 ISR (TIMER_INTR_NAME) // for ISR definitions
274 # elif defined(ISR)
275 ISR()
276 // for functions definitions which are called by separate (board specific) ISR
277 # endif
278 {
280 }
281 #endif
282 
283 /**********************************************************************************************************************
284  * Stream like API
285  **********************************************************************************************************************/
286 
293 void IRrecv::begin(uint_fast8_t aReceivePin, bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin) {
294 
295  setReceivePin(aReceivePin);
296 #if !defined(NO_LED_FEEDBACK_CODE)
297  uint_fast8_t tEnableLEDFeedback = DO_NOT_ENABLE_LED_FEEDBACK;
298  if (aEnableLEDFeedback) {
299  tEnableLEDFeedback = LED_FEEDBACK_ENABLED_FOR_RECEIVE;
300  }
301  setLEDFeedback(aFeedbackLEDPin, tEnableLEDFeedback);
302 #else
303  (void) aEnableLEDFeedback;
304  (void) aFeedbackLEDPin;
305 #endif
306 
307 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
308  pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);
309 #endif
310  start();
311 }
312 
316 void IRrecv::setReceivePin(uint_fast8_t aReceivePinNumber) {
317  irparams.IRReceivePin = aReceivePinNumber;
318 #if defined(__AVR__)
319 # if defined(__digitalPinToBit)
320  if (__builtin_constant_p(aReceivePinNumber)) {
321  irparams.IRReceivePinMask = 1UL << (__digitalPinToBit(aReceivePinNumber));
322  } else {
323  irparams.IRReceivePinMask = digitalPinToBitMask(aReceivePinNumber); // requires 10 bytes PGM, even if not referenced (?because it is assembler code?)
324  }
325 # else
326  irparams.IRReceivePinMask = digitalPinToBitMask(aReceivePinNumber); // requires 10 bytes PGM, even if not referenced (?because it is assembler code?)
327 # endif
328 # if defined(__digitalPinToPINReg)
329  /*
330  * This code is 54 bytes smaller, if aReceivePinNumber is a constant :-), but 38 byte longer if it is not constant (,which is not likely).
331  */
332  if (__builtin_constant_p(aReceivePinNumber)) {
333  irparams.IRReceivePinPortInputRegister = __digitalPinToPINReg(aReceivePinNumber);
334  } else {
335  irparams.IRReceivePinPortInputRegister = portInputRegister(digitalPinToPort(aReceivePinNumber)); // requires 44 bytes PGM, even if not referenced
336  }
337 # else
338  irparams.IRReceivePinPortInputRegister = portInputRegister(digitalPinToPort(aReceivePinNumber)); // requires 44 bytes PGM, even if not referenced
339 # endif
340 #endif
341  // Seems to be at least required by ESP32
342  // Set pin mode once. pinModeFast makes no difference if used, but saves 224 if not referenced :-(
343  if (__builtin_constant_p(aReceivePinNumber)) {
344  pinModeFast(aReceivePinNumber, INPUT);
345  } else {
346  pinModeFast(aReceivePinNumber, INPUT);
347  }
348 }
349 
350 #if !defined(IR_REMOTE_DISABLE_RECEIVE_COMPLETE_CALLBACK)
351 
354 void IRrecv::registerReceiveCompleteCallback(void (*aReceiveCompleteCallbackFunction)(void)) {
355  irparams.ReceiveCompleteCallbackFunction = aReceiveCompleteCallbackFunction;
356 }
357 #endif
358 
365 
366  // Setup for cyclic 50 us interrupt
367  timerConfigForReceive(); // no interrupts enabled here!
368 
369  // Initialize state machine state
370  resume();
371 
372  // Timer interrupt is enabled after state machine reset
373  timerEnableReceiveInterrupt(); // Enables the receive sample timer interrupt which consumes a small amount of CPU every 50 us.
374 #ifdef _IR_MEASURE_TIMING
375  pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);
376 #endif
377 }
378 
379 /*
380  * Restarts timer interrupts, adjusts TickCounterForISR for correct gap value after stopTimer(). Does not call resume()!
381  */
383  // Setup for cyclic 50 us interrupt
384  timerConfigForReceive(); // no interrupts enabled here!
385  // Timer interrupt is enabled after state machine reset
386  if (sMicrosAtLastStopTimer != 0) {
387  irparams.TickCounterForISR += (micros() - sMicrosAtLastStopTimer) / MICROS_PER_TICK; // adjust TickCounterForISR for correct gap value, which is used for repeat detection
389  }
390  timerEnableReceiveInterrupt(); // Enables the receive sample timer interrupt which consumes a small amount of CPU every 50 us.
391 #ifdef _IR_MEASURE_TIMING
392  pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);
393 #endif
394 }
399  start();
400 }
401 
412 void IRrecv::restartTimer(uint32_t aMicrosecondsToAddToGapCounter) {
413  irparams.TickCounterForISR += aMicrosecondsToAddToGapCounter / MICROS_PER_TICK;
414  timerConfigForReceive(); // no interrupts enabled here!
415  timerEnableReceiveInterrupt(); // Enables the receive sample timer interrupt which consumes a small amount of CPU every 50 us.
416 #ifdef _IR_MEASURE_TIMING
417  pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);
418 #endif
419 }
424 void IRrecv::restartTimerWithTicksToAdd(uint16_t aTicksToAddToGapCounter) {
425  irparams.TickCounterForISR += aTicksToAddToGapCounter;
426  timerConfigForReceive(); // no interrupts enabled here!
427  timerEnableReceiveInterrupt(); // Enables the receive sample timer interrupt which consumes a small amount of CPU every 50 us.
428 #ifdef _IR_MEASURE_TIMING
429  pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);
430 #endif
431 }
432 #if defined(ESP8266) || defined(ESP32)
433 #pragma GCC diagnostic push
434 #endif
435 
440 #if defined(SEND_PWM_BY_TIMER) && !defined(SEND_PWM_DOES_NOT_USE_RECEIVE_TIMER)
441  start();
442 #endif
443 }
444 
448 void IRrecv::stop() {
450 }
451 
452 /*
453  * Stores microseconds of stop, to adjust TickCounterForISR in restartTimer()
454  */
457  sMicrosAtLastStopTimer = micros();
458 }
463  stop();
464 }
468 void IRrecv::end() {
469  stop();
470 }
471 
478 }
479 
485  // This check allows to call resume at arbitrary places or more than once
488  }
489 }
490 
496 
497  if (irparams.OverflowFlag) {
499 #if defined(LOCAL_DEBUG)
500  Serial.print(F("Overflow happened, try to increase the \"RAW_BUFFER_LENGTH\" value of "));
501  Serial.print(RAW_BUFFER_LENGTH);
502  Serial.println(F(" with #define RAW_BUFFER_LENGTH=<biggerValue>"));
503 #endif
504 
505  } else {
507  // save last protocol, command and address for repeat handling (where they are compared or copied back :-))
508  lastDecodedProtocol = decodedIRData.protocol; // repeat patterns can be equal between protocols (e.g. NEC, Samsung and LG), so we must keep the original one
511 
512  }
518 }
519 
525 }
526 
532  return nullptr;
533  }
534  if (decode()) {
535  return &decodedIRData;
536  } else {
537  return nullptr;
538  }
539 }
540 
549  return false;
550  }
551 
552  /*
553  * Support for old examples, which do not use the default IrReceiver instance
554  */
555  if (this != &IrReceiver) {
558  }
559 
560  initDecodedIRData(); // sets IRDATA_FLAGS_WAS_OVERFLOW
561 
563  /*
564  * Set OverflowFlag flag and return true here, to let the loop call resume or print raw data.
565  */
567  return true;
568  }
569 
570 #if defined(DECODE_NEC) || defined(DECODE_ONKYO)
571  IR_TRACE_PRINTLN(F("Attempting NEC/Onkyo decode"));
572  if (decodeNEC()) {
573  return true;
574  }
575 #endif
576 
577 #if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO)
578  IR_TRACE_PRINTLN(F("Attempting Panasonic/Kaseikyo decode"));
579  if (decodeKaseikyo()) {
580  return true;
581  }
582 #endif
583 
584 #if defined(DECODE_DENON)
585  IR_TRACE_PRINTLN(F("Attempting Denon/Sharp decode"));
586  if (decodeDenon()) {
587  return true;
588  }
589 #endif
590 
591 #if defined(DECODE_SONY)
592  IR_TRACE_PRINTLN(F("Attempting Sony decode"));
593  if (decodeSony()) {
594  return true;
595  }
596 #endif
597 
598 #if defined(DECODE_RC5)
599  IR_TRACE_PRINTLN(F("Attempting RC5 decode"));
600  if (decodeRC5()) {
601  return true;
602  }
603 #endif
604 
605 #if defined(DECODE_RC6)
606  IR_TRACE_PRINTLN(F("Attempting RC6 decode"));
607  if (decodeRC6()) {
608  return true;
609  }
610 #endif
611 
612 #if defined(DECODE_LG)
613  IR_TRACE_PRINTLN(F("Attempting LG decode"));
614  if (decodeLG()) {
615  return true;
616  }
617 #endif
618 
619 #if defined(DECODE_JVC)
620  IR_TRACE_PRINTLN(F("Attempting JVC decode"));
621  if (decodeJVC()) {
622  return true;
623  }
624 #endif
625 
626 #if defined(DECODE_SAMSUNG)
627  IR_TRACE_PRINTLN(F("Attempting Samsung decode"));
628  if (decodeSamsung()) {
629  return true;
630  }
631 #endif
632  /*
633  * Start of the exotic protocols
634  */
635 
636 #if defined(DECODE_BEO)
637  IR_TRACE_PRINTLN(F("Attempting Bang & Olufsen decode"));
638  if (decodeBangOlufsen()) {
639  return true;
640  }
641 #endif
642 
643 #if defined(DECODE_FAST)
644  IR_TRACE_PRINTLN(F("Attempting FAST decode"));
645  if (decodeFAST()) {
646  return true;
647  }
648 #endif
649 
650 #if defined(DECODE_WHYNTER)
651  IR_TRACE_PRINTLN(F("Attempting Whynter decode"));
652  if (decodeWhynter()) {
653  return true;
654  }
655 #endif
656 
657 #if defined(DECODE_LEGO_PF)
658  IR_TRACE_PRINTLN(F("Attempting Lego Power Functions"));
659  if (decodeLegoPowerFunctions()) {
660  return true;
661  }
662 #endif
663 
664 #if defined(DECODE_BOSEWAVE)
665  IR_TRACE_PRINTLN(F("Attempting Bosewave decode"));
666  if (decodeBoseWave()) {
667  return true;
668  }
669 #endif
670 
671 #if defined(DECODE_MAGIQUEST)
672  IR_TRACE_PRINTLN(F("Attempting MagiQuest decode"));
673  if (decodeMagiQuest()) {
674  return true;
675  }
676 #endif
677 
678  /*
679  * Try the universal decoder for pulse distance protocols
680  */
681 #if defined(DECODE_DISTANCE_WIDTH)
682  IR_TRACE_PRINTLN(F("Attempting universal Distance Width decode"));
683  if (decodeDistanceWidth()) {
684  return true;
685  }
686 #endif
687 
688  /*
689  * Last resort is the universal hash decode which always return true
690  */
691 #if defined(DECODE_HASH)
692  IR_TRACE_PRINTLN(F("Hash decode"));
693  // decodeHash returns a hash on any input.
694  // Thus, it needs to be last in the list.
695  // If you add any decodes, add them before this.
696  if (decodeHash()) {
697  return true;
698  }
699 #endif
700 
701  /*
702  * Return true here, to let the loop decide to call resume or to print raw data.
703  */
704  return true;
705 }
706 
707 /**********************************************************************************************************************
708  * Common decode functions
709  **********************************************************************************************************************/
731 bool IRrecv::decodePulseDistanceWidthData(uint_fast8_t aNumberOfBits, IRRawlenType aStartOffset, uint16_t aOneMarkMicros,
732  uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, bool aMSBfirst) {
733 
734  auto *tRawBufPointer = &decodedIRData.rawDataPtr->rawbuf[aStartOffset];
735 
736  bool isPulseDistanceProtocol = (aOneMarkMicros == aZeroMarkMicros); // If true, we check aOneSpaceMicros -> pulse distance protocol
737 
738  IRRawDataType tDecodedData = 0; // For MSB first tDecodedData is shifted left each loop
739  IRRawDataType tMask = 1UL; // Mask is only used for LSB first
740 
741  for (uint_fast8_t i = aNumberOfBits; i > 0; i--) {
742  // get one mark and space pair
743  unsigned int tMarkTicks;
744  unsigned int tSpaceTicks;
745  bool tBitValue;
746 
747  if (isPulseDistanceProtocol) {
748  /*
749  * PULSE_DISTANCE -including PULSE_DISTANCE_WIDTH- here.
750  * !!!We only check variable length space indicating a 1 or 0!!!
751  */
752  tRawBufPointer++;
753  tSpaceTicks = *tRawBufPointer++; // maybe buffer overflow for last bit, but we do not evaluate this value :-)
754  tBitValue = matchSpace(tSpaceTicks, aOneSpaceMicros); // Check for variable length space indicating a 1 or 0
755 
756  } else {
757  /*
758  * PULSE_WIDTH here.
759  * !!!We only check variable length mark indicating a 1 or 0!!!
760  */
761  tMarkTicks = *tRawBufPointer++;
762  tBitValue = matchMark(tMarkTicks, aOneMarkMicros); // Check for variable length mark indicating a 1 or 0
763  tRawBufPointer++;
764  }
765 
766  if (aMSBfirst) {
767  tDecodedData <<= 1;
768  }
769 
770  if (tBitValue) {
771  // It's a 1 -> set the bit
772  if (aMSBfirst) {
773  tDecodedData |= 1;
774  } else {
775  tDecodedData |= tMask;
776  }
777  IR_TRACE_PRINTLN(F("=> 1"));
778  } else {
779  // do not set the bit
780  IR_TRACE_PRINTLN(F("=> 0"));
781  }
782  tMask <<= 1;
783  }
784  decodedIRData.decodedRawData = tDecodedData;
785  return true;
786 }
787 
788 /*
789  * Old deprecated version with 7 parameters and unused aZeroSpaceMicros parameter
790  */
791 bool IRrecv::decodePulseDistanceWidthData(uint_fast8_t aNumberOfBits, IRRawlenType aStartOffset, uint16_t aOneMarkMicros,
792  uint16_t aZeroMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroSpaceMicros, bool aMSBfirst) {
793 
794  (void) aZeroSpaceMicros;
795  auto *tRawBufPointer = &decodedIRData.rawDataPtr->rawbuf[aStartOffset];
796  bool isPulseDistanceProtocol = (aOneMarkMicros == aZeroMarkMicros); // If true, we have a constant mark -> pulse distance protocol
797 
798  IRRawDataType tDecodedData = 0; // For MSB first tDecodedData is shifted left each loop
799  IRRawDataType tMask = 1UL; // Mask is only used for LSB first
800 
801  for (uint_fast8_t i = aNumberOfBits; i > 0; i--) {
802  // get one mark and space pair
803  unsigned int tMarkTicks;
804  unsigned int tSpaceTicks;
805  bool tBitValue;
806 
807  if (isPulseDistanceProtocol) {
808  /*
809  * Pulse distance here, it is not required to check constant mark duration (aOneMarkMicros) and zero space duration.
810  */
811 
812  (void) aZeroSpaceMicros;
813  tRawBufPointer++;
814  tSpaceTicks = *tRawBufPointer++; // maybe buffer overflow for last bit, but we do not evaluate this value :-)
815  tBitValue = matchSpace(tSpaceTicks, aOneSpaceMicros); // Check for variable length space indicating a 1 or 0
816  } else {
817  /*
818  * Pulse width here, it is not required to check (constant) space duration and zero mark duration.
819  */
820  tMarkTicks = *tRawBufPointer++;
821  tBitValue = matchMark(tMarkTicks, aOneMarkMicros); // Check for variable length mark indicating a 1 or 0
822  tRawBufPointer++;
823  }
824 
825  if (aMSBfirst) {
826  tDecodedData <<= 1;
827  }
828 
829  if (tBitValue) {
830  // It's a 1 -> set the bit
831  if (aMSBfirst) {
832  tDecodedData |= 1;
833  } else {
834  tDecodedData |= tMask;
835  }
836  IR_TRACE_PRINTLN(F("=> 1"));
837  } else {
838  // do not set the bit
839  IR_TRACE_PRINTLN(F("=> 0"));
840  }
841  tMask <<= 1;
842  }
843  decodedIRData.decodedRawData = tDecodedData;
844  return true;
845 }
846 
847 /*
848  * Check for additional required characteristics of timing like length of mark for a constant mark protocol,
849  * where space length determines the bit value. Requires up to 194 additional bytes of program memory.
850  * Only sensible for development or very exotic requirements.
851  * @param aZeroMarkMicros For strict checks
852  * @param aZeroSpaceMicros For strict checks
853  *
854  * Not used yet
855  */
856 bool IRrecv::decodePulseDistanceWidthDataStrict(uint_fast8_t aNumberOfBits, IRRawlenType aStartOffset, uint16_t aOneMarkMicros,
857  uint16_t aZeroMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroSpaceMicros, bool aMSBfirst) {
858 
859  auto *tRawBufPointer = &decodedIRData.rawDataPtr->rawbuf[aStartOffset];
860 
861  bool isPulseDistanceProtocol = (aOneMarkMicros == aZeroMarkMicros); // If true, we have a constant mark -> pulse distance protocol
862 
863  IRRawDataType tDecodedData = 0; // For MSB first tDecodedData is shifted left each loop
864  IRRawDataType tMask = 1UL; // Mask is only used for LSB first
865 
866  for (uint_fast8_t i = aNumberOfBits; i > 0; i--) {
867  // get one mark and space pair
868  unsigned int tMarkTicks;
869  unsigned int tSpaceTicks;
870  bool tBitValue;
871 
872  if (isPulseDistanceProtocol) {
873  /*
874  * PULSE_DISTANCE here, it is not required to check constant mark duration (aOneMarkMicros) and zero space duration.
875  */
876  tMarkTicks = *tRawBufPointer++;
877  tSpaceTicks = *tRawBufPointer++; // maybe buffer overflow for last bit, but we do not evaluate this value :-)
878  tBitValue = matchSpace(tSpaceTicks, aOneSpaceMicros); // Check for variable length space indicating a 1 or 0
879 
880  // Check for constant length mark
881  if (!matchMark(tMarkTicks, aOneMarkMicros)) {
882 #if defined(LOCAL_DEBUG)
883  Serial.print(F("Mark="));
884  Serial.print(tMarkTicks * MICROS_PER_TICK);
885  Serial.print(F(" is not "));
886  Serial.print(aOneMarkMicros);
887  Serial.print(F(". Index="));
888  Serial.print(aNumberOfBits - i);
889  Serial.print(' ');
890 #endif
891  return false;
892  }
893 
894  } else {
895  /*
896  * PULSE_DISTANCE -including PULSE_DISTANCE_WIDTH- here.
897  * !!!We only check variable length mark indicating a 1 or 0!!!
898  * It is not required to check space duration and zero mark duration.
899  */
900  tMarkTicks = *tRawBufPointer++;
901  tBitValue = matchMark(tMarkTicks, aOneMarkMicros); // Check for variable length mark indicating a 1 or 0
902  tSpaceTicks = *tRawBufPointer++; // maybe buffer overflow for last bit, but we do not evaluate this value :-)
903  }
904 
905  if (aMSBfirst) {
906  tDecodedData <<= 1;
907  }
908 
909  if (tBitValue) {
910  // It's a 1 -> set the bit
911  if (aMSBfirst) {
912  tDecodedData |= 1;
913  } else {
914  tDecodedData |= tMask;
915  }
916  IR_TRACE_PRINTLN(F("=> 1"));
917  } else {
918  /*
919  * Additionally check length of tSpaceTicks parameter for PULSE_DISTANCE or tMarkTicks for PULSE_WIDTH
920  * which determine a zero
921  */
922  if (isPulseDistanceProtocol) {
923  if (!matchSpace(tSpaceTicks, aZeroSpaceMicros)) {
924 #if defined(LOCAL_DEBUG)
925  Serial.print(F("Space="));
926  Serial.print(tSpaceTicks * MICROS_PER_TICK);
927  Serial.print(F(" is not "));
928  Serial.print(aOneSpaceMicros);
929  Serial.print(F(" or "));
930  Serial.print(aZeroSpaceMicros);
931  Serial.print(F(". Index="));
932  Serial.print(aNumberOfBits - i);
933  Serial.print(' ');
934 #endif
935  return false;
936  }
937  } else {
938  if (!matchMark(tMarkTicks, aZeroMarkMicros)) {
939 #if defined(LOCAL_DEBUG)
940  Serial.print(F("Mark="));
941  Serial.print(tMarkTicks * MICROS_PER_TICK);
942  Serial.print(F(" is not "));
943  Serial.print(aOneMarkMicros);
944  Serial.print(F(" or "));
945  Serial.print(aZeroMarkMicros);
946  Serial.print(F(". Index="));
947  Serial.print(aNumberOfBits - i);
948  Serial.print(' ');
949 #endif
950  return false;
951  }
952  }
953  // do not set the bit
954  IR_TRACE_PRINTLN(F("=> 0"));
955  }
956  // If we have no stop bit, assume that last space, which is not recorded, is correct, since we can not check it
957  if (aZeroSpaceMicros == aOneSpaceMicros
958  && tRawBufPointer < &decodedIRData.rawDataPtr->rawbuf[decodedIRData.rawDataPtr->rawlen]) {
959  // Check for constant length space (of pulse width protocol) here
960  if (!matchSpace(tSpaceTicks, aOneSpaceMicros)) {
961 #if defined(LOCAL_DEBUG)
962  Serial.print(F("Space="));
963  Serial.print(tSpaceTicks * MICROS_PER_TICK);
964  Serial.print(F(" is not "));
965  Serial.print(aOneSpaceMicros);
966  Serial.print(F(". Index="));
967  Serial.print(aNumberOfBits - i);
968  Serial.print(' ');
969 #endif
970  return false;
971  }
972  }
973  tMask <<= 1;
974  }
975  decodedIRData.decodedRawData = tDecodedData;
976  return true;
977 }
978 
983 bool IRrecv::decodePulseDistanceWidthData(PulseDistanceWidthProtocolConstants *aProtocolConstants, uint_fast8_t aNumberOfBits,
984  IRRawlenType aStartOffset) {
985 
986  return decodePulseDistanceWidthData(aNumberOfBits, aStartOffset, aProtocolConstants->DistanceWidthTimingInfo.OneMarkMicros,
987  aProtocolConstants->DistanceWidthTimingInfo.OneSpaceMicros, aProtocolConstants->DistanceWidthTimingInfo.ZeroMarkMicros,
988  aProtocolConstants->Flags);
989 }
990 
992  uint_fast8_t aNumberOfBits, IRRawlenType aStartOffset) {
993  PulseDistanceWidthProtocolConstants tTemporaryPulseDistanceWidthProtocolConstants;
994  memcpy_P(&tTemporaryPulseDistanceWidthProtocolConstants, aProtocolConstantsPGM,
995  sizeof(tTemporaryPulseDistanceWidthProtocolConstants));
996 
997  return decodePulseDistanceWidthData(&tTemporaryPulseDistanceWidthProtocolConstants, aNumberOfBits, aStartOffset);
998 }
999 
1000 /*
1001  * Static variables for the getBiphaselevel function
1002  */
1003 uint_fast8_t sBiphaseDecodeRawbuffOffset; // Index into raw timing array
1004 uint16_t sBiphaseCurrentTimingIntervals; // 1, 2 or 3. Number of aBiphaseTimeUnit intervals of the current rawbuf[sBiphaseDecodeRawbuffOffset] timing.
1005 uint_fast8_t sBiphaseUsedTimingIntervals; // Number of already used intervals of sCurrentTimingIntervals.
1007 
1008 void IRrecv::initBiphaselevel(uint_fast8_t aRCDecodeRawbuffOffset, uint16_t aBiphaseTimeUnit) {
1009  sBiphaseDecodeRawbuffOffset = aRCDecodeRawbuffOffset;
1010  sBiphaseTimeUnit = aBiphaseTimeUnit;
1012 }
1013 
1030 uint_fast8_t IRrecv::getBiphaselevel() {
1031  uint_fast8_t tLevelOfCurrentInterval; // 0 (SPACE) or 1 (MARK)
1032 
1034  return SPACE; // After end of recorded buffer, assume space.
1035  }
1036 
1037  tLevelOfCurrentInterval = (sBiphaseDecodeRawbuffOffset) & 1; // on odd rawbuf offsets we have mark timings
1038 
1039  /*
1040  * Setup data if sUsedTimingIntervals is 0
1041  */
1042  if (sBiphaseUsedTimingIntervals == 0) {
1043  uint16_t tCurrentTimingWith = decodedIRData.rawDataPtr->rawbuf[sBiphaseDecodeRawbuffOffset];
1044  uint16_t tMarkExcessCorrection = (tLevelOfCurrentInterval == MARK) ? MARK_EXCESS_MICROS : -MARK_EXCESS_MICROS;
1045 
1046  if (matchTicks(tCurrentTimingWith, sBiphaseTimeUnit + tMarkExcessCorrection)) {
1048  } else if (matchTicks(tCurrentTimingWith, (2 * sBiphaseTimeUnit) + tMarkExcessCorrection)) {
1050  } else if (matchTicks(tCurrentTimingWith, (3 * sBiphaseTimeUnit) + tMarkExcessCorrection)) {
1052  } else {
1053  return -1;
1054  }
1055  }
1056 
1057 // We use another interval from tCurrentTimingIntervals
1059 
1060 // keep track of current timing offset
1062  // we have used all intervals of current timing, switch to next timing value
1065  }
1066 
1067  IR_TRACE_PRINTLN(tLevelOfCurrentInterval);
1068 
1069  return tLevelOfCurrentInterval;
1070 }
1071 
1072 /**********************************************************************************************************************
1073  * Internal Hash decode function
1074  **********************************************************************************************************************/
1075 #define FNV_PRIME_32 16777619
1076 #define FNV_BASIS_32 2166136261
1078 
1083 uint_fast8_t IRrecv::compare(uint16_t oldval, uint16_t newval) {
1084  if (newval * 10 < oldval * 8) {
1085  return 0;
1086  }
1087  if (oldval * 10 < newval * 8) {
1088  return 2;
1089  }
1090  return 1;
1091 }
1092 
1111  unsigned long hash = FNV_BASIS_32; // the result is the same no matter if we use a long or unsigned long variable
1112 
1113 // Require at least 6 samples to prevent triggering on noise
1114  if (decodedIRData.rawlen < 6) {
1115  IR_DEBUG_PRINT(F("HASH: "));
1116  IR_DEBUG_PRINT(F("Data length="));
1118  IR_DEBUG_PRINTLN(F(" is less than 6"));
1119  return false;
1120  }
1121  for (IRRawlenType i = 1; (i + 2) < decodedIRData.rawlen; i++) {
1122  // Compare mark with mark and space with space
1123  uint_fast8_t value = compare(decodedIRData.rawDataPtr->rawbuf[i], decodedIRData.rawDataPtr->rawbuf[i + 2]);
1124  // Add value into the hash
1125  hash = (hash * FNV_PRIME_32) ^ value;
1126  }
1127 
1131 
1132  return true;
1133 }
1134 
1136  unsigned long hash = FNV_BASIS_32;
1137 
1138 // Require at least 6 samples to prevent triggering on noise
1139  if (aResults->rawlen < 6) {
1140  return false;
1141  }
1142 
1143  for (uint8_t i = 3; i < aResults->rawlen; i++) {
1144  uint_fast8_t value = compare(aResults->rawbuf[i - 2], aResults->rawbuf[i]);
1145  // Add value into the hash
1146  hash = (hash * FNV_PRIME_32) ^ value;
1147  }
1148 
1149  aResults->value = hash;
1150  aResults->bits = 32;
1151  aResults->decode_type = UNKNOWN;
1153 
1154  return true;
1155 }
1156 
1157 /**********************************************************************************************************************
1158  * Match functions
1159  **********************************************************************************************************************/
1160 
1161 /*
1162  * returns true if values do match
1163  */
1165 // Check header "mark" and "space"
1167 #if defined(LOCAL_TRACE)
1168  Serial.print(::getProtocolString(aProtocolConstants->ProtocolIndex));
1169  Serial.println(F(": Header mark length is wrong"));
1170 #endif
1171  return false;
1172  }
1174 #if defined(LOCAL_TRACE)
1175  Serial.print(::getProtocolString(aProtocolConstants->ProtocolIndex));
1176  Serial.println(F(": Header space length is wrong"));
1177 #endif
1178  return false;
1179  }
1180  return true;
1181 }
1182 
1184 // Check header "mark" and "space"
1185  if (!matchMark(decodedIRData.rawDataPtr->rawbuf[1], pgm_read_word(&aProtocolConstantsPGM->DistanceWidthTimingInfo.HeaderMarkMicros))) {
1186 #if defined(LOCAL_TRACE)
1187  Serial.print(::getProtocolString(aProtocolConstants->ProtocolIndex));
1188  Serial.println(F(": Header mark length is wrong"));
1189 #endif
1190  return false;
1191  }
1192  if (!matchSpace(decodedIRData.rawDataPtr->rawbuf[2], pgm_read_word(&aProtocolConstantsPGM->DistanceWidthTimingInfo.HeaderSpaceMicros))) {
1193 #if defined(LOCAL_TRACE)
1194  Serial.print(::getProtocolString(aProtocolConstants->ProtocolIndex));
1195  Serial.println(F(": Header space length is wrong"));
1196 #endif
1197  return false;
1198  }
1199  return true;
1200 }
1201 
1202 /*
1203  * Does not check for same address and command, because it is almost not possible to press 2 different buttons on the remote within around 100 ms.
1204  * And if really required, it can be enabled here, or done manually in user program.
1205  * And we have still no RC6 toggle bit check for detecting a second press on the same button.
1206  */
1207 void IRrecv::checkForRepeatSpaceTicksAndSetFlag(uint16_t aMaximumRepeatSpaceTicks) {
1208  if (decodedIRData.initialGapTicks < aMaximumRepeatSpaceTicks
1209 #if defined(ENABLE_COMPLETE_REPEAT_CHECK)
1210 // Check also for same command and address values to detect a repeat. Not sensible for standard protocols, because it is almost not possible to press 2 different buttons on the remote within around 100 ms
1211  && decodedIRData.address == lastDecodedAddress && decodedIRData.command == lastDecodedCommand /* requires around 44 bytes program space */
1212 #endif
1213  ) {
1215  }
1216 }
1217 
1223 bool matchTicks(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros) {
1224 #if defined(LOCAL_TRACE)
1225  Serial.print(F("Testing: "));
1226  Serial.print(TICKS_LOW(aMatchValueMicros), DEC);
1227  Serial.print(F(" <= "));
1228  Serial.print(aMeasuredTicks, DEC);
1229  Serial.print(F(" <= "));
1230  Serial.print(TICKS_HIGH(aMatchValueMicros), DEC);
1231 #endif
1232  bool passed = ((aMeasuredTicks >= TICKS_LOW(aMatchValueMicros)) && (aMeasuredTicks <= TICKS_HIGH(aMatchValueMicros)));
1233 #if defined(LOCAL_TRACE)
1234  if (passed) {
1235  Serial.println(F(" => passed"));
1236  } else {
1237  Serial.println(F(" => FAILED"));
1238  }
1239 #endif
1240  return passed;
1241 }
1242 
1243 bool MATCH(uint16_t measured_ticks, uint16_t desired_us) {
1244  return matchTicks(measured_ticks, desired_us);
1245 }
1246 
1251 bool matchMark(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros) {
1252 #if defined(LOCAL_TRACE)
1253  Serial.print(F("Testing mark (actual vs desired): "));
1254  Serial.print(aMeasuredTicks * MICROS_PER_TICK, DEC);
1255  Serial.print(F("us vs "));
1256  Serial.print(aMatchValueMicros, DEC);
1257  Serial.print(F("us: "));
1258  Serial.print(TICKS_LOW(aMatchValueMicros + MARK_EXCESS_MICROS) * MICROS_PER_TICK, DEC);
1259  Serial.print(F(" <= "));
1260  Serial.print(aMeasuredTicks * MICROS_PER_TICK, DEC);
1261  Serial.print(F(" <= "));
1262  Serial.print(TICKS_HIGH(aMatchValueMicros + MARK_EXCESS_MICROS) * MICROS_PER_TICK, DEC);
1263 #endif
1264  // compensate for marks exceeded by demodulator hardware
1265  bool passed = ((aMeasuredTicks >= TICKS_LOW(aMatchValueMicros + MARK_EXCESS_MICROS))
1266  && (aMeasuredTicks <= TICKS_HIGH(aMatchValueMicros + MARK_EXCESS_MICROS)));
1267 #if defined(LOCAL_TRACE)
1268  if (passed) {
1269  Serial.println(F(" => passed"));
1270  } else {
1271  Serial.println(F(" => FAILED"));
1272  }
1273 #endif
1274  return passed;
1275 }
1276 
1277 bool MATCH_MARK(uint16_t measured_ticks, uint16_t desired_us) {
1278  return matchMark(measured_ticks, desired_us);
1279 }
1280 
1285 bool matchSpace(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros) {
1286 #if defined(LOCAL_TRACE)
1287  Serial.print(F("Testing space (actual vs desired): "));
1288  Serial.print(aMeasuredTicks * MICROS_PER_TICK, DEC);
1289  Serial.print(F("us vs "));
1290  Serial.print(aMatchValueMicros, DEC);
1291  Serial.print(F("us: "));
1292  Serial.print(TICKS_LOW(aMatchValueMicros - MARK_EXCESS_MICROS) * MICROS_PER_TICK, DEC);
1293  Serial.print(F(" <= "));
1294  Serial.print(aMeasuredTicks * MICROS_PER_TICK, DEC);
1295  Serial.print(F(" <= "));
1296  Serial.print(TICKS_HIGH(aMatchValueMicros - MARK_EXCESS_MICROS) * MICROS_PER_TICK, DEC);
1297 #endif
1298  // compensate for spaces shortened by demodulator hardware
1299  bool passed = ((aMeasuredTicks >= TICKS_LOW(aMatchValueMicros - MARK_EXCESS_MICROS))
1300  && (aMeasuredTicks <= TICKS_HIGH(aMatchValueMicros - MARK_EXCESS_MICROS)));
1301 #if defined(LOCAL_TRACE)
1302  if (passed) {
1303  Serial.println(F(" => passed"));
1304  } else {
1305  Serial.println(F(" => FAILED"));
1306  }
1307 #endif
1308  return passed;
1309 }
1310 
1311 bool MATCH_SPACE(uint16_t measured_ticks, uint16_t desired_us) {
1312  return matchSpace(measured_ticks, desired_us);
1313 }
1314 
1319  return MARK_EXCESS_MICROS;
1320 }
1321 
1327 bool IRrecv::checkForRecordGapsMicros(Print *aSerial) {
1328  /*
1329  * Check if protocol is not detected and detected space between two transmissions
1330  * is smaller than known value for protocols (Sony with around 24 ms)
1331  */
1334  aSerial->println();
1335  aSerial->print(F("Space of "));
1336  aSerial->print(decodedIRData.initialGapTicks * MICROS_PER_TICK);
1337  aSerial->print(F(" us between two detected transmission is smaller than the minimal gap of "));
1338  aSerial->print(RECORD_GAP_MICROS_WARNING_THRESHOLD);
1339  aSerial->println(F(" us known for implemented protocols like NEC, Sony, RC% etc.."));
1340  aSerial->println(F("But it can be OK for some yet unsupported protocols, and especially for repeats."));
1341  aSerial->println(F("If you get unexpected results, try to increase the RECORD_GAP_MICROS in IRremote.h."));
1342  aSerial->println();
1343  return true;
1344  }
1345  return false;
1346 }
1347 
1348 /**********************************************************************************************************************
1349  * Print functions
1350  * Since a library should not allocate the "Serial" object, all functions require a pointer to a Print object.
1351  **********************************************************************************************************************/
1352 void IRrecv::printActiveIRProtocols(Print *aSerial) {
1353 // call no class function with same name
1354  ::printActiveIRProtocols(aSerial);
1355 }
1356 /*
1357  * Prints a list of enabled protocols for this application.
1358  * @param aSerial pointer to serial used for printing. Use "&Serial".
1359  */
1360 void printActiveIRProtocols(Print *aSerial) {
1361 #if defined(DECODE_ONKYO)
1362  aSerial->print(F("Onkyo, "));
1363 #elif defined(DECODE_NEC)
1364  aSerial->print(F("NEC/NEC2/Onkyo/Apple, "));
1365 #endif
1366 #if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO)
1367  aSerial->print(F("Panasonic/Kaseikyo, "));
1368 #endif
1369 #if defined(DECODE_DENON)
1370  aSerial->print(F("Denon/Sharp, "));
1371 #endif
1372 #if defined(DECODE_SONY)
1373  aSerial->print(F("Sony, "));
1374 #endif
1375 #if defined(DECODE_RC5)
1376  aSerial->print(F("RC5, "));
1377 #endif
1378 #if defined(DECODE_RC6)
1379  aSerial->print(F("RC6, "));
1380 #endif
1381 #if defined(DECODE_LG)
1382  aSerial->print(F("LG, "));
1383 #endif
1384 #if defined(DECODE_JVC)
1385  aSerial->print(F("JVC, "));
1386 #endif
1387 #if defined(DECODE_SAMSUNG)
1388  aSerial->print(F("Samsung, "));
1389 #endif
1390  /*
1391  * Start of the exotic protocols
1392  */
1393 #if defined(DECODE_BEO)
1394  aSerial->print(F("Bang & Olufsen, "));
1395 #endif
1396 #if defined(DECODE_FAST)
1397  aSerial->print(F("FAST, "));
1398 #endif
1399 #if defined(DECODE_WHYNTER)
1400  aSerial->print(F("Whynter, "));
1401 #endif
1402 #if defined(DECODE_LEGO_PF)
1403  aSerial->print(F("Lego Power Functions, "));
1404 #endif
1405 #if defined(DECODE_BOSEWAVE)
1406  aSerial->print(F("Bosewave, "));
1407 #endif
1408 #if defined(DECODE_MAGIQUEST)
1409  aSerial->print(F("MagiQuest, "));
1410 #endif
1411 #if defined(DECODE_DISTANCE_WIDTH)
1412  aSerial->print(F("Universal Pulse Distance Width, "));
1413 #endif
1414 #if defined(DECODE_HASH)
1415  aSerial->print(F("Hash "));
1416 #endif
1417 #if defined(NO_DECODER) // for sending raw only
1418  (void)aSerial; // to avoid compiler warnings
1419 #endif
1420 }
1421 
1431 bool IRrecv::printIRResultShort(Print *aSerial, bool aCheckForRecordGapsMicros) {
1432 // call no class function with same name
1434  if (aCheckForRecordGapsMicros && decodedIRData.protocol != UNKNOWN) {
1435  return checkForRecordGapsMicros(aSerial);
1436  }
1437  return false;
1438 }
1439 
1440 void IRrecv::printDistanceWidthTimingInfo(Print *aSerial, DistanceWidthTimingInfoStruct *aDistanceWidthTimingInfo) {
1441  aSerial->print(aDistanceWidthTimingInfo->HeaderMarkMicros);
1442  aSerial->print(F(", "));
1443  aSerial->print(aDistanceWidthTimingInfo->HeaderSpaceMicros);
1444  aSerial->print(F(", "));
1445  aSerial->print(aDistanceWidthTimingInfo->OneMarkMicros);
1446  aSerial->print(F(", "));
1447  aSerial->print(aDistanceWidthTimingInfo->OneSpaceMicros);
1448  aSerial->print(F(", "));
1449  aSerial->print(aDistanceWidthTimingInfo->ZeroMarkMicros);
1450  aSerial->print(F(", "));
1451  aSerial->print(aDistanceWidthTimingInfo->ZeroSpaceMicros);
1452 }
1453 
1454 /*
1455  * Get maximum of mark ticks in rawDataPtr.
1456  * Skip leading start and trailing stop bit.
1457  */
1459  uint8_t tMaximumTick = 0;
1460  for (IRRawlenType i = 3; i < decodedIRData.rawlen - 2; i += 2) { // Skip leading start and trailing stop bit.
1461  auto tTick = decodedIRData.rawDataPtr->rawbuf[i];
1462  if (tMaximumTick < tTick) {
1463  tMaximumTick = tTick;
1464  }
1465  }
1466  return tMaximumTick;
1467 }
1469  uint8_t tMaximumTick = 0;
1470  for (IRRawlenType i = 4; i < decodedIRData.rawlen - 2; i += 2) { // Skip leading start and trailing stop bit.
1471  auto tTick = decodedIRData.rawDataPtr->rawbuf[i];
1472  if (tMaximumTick < tTick) {
1473  tMaximumTick = tTick;
1474  }
1475  }
1476  return tMaximumTick;
1477 }
1478 
1479 /*
1480  * The optimizing compiler internally generates this function, if getMaximumMarkTicksFromRawData() and getMaximumSpaceTicksFromRawData() is used.
1481  */
1482 uint8_t IRrecv::getMaximumTicksFromRawData(bool aSearchSpaceInsteadOfMark) {
1483  uint8_t tMaximumTick = 0;
1484  IRRawlenType i;
1485  if (aSearchSpaceInsteadOfMark) {
1486  i = 4;
1487  } else {
1488  i = 3;
1489  }
1490  for (; i < decodedIRData.rawlen - 2; i += 2) { // Skip leading start and trailing stop bit.
1491  auto tTick = decodedIRData.rawDataPtr->rawbuf[i];
1492  if (tMaximumTick < tTick) {
1493  tMaximumTick = tTick;
1494  }
1495  }
1496  return tMaximumTick;
1497 }
1498 
1500  uint16_t tSumOfDurationTicks = 0;
1501 
1502  for (IRRawlenType i = 1; i < decodedIRData.rawlen; i++) {
1503  tSumOfDurationTicks += decodedIRData.rawDataPtr->rawbuf[i];
1504  }
1505  return tSumOfDurationTicks * (uint32_t) MICROS_PER_TICK;
1506 }
1507 
1516 void IRrecv::printIRSendUsage(Print *aSerial) {
1520 #if defined(DECODE_DISTANCE_WIDTH)
1521  uint_fast8_t tNumberOfArrayData = 0;
1523 # if __INT_WIDTH__ < 32
1524  aSerial->print(F("Send on a 8 bit platform with: "));
1525  tNumberOfArrayData = ((decodedIRData.numberOfBits - 1) / 32) + 1;
1526  if(tNumberOfArrayData > 1) {
1527  aSerial->println();
1528  aSerial->print(F(" uint32_t tRawData[]={0x"));
1529 # else
1530  aSerial->print(F("Send on a 32 bit platform with: "));
1531  tNumberOfArrayData = ((decodedIRData.numberOfBits - 1) / 64) + 1;
1532  if(tNumberOfArrayData > 1) {
1533  aSerial->println();
1534  aSerial->print(F(" uint64_t tRawData[]={0x"));
1535 # endif
1536  for (uint_fast8_t i = 0; i < tNumberOfArrayData; ++i) {
1537 # if (__INT_WIDTH__ < 32)
1538  aSerial->print(decodedIRData.decodedRawDataArray[i], HEX);
1539 # else
1540  PrintULL::print(aSerial, decodedIRData.decodedRawDataArray[i], HEX);
1541 # endif
1542  if (i != tNumberOfArrayData - 1) {
1543  aSerial->print(F(", 0x"));
1544  }
1545  }
1546  aSerial->println(F("};"));
1547  aSerial->print(F(" "));
1548  }
1549  } else {
1550  aSerial->print(F("Send with: "));
1551  }
1552  aSerial->print(F("IrSender.send"));
1553 
1554 #else
1555  aSerial->print(F("Send with: IrSender.send"));
1556 #endif
1557 
1558 #if defined(DECODE_DISTANCE_WIDTH)
1560 #endif
1561  aSerial->print(getProtocolString());
1562  aSerial->print(F("(0x"));
1563 #if defined(DECODE_MAGIQUEST)
1564  if (decodedIRData.protocol == MAGIQUEST) {
1565 # if (__INT_WIDTH__ < 32)
1566  aSerial->print(decodedIRData.decodedRawData, HEX);
1567 # else
1568  PrintULL::print(aSerial, decodedIRData.decodedRawData, HEX);
1569 # endif
1570  } else {
1571  aSerial->print(decodedIRData.address, HEX);
1572  }
1573 #else
1574  /*
1575  * New decoders have address and command
1576  */
1577  aSerial->print(decodedIRData.address, HEX);
1578 #endif
1579 
1580  aSerial->print(F(", 0x"));
1581  aSerial->print(decodedIRData.command, HEX);
1582  if (decodedIRData.protocol == SONY) {
1583  aSerial->print(F(", 2, "));
1584  aSerial->print(decodedIRData.numberOfBits);
1585  } else {
1586  aSerial->print(F(", <numberOfRepeats>"));
1587  }
1588 
1589 #if defined(DECODE_DISTANCE_WIDTH)
1590  } else {
1591  /*
1592  * Pulse distance or pulse width here
1593  */
1594  aSerial->print(F("PulseDistanceWidth"));
1595  if(tNumberOfArrayData > 1) {
1596  aSerial->print(F("FromArray(38, "));
1597  } else {
1598  aSerial->print(F("(38, "));
1599  }
1600  printDistanceWidthTimingInfo(aSerial, &decodedIRData.DistanceWidthTimingInfo);
1601 
1602  if(tNumberOfArrayData > 1) {
1603  aSerial->print(F(", &tRawData[0], "));
1604  } else {
1605  aSerial->print(F(", 0x"));
1606 # if (__INT_WIDTH__ < 32)
1607  aSerial->print(decodedIRData.decodedRawData, HEX);
1608 # else
1609  PrintULL::print(aSerial, decodedIRData.decodedRawData, HEX);
1610 # endif
1611  aSerial->print(F(", "));
1612  }
1613  aSerial->print(decodedIRData.numberOfBits);// aNumberOfBits
1614  aSerial->print(F(", PROTOCOL_IS_"));
1615 
1617  aSerial->print('M');
1618  } else {
1619  aSerial->print('L');
1620  }
1621  aSerial->print(F("SB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>"));
1622  }
1623 #endif
1624 #if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO) || defined(DECODE_RC6)
1626  aSerial->print(F(", 0x"));
1627  aSerial->print(decodedIRData.extra, HEX);
1628  }
1629 #endif
1630  aSerial->print(F(");"));
1631  aSerial->println();
1632  }
1633 }
1634 
1641 void IRrecv::printIRResultMinimal(Print *aSerial) {
1642  aSerial->print(F("P="));
1643  aSerial->print(decodedIRData.protocol);
1644  if (decodedIRData.protocol == UNKNOWN) {
1645 #if defined(DECODE_HASH)
1646  aSerial->print(F(" #=0x"));
1647 # if (__INT_WIDTH__ < 32)
1648  aSerial->print(decodedIRData.decodedRawData, HEX);
1649 # else
1650  PrintULL::print(aSerial, decodedIRData.decodedRawData, HEX);
1651 # endif
1652 #endif
1653  aSerial->print(' ');
1654  aSerial->print((decodedIRData.rawlen + 1) / 2, DEC);
1655  aSerial->println(F(" bits received"));
1656  } else {
1657  /*
1658  * New decoders have address and command
1659  */
1660  aSerial->print(F(" A=0x"));
1661  aSerial->print(decodedIRData.address, HEX);
1662 
1663  aSerial->print(F(" C=0x"));
1664  aSerial->print(decodedIRData.command, HEX);
1665 
1666  aSerial->print(F(" Raw=0x"));
1667 #if (__INT_WIDTH__ < 32)
1668  aSerial->print(decodedIRData.decodedRawData, HEX);
1669 #else
1670  PrintULL::print(aSerial, decodedIRData.decodedRawData, HEX);
1671 #endif
1672 
1674  aSerial->print(F(" R"));
1675  }
1676  }
1677 }
1678 
1679 /*
1680  * Not used yet
1681  */
1682 void IRrecv::printIRDuration(Print *aSerial, bool aOutputMicrosecondsInsteadOfTicks) {
1683  uint16_t tSumOfDurationTicks = 0;
1684  for (IRRawlenType i = 1; i < decodedIRData.rawlen; i++) {
1685  tSumOfDurationTicks += decodedIRData.rawDataPtr->rawbuf[i];
1686  }
1687  aSerial->print(F("Duration="));
1688  if (aOutputMicrosecondsInsteadOfTicks) {
1689  aSerial->print((uint32_t) tSumOfDurationTicks * MICROS_PER_TICK, DEC);
1690  aSerial->println(F("us"));
1691 
1692  } else {
1693  aSerial->print(tSumOfDurationTicks, DEC);
1694  aSerial->println(F(" ticks"));
1695  }
1696 }
1697 
1704 void IRrecv::printIRResultRawFormatted(Print *aSerial, bool aOutputMicrosecondsInsteadOfTicks) {
1705 
1706 // Print Raw data
1707  aSerial->print(F("rawData["));
1708  aSerial->print(decodedIRData.rawlen, DEC);
1709  aSerial->println(F("]: "));
1710 
1711  /*
1712  * Print initial gap
1713  */
1714  aSerial->print(F(" -"));
1715  if (aOutputMicrosecondsInsteadOfTicks) {
1716  aSerial->println((uint32_t) decodedIRData.initialGapTicks * MICROS_PER_TICK, DEC);
1717  } else {
1718  aSerial->println(decodedIRData.initialGapTicks, DEC);
1719  }
1720 
1721 // Newline is printed every 8. value, if tCounterForNewline % 8 == 0
1722  uint_fast8_t tCounterForNewline = 6; // first newline is after the 2 values of the start bit
1723 
1724 // check if we have a protocol with no or 8 start bits
1725 #if defined(DECODE_DENON) || defined(DECODE_MAGIQUEST)
1726  if (
1727 # if defined(DECODE_DENON)
1729 # endif
1730 # if defined(DECODE_MAGIQUEST)
1732 # endif
1733  false) {
1734  tCounterForNewline = 0; // no or 8 start bits
1735  }
1736 #endif
1737 
1738  uint32_t tDuration;
1739  uint16_t tSumOfDurationTicks = 0;
1740  for (IRRawlenType i = 1; i < decodedIRData.rawlen; i++) {
1741  auto tCurrentTicks = decodedIRData.rawDataPtr->rawbuf[i];
1742  if (aOutputMicrosecondsInsteadOfTicks) {
1743  tDuration = tCurrentTicks * MICROS_PER_TICK;
1744  } else {
1745  tDuration = tCurrentTicks;
1746  }
1747  tSumOfDurationTicks += tCurrentTicks; // compute length of protocol frame
1748 
1749  if (!(i & 1)) { // even
1750  aSerial->print('-');
1751  } else { // odd
1752  aSerial->print(F(" +"));
1753  }
1754 
1755  // padding only for big values
1756  if (aOutputMicrosecondsInsteadOfTicks && tDuration < 1000) {
1757  aSerial->print(' ');
1758  }
1759  if (aOutputMicrosecondsInsteadOfTicks && tDuration < 100) {
1760  aSerial->print(' ');
1761  }
1762  if (tDuration < 10) {
1763  aSerial->print(' ');
1764  }
1765  aSerial->print(tDuration, DEC);
1766 
1767  if ((i & 1) && (i + 1) < decodedIRData.rawlen) {
1768  aSerial->print(','); //',' not required for last one
1769  }
1770 
1771  tCounterForNewline++;
1772  if ((tCounterForNewline % 8) == 0) {
1773  aSerial->println();
1774  }
1775  }
1776 
1777  aSerial->println();
1778  aSerial->print(F("Duration="));
1779  if (aOutputMicrosecondsInsteadOfTicks) {
1780  aSerial->print((uint32_t) tSumOfDurationTicks * MICROS_PER_TICK, DEC);
1781  aSerial->println(F("us"));
1782 
1783  } else {
1784  aSerial->print(tSumOfDurationTicks, DEC);
1785  aSerial->println(F(" ticks"));
1786  }
1787  aSerial->println();
1788 
1789 }
1790 
1802 void IRrecv::compensateAndPrintIRResultAsCArray(Print *aSerial, bool aOutputMicrosecondsInsteadOfTicks) {
1803 // Start declaration
1804  if (aOutputMicrosecondsInsteadOfTicks) {
1805  aSerial->print(F("uint16_t rawData[")); // variable type, array name
1806  } else {
1807  aSerial->print(F("uint8_t rawTicks[")); // variable type, array name
1808  }
1809 
1810  aSerial->print(decodedIRData.rawlen - 1, DEC); // array size
1811  aSerial->print(F("] = {")); // Start declaration
1812 
1813 // Dump data
1814  for (IRRawlenType i = 1; i < decodedIRData.rawlen; i++) {
1815  uint32_t tDuration = decodedIRData.rawDataPtr->rawbuf[i] * MICROS_PER_TICK;
1816 
1817  if (i & 1) {
1818  // Mark
1819  tDuration -= MARK_EXCESS_MICROS;
1820  } else {
1821  tDuration += MARK_EXCESS_MICROS;
1822  }
1823 
1824  if (aOutputMicrosecondsInsteadOfTicks) {
1825  aSerial->print(tDuration);
1826  } else {
1827  unsigned int tTicks = (tDuration + (MICROS_PER_TICK / 2)) / MICROS_PER_TICK;
1828  /*
1829  * Clip to 8 bit value
1830  */
1831  tTicks = (tTicks > UINT8_MAX) ? UINT8_MAX : tTicks;
1832  aSerial->print(tTicks);
1833  }
1834  if (i + 1 < decodedIRData.rawlen) aSerial->print(','); // ',' not required on last one
1835  if (!(i & 1)) aSerial->print(' ');
1836  }
1837 
1838 // End declaration
1839  aSerial->print(F("};")); //
1840 
1841 // Comment
1842  aSerial->print(F(" // "));
1843  printIRResultShort(aSerial);
1844 
1845 // Newline
1846  aSerial->println();
1847 }
1848 
1859 
1860 // Store data, skip leading space#
1861  IRRawlenType i;
1862  for (i = 1; i < decodedIRData.rawlen; i++) {
1863  uint32_t tDuration = decodedIRData.rawDataPtr->rawbuf[i] * MICROS_PER_TICK;
1864  if (i & 1) {
1865  // Mark
1866  tDuration -= MARK_EXCESS_MICROS;
1867  } else {
1868  tDuration += MARK_EXCESS_MICROS;
1869  }
1870 
1871  unsigned int tTicks = (tDuration + (MICROS_PER_TICK / 2)) / MICROS_PER_TICK;
1872  *aArrayPtr = (tTicks > UINT8_MAX) ? UINT8_MAX : tTicks; // we store it in an 8 bit array
1873  aArrayPtr++;
1874  }
1875 }
1876 
1882 // Now dump "known" codes
1883  if (decodedIRData.protocol != UNKNOWN) {
1884 
1885  /*
1886  * New decoders have address and command
1887  */
1888  aSerial->print(F("uint16_t"));
1889  aSerial->print(F(" address = 0x"));
1890  aSerial->print(decodedIRData.address, HEX);
1891  aSerial->println(';');
1892 
1893  aSerial->print(F("uint16_t"));
1894  aSerial->print(F(" command = 0x"));
1895  aSerial->print(decodedIRData.command, HEX);
1896  aSerial->println(';');
1897 
1898  // All protocols have raw data
1899 #if __INT_WIDTH__ < 32
1900  aSerial->print(F("uint32_t rawData = 0x"));
1901 #else
1902  aSerial->print(F("uint64_t rawData = 0x"));
1903 #endif
1904 #if (__INT_WIDTH__ < 32)
1905  aSerial->print(decodedIRData.decodedRawData, HEX);
1906 #else
1907  PrintULL::print(aSerial, decodedIRData.decodedRawData, HEX);
1908 #endif
1909  aSerial->println(';');
1910  aSerial->println();
1911  }
1912 }
1913 
1914 #if defined(__AVR__)
1915 const __FlashStringHelper* IRrecv::getProtocolString() {
1916 // call no class function with same name
1918 }
1919 #else
1921  // call no class function with same name
1923 }
1924 #endif
1925 
1926 /**********************************************************************************************************************
1927  * The OLD and DEPRECATED decode function with parameter aResults, kept for backward compatibility to old 2.0 tutorials
1928  * This function calls the old MSB first decoders and fills only the 3 variables:
1929  * aResults->value
1930  * aResults->bits
1931  * aResults->decode_type
1932  **********************************************************************************************************************/
1934 
1936  return false;
1937  }
1938 
1939 // copy for usage by legacy programs
1940  aResults->rawbuf[0] = irparams.initialGapTicks;
1941  for (int i = 1; i < RAW_BUFFER_LENGTH; ++i) {
1942  aResults->rawbuf[i] = irparams.rawbuf[i]; // copy 8 bit array into a 16 bit array
1943  }
1944  aResults->rawlen = irparams.rawlen;
1945  if (irparams.OverflowFlag) {
1946  // Copy overflow flag to decodedIRData.flags
1947  irparams.OverflowFlag = false;
1948  irparams.rawlen = 0; // otherwise we have OverflowFlag again at next ISR call
1949  IR_DEBUG_PRINTLN(F("Overflow happened"));
1950  }
1951  aResults->overflow = irparams.OverflowFlag;
1952  aResults->value = 0;
1953 
1955 
1956 #if defined(DECODE_NEC)
1957  IR_DEBUG_PRINTLN(F("Attempting old NEC decode"));
1958  if (decodeNECMSB(aResults)) {
1959  return true;
1960  }
1961 #endif
1962 
1963 #if defined(DECODE_SONY)
1964  IR_DEBUG_PRINTLN(F("Attempting old Sony decode"));
1965  if (decodeSonyMSB(aResults)) {
1966  return true;
1967  }
1968 #endif
1969 
1970 #if defined(DECODE_RC5)
1971  IR_DEBUG_PRINTLN(F("Attempting RC5 decode"));
1972  if (decodeRC5()) {
1973  aResults->bits = decodedIRData.numberOfBits;
1974  aResults->value = decodedIRData.decodedRawData;
1975  aResults->decode_type = RC5;
1976 
1977  return true;
1978  }
1979 #endif
1980 
1981 #if defined(DECODE_RC6)
1982  IR_DEBUG_PRINTLN(F("Attempting RC6 decode"));
1983  if (decodeRC6()) {
1984  aResults->bits = decodedIRData.numberOfBits;
1985  aResults->value = decodedIRData.decodedRawData;
1986  aResults->decode_type = RC6;
1987  return true;
1988  }
1989 #endif
1990 
1991 // Removed bool IRrecv::decodePanasonicMSB(decode_results *aResults) since implementations was wrong (wrong length), and nobody recognized it
1992 
1993 #if defined(DECODE_LG)
1994  IR_DEBUG_PRINTLN(F("Attempting old LG decode"));
1995  if (decodeLGMSB(aResults)) {return true;}
1996 #endif
1997 
1998 #if defined(DECODE_JVC)
1999  IR_DEBUG_PRINTLN(F("Attempting old JVC decode"));
2000  if (decodeJVCMSB(aResults)) {
2001  return true;
2002  }
2003 #endif
2004 
2005 #if defined(DECODE_SAMSUNG)
2006  IR_DEBUG_PRINTLN(F("Attempting old SAMSUNG decode"));
2007  if (decodeSAMSUNG(aResults)) {
2008  return true;
2009  }
2010 #endif
2011 
2012 #if defined(DECODE_DENON)
2013  IR_DEBUG_PRINTLN(F("Attempting old Denon decode"));
2014  if (decodeDenonOld(aResults)) {
2015  return true;
2016  }
2017 #endif
2018 
2019 // decodeHash returns a hash on any input.
2020 // Thus, it needs to be last in the list.
2021 // If you add any decodes, add them before this.
2022  if (decodeHashOld(aResults)) {
2023  return true;
2024  }
2025 // Throw away and start over
2026  resume();
2027  return false;
2028 }
2029 
2031 #if defined(_IR_MEASURE_TIMING)
2032 #undef _IR_MEASURE_TIMING
2033 #endif
2034 #if defined(LOCAL_TRACE)
2035 #undef LOCAL_TRACE
2036 #endif
2037 #if defined(LOCAL_DEBUG)
2038 #undef LOCAL_DEBUG
2039 #endif
2040 #endif // _IR_RECEIVE_HPP
IRData::address
uint16_t address
Decoded address, Distance protocol (tMarkTicksLong (if tMarkTicksLong == 0, then tMarkTicksShort) << ...
Definition: IRProtocol.h:111
timerConfigForReceive
void timerConfigForReceive()
Configures the timer to be able to generate the receive sample interrupt, which consumes a small amou...
Definition: IRTimer.hpp:105
MICROS_PER_TICK
#define MICROS_PER_TICK
microseconds per clock interrupt tick
Definition: IRremote.hpp:250
IRrecv::decodeHash
bool decodeHash()
Decodes an arbitrary IR code to a 32-bit value.
Definition: IRReceive.hpp:1110
decode_results
Results returned from old decoders !!!deprecated!!!
Definition: IRremoteInt.h:188
digitalReadFast
#define digitalReadFast
Definition: digitalWriteFast.h:399
DistanceWidthTimingInfoStruct::HeaderMarkMicros
uint16_t HeaderMarkMicros
Definition: IRProtocol.h:81
decode_results::rawbuf
uint16_t * rawbuf
Definition: IRremoteInt.h:199
DECODE_MAGIQUEST
#define DECODE_MAGIQUEST
Definition: IRremote.hpp:110
setFeedbackLED
void setFeedbackLED(bool aSwitchLedOn)
Flash LED while receiving or sending IR data.
Definition: IRFeedbackLED.hpp:108
IRrecv::stop
void stop()
Disables the timer for IR reception.
Definition: IRReceive.hpp:448
IRrecv::lastDecodedProtocol
decode_type_t lastDecodedProtocol
Definition: IRremoteInt.h:370
IRData::numberOfBits
uint16_t numberOfBits
Number of bits received for data (address + command + parity) - to determine protocol length if diffe...
Definition: IRProtocol.h:120
RECORD_GAP_TICKS
#define RECORD_GAP_TICKS
Minimum gap between IR transmissions, in MICROS_PER_TICK.
Definition: IRremote.hpp:173
IRrecv::disableIRIn
void disableIRIn()
Alias for stop().
Definition: IRReceive.hpp:462
IRRawlenType
unsigned int IRRawlenType
Definition: IRremoteInt.h:94
IRrecv::checkHeader_P
bool checkHeader_P(PulseDistanceWidthProtocolConstants const *aProtocolConstantsPGM)
Definition: IRReceive.hpp:1183
IRrecv::enableIRIn
void enableIRIn()
Alias for start().
Definition: IRReceive.hpp:398
MARK_EXCESS_MICROS
#define MARK_EXCESS_MICROS
MARK_EXCESS_MICROS is subtracted from all marks and added to all spaces before decoding,...
Definition: IRremote.hpp:150
pinModeFast
#define pinModeFast
Definition: digitalWriteFast.h:383
IRrecv::checkForRecordGapsMicros
bool checkForRecordGapsMicros(Print *aSerial)
Checks if protocol is not detected and detected space between two transmissions is smaller than known...
Definition: IRReceive.hpp:1327
digitalWriteFast
#define digitalWriteFast
Definition: digitalWriteFast.h:347
IRrecv::registerReceiveCompleteCallback
void registerReceiveCompleteCallback(void(*aReceiveCompleteCallbackFunction)(void))
Sets the function to call if a complete protocol frame has arrived.
Definition: IRReceive.hpp:354
IRrecv
Main class for receiving IR signals.
Definition: IRremoteInt.h:205
IRrecv::decodeDistanceWidth
bool decodeDistanceWidth()
Definition: ir_DistanceWidthProtocol.hpp:197
SONY
@ SONY
Definition: IRProtocol.h:65
PULSE_WIDTH
@ PULSE_WIDTH
Definition: IRProtocol.h:42
decode_results::overflow
bool overflow
Definition: IRremoteInt.h:201
IRDATA_FLAGS_IS_REPEAT
#define IRDATA_FLAGS_IS_REPEAT
The gap between the preceding frame is as smaller than the maximum gap expected for a repeat....
Definition: IRProtocol.h:93
PulseDistanceWidthProtocolConstants::ProtocolIndex
decode_type_t ProtocolIndex
Definition: IRProtocol.h:138
IRrecv::restartAfterSend
void restartAfterSend()
Restarts receiver after send.
Definition: IRReceive.hpp:439
IRrecv::IRrecv
IRrecv()
Instantiate the IRrecv class.
Definition: IRReceive.hpp:71
sBiphaseDecodeRawbuffOffset
uint_fast8_t sBiphaseDecodeRawbuffOffset
Definition: IRReceive.hpp:1003
TICKS_LOW
#define TICKS_LOW(us)
Definition: IRremoteInt.h:439
IRrecv::printIRResultAsCVariables
void printIRResultAsCVariables(Print *aSerial)
Print results as C variables to be used for sendXXX()
Definition: IRReceive.hpp:1881
sMicrosAtLastStopTimer
unsigned long sMicrosAtLastStopTimer
Definition: IRReceive.hpp:65
DistanceWidthTimingInfoStruct::OneSpaceMicros
uint16_t OneSpaceMicros
Definition: IRProtocol.h:84
IRData::rawDataPtr
irparams_struct * rawDataPtr
Pointer of the raw timing data to be decoded. Mainly the OverflowFlag and the data buffer filled by r...
Definition: IRProtocol.h:132
IRDATA_FLAGS_IS_AUTO_REPEAT
#define IRDATA_FLAGS_IS_AUTO_REPEAT
The current repeat frame is a repeat, that is always sent after a regular frame and cannot be avoided...
Definition: IRProtocol.h:94
decode_results::bits
uint8_t bits
Definition: IRremoteInt.h:194
decode_results::decode_type
decode_type_t decode_type
Definition: IRremoteInt.h:191
IRData::decodedRawData
IRRawDataType decodedRawData
Up to 32/64 bit decoded raw data, to be used for send functions.
Definition: IRProtocol.h:114
matchTicks
bool matchTicks(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros)
Match function without compensating for marks exceeded or spaces shortened by demodulator hardware.
Definition: IRReceive.hpp:1223
irparams_struct::ReceiveCompleteCallbackFunction
void(* ReceiveCompleteCallbackFunction)(void)
The function to call if a protocol message has arrived, i.e. StateForISR changed to IR_REC_STATE_STOP...
Definition: IRremoteInt.h:142
PULSE_DISTANCE
@ PULSE_DISTANCE
Definition: IRProtocol.h:43
IRrecv::begin
void begin(uint_fast8_t aReceivePin, bool aEnableLEDFeedback=false, uint_fast8_t aFeedbackLEDPin=USE_DEFAULT_FEEDBACK_LED_PIN)
Initializes the receive and feedback pin.
Definition: IRReceive.hpp:293
IRrecv::checkForRepeatSpaceTicksAndSetFlag
void checkForRepeatSpaceTicksAndSetFlag(uint16_t aMaximumRepeatSpaceTicks)
Definition: IRReceive.hpp:1207
IR_DEBUG_PRINT
#define IR_DEBUG_PRINT(...)
If DEBUG, print the arguments, otherwise do nothing.
Definition: IRremoteInt.h:166
RECORD_GAP_MICROS_WARNING_THRESHOLD
#define RECORD_GAP_MICROS_WARNING_THRESHOLD
Threshold for warnings at printIRResult*() to report about changing the RECORD_GAP_MICROS value to a ...
Definition: IRremote.hpp:169
IRrecv::decodeSonyMSB
bool decodeSonyMSB(decode_results *aResults)
Definition: ir_Sony.hpp:154
IRrecv::decodePulseDistanceWidthDataStrict
bool decodePulseDistanceWidthDataStrict(uint_fast8_t aNumberOfBits, IRRawlenType aStartOffset, uint16_t aOneMarkMicros, uint16_t aZeroMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroSpaceMicros, bool aMSBfirst)
Definition: IRReceive.hpp:856
IRrecv::decodeSony
bool decodeSony()
Definition: ir_Sony.hpp:109
irparams_struct
This struct contains the data and control used for receiver static functions and the ISR (interrupt s...
Definition: IRremoteInt.h:132
matchSpace
bool matchSpace(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros)
Compensate for spaces shortened by demodulator hardware.
Definition: IRReceive.hpp:1285
DistanceWidthTimingInfoStruct::ZeroMarkMicros
uint16_t ZeroMarkMicros
Definition: IRProtocol.h:85
IRrecv::read
IRData * read()
Returns pointer to IrReceiver.decodedIRData if IR receiver data is available, else nullptr.
Definition: IRReceive.hpp:530
IRrecv::getBiphaselevel
uint_fast8_t getBiphaselevel()
Gets the level of one time interval (aBiphaseTimeUnit) at a time from the raw buffer.
Definition: IRReceive.hpp:1030
MAGIQUEST
@ MAGIQUEST
Definition: IRProtocol.h:70
sBiphaseCurrentTimingIntervals
uint16_t sBiphaseCurrentTimingIntervals
Definition: IRReceive.hpp:1004
timerDisableReceiveInterrupt
void timerDisableReceiveInterrupt()
Disables the receive sample timer interrupt.
Definition: IRTimer.hpp:117
IRrecv::decodeLGMSB
bool decodeLGMSB(decode_results *aResults)
Definition: ir_LG.hpp:290
PulseDistanceWidthProtocolConstants::Flags
uint8_t Flags
Definition: IRProtocol.h:141
irparams
struct irparams_struct irparams
Definition: IRReceive.hpp:64
decode_results::value
uint32_t value
Definition: IRremoteInt.h:193
DistanceWidthTimingInfoStruct
Definition: IRProtocol.h:80
MATCH_SPACE
bool MATCH_SPACE(uint16_t measured_ticks, uint16_t desired_us)
Definition: IRReceive.hpp:1311
IRrecv::decodeSAMSUNG
bool decodeSAMSUNG(decode_results *aResults)
Definition: ir_Samsung.hpp:368
IRrecv::decodeBangOlufsen
bool decodeBangOlufsen()
Definition: ir_BangOlufsen.hpp:293
IRrecv::decodeLegoPowerFunctions
bool decodeLegoPowerFunctions()
Definition: ir_Lego.hpp:128
irparams_struct::OverflowFlag
bool OverflowFlag
Raw buffer OverflowFlag occurred.
Definition: IRremoteInt.h:144
IRrecv::decodeFAST
bool decodeFAST()
Definition: ir_FAST.hpp:99
PulseDistanceWidthProtocolConstants
Definition: IRProtocol.h:137
FeedbackLEDControlStruct::LedFeedbackEnabled
uint8_t LedFeedbackEnabled
LED_FEEDBACK_ENABLED_FOR_RECEIVE or LED_FEEDBACK_ENABLED_FOR_SEND -> enable blinking of pin on IR pro...
Definition: IRFeedbackLED.hpp:44
irparams_struct::rawlen
IRRawlenType rawlen
counter of entries in rawbuf
Definition: IRremoteInt.h:145
IRrecv::decodedIRData
IRData decodedIRData
Definition: IRremoteInt.h:367
IRData
Data structure for the user application, available as decodedIRData.
Definition: IRProtocol.h:109
IRDATA_FLAGS_EXTRA_INFO
#define IRDATA_FLAGS_EXTRA_INFO
There is extra info not contained in address and data (e.g. Kaseikyo unknown vendor ID,...
Definition: IRProtocol.h:98
FNV_PRIME_32
#define FNV_PRIME_32
used for decodeHash()
Definition: IRReceive.hpp:1075
IRrecv::decodeSamsung
bool decodeSamsung()
Definition: ir_Samsung.hpp:269
IRData::flags
uint8_t flags
IRDATA_FLAGS_IS_REPEAT, IRDATA_FLAGS_WAS_OVERFLOW etc. See IRDATA_FLAGS_* definitions above.
Definition: IRProtocol.h:121
IRDATA_FLAGS_IS_PROTOCOL_WITH_DIFFERENT_REPEAT
#define IRDATA_FLAGS_IS_PROTOCOL_WITH_DIFFERENT_REPEAT
Here we have a repeat of type NEC2 or SamsungLG.
Definition: IRProtocol.h:99
DistanceWidthTimingInfoStruct::OneMarkMicros
uint16_t OneMarkMicros
Definition: IRProtocol.h:83
IRDATA_FLAGS_WAS_OVERFLOW
#define IRDATA_FLAGS_WAS_OVERFLOW
irparams.rawlen is set to 0 in this case to avoid endless OverflowFlag.
Definition: IRProtocol.h:100
DO_NOT_ENABLE_LED_FEEDBACK
#define DO_NOT_ENABLE_LED_FEEDBACK
Definition: IRremoteInt.h:403
MATCH
bool MATCH(uint16_t measured_ticks, uint16_t desired_us)
Definition: IRReceive.hpp:1243
IRrecv::checkHeader
bool checkHeader(PulseDistanceWidthProtocolConstants *aProtocolConstants)
Definition: IRReceive.hpp:1164
IRrecv::decodePulseDistanceWidthData
bool decodePulseDistanceWidthData(PulseDistanceWidthProtocolConstants *aProtocolConstants, uint_fast8_t aNumberOfBits, IRRawlenType aStartOffset=3)
Decode pulse distance protocols for PulseDistanceWidthProtocolConstants.
Definition: IRReceive.hpp:983
sBiphaseUsedTimingIntervals
uint_fast8_t sBiphaseUsedTimingIntervals
Definition: IRReceive.hpp:1005
IRrecv::compare
uint_fast8_t compare(uint16_t oldval, uint16_t newval)
Compare two (tick) values for Hash decoder Use a tolerance of 20% to enable e.g.
Definition: IRReceive.hpp:1083
IRrecv::printActiveIRProtocols
static void printActiveIRProtocols(Print *aSerial)
Definition: IRReceive.hpp:1352
printActiveIRProtocols
void printActiveIRProtocols(Print *aSerial)
Definition: IRReceive.hpp:1360
IRData::command
uint16_t command
Decoded command, Distance protocol (tMarkTicksShort << 8) | tSpaceTicksShort.
Definition: IRProtocol.h:112
IR_REC_STATE_STOP
#define IR_REC_STATE_STOP
Definition: IRremoteInt.h:126
IR_REC_STATE_MARK
#define IR_REC_STATE_MARK
Definition: IRremoteInt.h:124
IRReceiveTimerInterruptHandler
void IRReceiveTimerInterruptHandler()
Definition: IRReceive.hpp:125
IRrecv::getMaximumTicksFromRawData
uint8_t getMaximumTicksFromRawData(bool aSearchSpaceInsteadOfMark)
Definition: IRReceive.hpp:1482
IRrecv::restartTimer
void restartTimer()
Definition: IRReceive.hpp:382
IRrecv::printIRResultShort
bool printIRResultShort(Print *aSerial, bool aCheckForRecordGapsMicros=true)
Function to print values and flags of IrReceiver.decodedIRData in one line.
Definition: IRReceive.hpp:1431
IRrecv::restartTimerWithTicksToAdd
void restartTimerWithTicksToAdd(uint16_t aTicksToAddToGapCounter)
Configures the timer and the state machine for IR reception.
Definition: IRReceive.hpp:424
FNV_BASIS_32
#define FNV_BASIS_32
used for decodeHash()
Definition: IRReceive.hpp:1076
IRrecv::isIdle
bool isIdle()
Returns status of reception.
Definition: IRReceive.hpp:476
sBiphaseTimeUnit
uint16_t sBiphaseTimeUnit
Definition: IRReceive.hpp:1006
timerResetInterruptPending
void timerResetInterruptPending()
IRrecv::printDistanceWidthTimingInfo
void printDistanceWidthTimingInfo(Print *aSerial, DistanceWidthTimingInfoStruct *aDistanceWidthTimingInfo)
Definition: IRReceive.hpp:1440
timerEnableReceiveInterrupt
void timerEnableReceiveInterrupt()
Enables the receive sample timer interrupt, which consumes a small amount of CPU every 50 us.
Definition: IRTimer.hpp:110
getMarkExcessMicros
int getMarkExcessMicros()
Getter function for MARK_EXCESS_MICROS.
Definition: IRReceive.hpp:1318
LED_FEEDBACK_ENABLED_FOR_RECEIVE
#define LED_FEEDBACK_ENABLED_FOR_RECEIVE
Definition: IRremoteInt.h:405
matchMark
bool matchMark(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros)
Compensate for marks exceeded by demodulator hardware.
Definition: IRReceive.hpp:1251
IRrecv::compensateAndPrintIRResultAsCArray
void compensateAndPrintIRResultAsCArray(Print *aSerial, bool aOutputMicrosecondsInsteadOfTicks=true)
Dump out the IrReceiver.decodedIRData.rawDataPtr->rawbuf[] to be used as C definition for sendRaw().
Definition: IRReceive.hpp:1802
MATCH_MARK
bool MATCH_MARK(uint16_t measured_ticks, uint16_t desired_us)
Definition: IRReceive.hpp:1277
irparams_struct::TickCounterForISR
volatile uint_fast16_t TickCounterForISR
Counts 50uS ticks. The value is copied into the rawbuf array on every transition. Counting is indepen...
Definition: IRremoteInt.h:140
irparams_struct::StateForISR
volatile uint8_t StateForISR
State Machine state.
Definition: IRremoteInt.h:134
IRrecv::setReceivePin
void setReceivePin(uint_fast8_t aReceivePinNumber)
Sets / changes the receiver pin number.
Definition: IRReceive.hpp:316
irparams_struct::rawbuf
IRRawbufType rawbuf[RAW_BUFFER_LENGTH]
raw data / tick counts per mark/space. With 8 bit we can only store up to 12.7 ms....
Definition: IRremoteInt.h:147
DistanceWidthTimingInfoStruct::ZeroSpaceMicros
uint16_t ZeroSpaceMicros
Definition: IRProtocol.h:86
IRrecv::decodeDenonOld
bool decodeDenonOld(decode_results *aResults)
Definition: ir_Denon.hpp:294
IRRawDataType
uint32_t IRRawDataType
Definition: IRremoteInt.h:112
IRrecv::start
void start()
Start the receiving process.
Definition: IRReceive.hpp:364
IRrecv::compensateAndStoreIRResultInArray
void compensateAndStoreIRResultInArray(uint8_t *aArrayPtr)
Store the decodedIRData to be used for sendRaw().
Definition: IRReceive.hpp:1858
IRrecv::printIRResultMinimal
void printIRResultMinimal(Print *aSerial)
Function to print protocol number, address, command, raw data and repeat flag of IrReceiver....
Definition: IRReceive.hpp:1641
IR_TRACE_PRINTLN
#define IR_TRACE_PRINTLN(...)
Definition: IRremoteInt.h:178
IRrecv::initDecodedIRData
void initDecodedIRData()
Is internally called by decode before calling decoders.
Definition: IRReceive.hpp:495
KASEIKYO
@ KASEIKYO
Definition: IRProtocol.h:53
IRrecv::lastDecodedCommand
uint16_t lastDecodedCommand
Definition: IRremoteInt.h:372
DENON
@ DENON
Definition: IRProtocol.h:45
IRrecv::getMaximumMarkTicksFromRawData
uint8_t getMaximumMarkTicksFromRawData()
Definition: IRReceive.hpp:1458
DECODE_DENON
#define DECODE_DENON
Definition: IRremote.hpp:96
IRDATA_FLAGS_IS_MSB_FIRST
#define IRDATA_FLAGS_IS_MSB_FIRST
Value is mainly determined by the (known) protocol.
Definition: IRProtocol.h:101
TICKS_HIGH
#define TICKS_HIGH(us)
Definition: IRremoteInt.h:440
IRrecv::decodePulseDistanceWidthData_P
bool decodePulseDistanceWidthData_P(PulseDistanceWidthProtocolConstants const *aProtocolConstantsPGM, uint_fast8_t aNumberOfBits, IRRawlenType aStartOffset=3)
Definition: IRReceive.hpp:991
IRrecv::decodeRC5
bool decodeRC5()
Try to decode data as RC5 protocol.
Definition: ir_RC5_RC6.hpp:157
RC6A
@ RC6A
Definition: IRProtocol.h:60
IRrecv::decodeBoseWave
bool decodeBoseWave()
Definition: ir_BoseWave.hpp:64
IRDATA_FLAGS_EMPTY
#define IRDATA_FLAGS_EMPTY
Definition: IRProtocol.h:92
RC5
@ RC5
Definition: IRProtocol.h:58
IRrecv::available
bool available()
Returns true if IR receiver data is available.
Definition: IRReceive.hpp:523
IRData::extra
uint16_t extra
Contains upper 16 bit of Magiquest WandID, Kaseikyo unknown vendor ID and Distance protocol (HeaderMa...
Definition: IRProtocol.h:113
PulseDistanceWidthProtocolConstants::DistanceWidthTimingInfo
DistanceWidthTimingInfoStruct DistanceWidthTimingInfo
Definition: IRProtocol.h:140
IRrecv::getMaximumSpaceTicksFromRawData
uint8_t getMaximumSpaceTicksFromRawData()
Definition: IRReceive.hpp:1468
IRrecv::decodeMagiQuest
bool decodeMagiQuest()
Definition: ir_MagiQuest.hpp:154
INPUT_MARK
#define INPUT_MARK
Sensor output for a mark ("flash")
Definition: IRremote.hpp:184
IRrecv::printIRDuration
void printIRDuration(Print *aSerial, bool aOutputMicrosecondsInsteadOfTicks)
Definition: IRReceive.hpp:1682
FeedbackLEDControl
struct FeedbackLEDControlStruct FeedbackLEDControl
The feedback LED control instance.
Definition: IRFeedbackLED.hpp:47
IRrecv::initBiphaselevel
void initBiphaselevel(uint_fast8_t aRCDecodeRawbuffOffset, uint16_t aBiphaseTimeUnit)
Definition: IRReceive.hpp:1008
IRrecv::end
void end()
Alias for stop().
Definition: IRReceive.hpp:468
SPACE
#define SPACE
Definition: IRremoteInt.h:39
IRData::rawlen
IRRawlenType rawlen
counter of entries in rawbuf of last received frame.
Definition: IRProtocol.h:129
IRrecv::decodeNECMSB
bool decodeNECMSB(decode_results *aResults)
Definition: ir_NEC.hpp:344
IRrecv::decodeNEC
bool decodeNEC()
Decodes also Onkyo and Apple.
Definition: ir_NEC.hpp:237
RC6
@ RC6
Definition: IRProtocol.h:59
IRrecv::decodeHashOld
bool decodeHashOld(decode_results *aResults)
Definition: IRReceive.hpp:1135
IRrecv::printIRSendUsage
void printIRSendUsage(Print *aSerial)
Function to print values and flags of IrReceiver.decodedIRData in one line.
Definition: IRReceive.hpp:1516
IRrecv::decodeDenon
bool decodeDenon()
Definition: ir_Denon.hpp:169
IRrecv::decodeLG
bool decodeLG()
Definition: ir_LG.hpp:176
IRrecv::stopTimer
void stopTimer()
Definition: IRReceive.hpp:455
IRrecv::decode
bool decode()
The main decode function, attempts to decode the recently receive IR signal.
Definition: IRReceive.hpp:547
IRrecv::decodeJVC
bool decodeJVC()
Definition: ir_JVC.hpp:119
UNKNOWN
@ UNKNOWN
Definition: IRProtocol.h:41
RAW_BUFFER_LENGTH
#define RAW_BUFFER_LENGTH
The RAW_BUFFER_LENGTH determines the length of the byte buffer where the received IR timing data is s...
Definition: IRremoteInt.h:84
IRrecv::decodeKaseikyo
bool decodeKaseikyo()
Definition: ir_Kaseikyo.hpp:199
IR_DEBUG_PRINTLN
#define IR_DEBUG_PRINTLN(...)
If DEBUG, print the arguments as a line, otherwise do nothing.
Definition: IRremoteInt.h:170
IRrecv::getTotalDurationOfRawData
uint32_t getTotalDurationOfRawData()
Definition: IRReceive.hpp:1499
decode_results::rawlen
uint_fast8_t rawlen
Definition: IRremoteInt.h:200
IRData::protocol
decode_type_t protocol
UNKNOWN, NEC, SONY, RC5, PULSE_DISTANCE, ...
Definition: IRProtocol.h:110
IRrecv::decodeRC6
bool decodeRC6()
Try to decode data as RC6 protocol.
Definition: ir_RC5_RC6.hpp:449
IR_REC_STATE_SPACE
#define IR_REC_STATE_SPACE
Definition: IRremoteInt.h:125
IRrecv::getProtocolString
const char * getProtocolString()
Definition: IRReceive.hpp:1920
IRrecv::resume
void resume()
Restart the ISR (Interrupt Service Routine) state machine, to enable receiving of the next IR frame.
Definition: IRReceive.hpp:484
MARK
#define MARK
Definition: IRremoteInt.h:38
DistanceWidthTimingInfoStruct::HeaderSpaceMicros
uint16_t HeaderSpaceMicros
Definition: IRProtocol.h:82
IRrecv::decode_old
bool decode_old(decode_results *aResults)
Definition: IRReceive.hpp:1933
IRrecv::lastDecodedAddress
uint16_t lastDecodedAddress
Definition: IRremoteInt.h:371
IrReceiver
IRrecv IrReceiver
The receiver instance.
Definition: IRReceive.hpp:59
IRData::initialGapTicks
uint16_t initialGapTicks
contains the initial gap (pre 4.4: the value in rawbuf[0]) of the last received frame.
Definition: IRProtocol.h:130
IRrecv::printIRResultRawFormatted
void printIRResultRawFormatted(Print *aSerial, bool aOutputMicrosecondsInsteadOfTicks=true)
Dump out the timings in IrReceiver.decodedIRData.rawDataPtr->rawbuf[] array 8 values per line.
Definition: IRReceive.hpp:1704
IR_REC_STATE_IDLE
#define IR_REC_STATE_IDLE
Definition: IRremoteInt.h:123
getProtocolString
const char * getProtocolString(decode_type_t aProtocol)
Definition: IRProtocol.hpp:97
IRrecv::decodeJVCMSB
bool decodeJVCMSB(decode_results *aResults)
Definition: ir_JVC.hpp:177
setLEDFeedback
void setLEDFeedback(uint8_t aFeedbackLEDPin, uint8_t aEnableLEDFeedback)
Enables blinking of feedback LED (LED_BUILTIN is taken as default) on IR sending and receiving Cannot...
Definition: IRFeedbackLED.hpp:56
SHARP
@ SHARP
Definition: IRProtocol.h:64
IRrecv::decodeWhynter
bool decodeWhynter()
Definition: ir_Others.hpp:94
irparams_struct::IRReceivePin
uint_fast8_t IRReceivePin
Pin connected to IR data from detector.
Definition: IRremoteInt.h:135
irparams_struct::initialGapTicks
uint16_t initialGapTicks
Tick counts of the length of the gap between previous and current IR frame. Pre 4....
Definition: IRremoteInt.h:146