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-2022 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) && !defined(LOCAL_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 /*
49  * Check for additional characteristics of timing like length of mark for a constant mark protocol,
50  * where space length determines the bit value. Requires up to 194 additional bytes of program memory.
51  */
52 //#define DECODE_STRICT_CHECKS
60 
61 /*
62  * The control structure instance
63  */
64 struct irparams_struct irparams; // the irparams instance
65 
71  decodedIRData.rawDataPtr = &irparams; // for decodePulseDistanceData() etc.
72  setReceivePin(0);
73 #if !defined(NO_LED_FEEDBACK_CODE)
75 #endif
76 }
77 
78 IRrecv::IRrecv(uint_fast8_t aReceivePin) {
79  decodedIRData.rawDataPtr = &irparams; // for decodePulseDistanceData() etc.
80  setReceivePin(aReceivePin);
81 #if !defined(NO_LED_FEEDBACK_CODE)
83 #endif
84 }
85 
91 IRrecv::IRrecv(uint_fast8_t aReceivePin, uint_fast8_t aFeedbackLEDPin) {
92  decodedIRData.rawDataPtr = &irparams; // for decodePulseDistanceData() etc.
93  setReceivePin(aReceivePin);
94 #if !defined(NO_LED_FEEDBACK_CODE)
96 #else
97  (void) aFeedbackLEDPin;
98 #endif
99 }
100 
101 /**********************************************************************************************************************
102  * Interrupt Service Routine - Called every 50 us
103  *
104  * Duration in ticks of 50 us of alternating SPACE, MARK are recorded in irparams.rawbuf array.
105  * 'rawlen' counts the number of entries recorded so far.
106  * First entry is the SPACE between transmissions.
107  *
108  * As soon as one SPACE entry gets longer than RECORD_GAP_TICKS, state switches to STOP (frame received). Timing of SPACE continues.
109  * A call of resume() switches from STOP to IDLE.
110  * As soon as first MARK arrives in IDLE, gap width is recorded and new logging starts.
111  *
112  * With digitalRead and Feedback LED
113  * 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
114  * With portInputRegister and mask and Feedback LED code commented
115  * 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
116  * => Minimal CPU frequency is 4 MHz
117  *
118  **********************************************************************************************************************/
119 //#define _IR_MEASURE_TIMING
120 //#define _IR_TIMING_TEST_PIN 10 // "pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);" is executed at start()
121 #if defined(TIMER_INTR_NAME)
122 ISR (TIMER_INTR_NAME) // for ISR definitions
123 #else
124 ISR()
125 // for functions definitions which are called by separate (board specific) ISR
126 #endif
127 {
128 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
129  digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles
130 #endif
131 // 7 - 8.5 us for ISR body (without pushes and pops) for ATmega328 @16MHz
132 
133 #if defined(TIMER_REQUIRES_RESET_INTR_PENDING)
134  timerResetInterruptPending(); // reset TickCounterForISR interrupt flag if required (currently only for Teensy and ATmega4809)
135 #endif
136 
137 // Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on]
138 #if defined(__AVR__)
139  uint8_t tIRInputLevel = *irparams.IRReceivePinPortInputRegister & irparams.IRReceivePinMask;
140 #else
141  uint_fast8_t tIRInputLevel = (uint_fast8_t) digitalReadFast(irparams.IRReceivePin);
142 #endif
143 
144  /*
145  * Increase TickCounter and clip it at maximum 0xFFFF / 3.2 seconds at 50 us ticks
146  */
147  if (irparams.TickCounterForISR < UINT16_MAX) {
148  irparams.TickCounterForISR++; // One more 50uS tick
149  }
150 
151  /*
152  * Due to a ESP32 compiler bug https://github.com/espressif/esp-idf/issues/1552 no switch statements are possible for ESP32
153  * So we change the code to if / else if
154  */
155 // switch (irparams.StateForISR) {
156 //......................................................................
158  /*
159  * Here we are just resumed and maybe in the middle of a transmission
160  */
161  if (tIRInputLevel == INPUT_MARK) {
162  // check if we did not start in the middle of a transmission by checking the minimum length of leading space
164 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
165 // digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles
166 #endif
167  /*
168  * Gap between two transmissions just ended; Record gap duration + start recording transmission
169  * Initialize all state machine variables
170  */
171  irparams.OverflowFlag = false;
173  irparams.rawlen = 1;
175  } // otherwise stay in idle state
176  irparams.TickCounterForISR = 0;// reset counter in both cases
177  }
178 
179  } else if (irparams.StateForISR == IR_REC_STATE_MARK) { // Timing mark
180  if (tIRInputLevel != INPUT_MARK) { // Mark ended; Record time
181 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
182 // digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles
183 #endif
186  irparams.TickCounterForISR = 0; // This resets the tick counter also at end of frame :-)
187  }
188 
189  } else if (irparams.StateForISR == IR_REC_STATE_SPACE) { // Timing space
190  if (tIRInputLevel == INPUT_MARK) { // Space just ended; Record time
192  // Flag up a read OverflowFlag; Stop the state machine
193  irparams.OverflowFlag = true;
195 #if !IR_REMOTE_DISABLE_RECEIVE_COMPLETE_CALLBACK
196  /*
197  * Call callback if registered (not NULL)
198  */
201  }
202 #endif
203  } else {
204 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
205 // digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles
206 #endif
209  }
211 
213  /*
214  * Current code is ready for processing!
215  * We received a long space, which indicates gap between codes.
216  * Switch to IR_REC_STATE_STOP
217  * Don't reset TickCounterForISR; keep counting width of next leading space
218  */
220 #if !IR_REMOTE_DISABLE_RECEIVE_COMPLETE_CALLBACK
221  /*
222  * Call callback if registered (not NULL)
223  */
226  }
227 #endif
228  }
229  } else if (irparams.StateForISR == IR_REC_STATE_STOP) {
230  /*
231  * Complete command received
232  * stay here until resume() is called, which switches state to IR_REC_STATE_IDLE
233  */
234 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
235 // digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles
236 #endif
237  if (tIRInputLevel == INPUT_MARK) {
238  // Reset gap TickCounterForISR, to prepare for detection if we are in the middle of a transmission after call of resume()
240  }
241  }
242 
243 #if !defined(NO_LED_FEEDBACK_CODE)
245  setFeedbackLED(tIRInputLevel == INPUT_MARK);
246  }
247 #endif
248 
249 #ifdef _IR_MEASURE_TIMING
250  digitalWriteFast(_IR_TIMING_TEST_PIN, LOW); // 2 clock cycles
251 #endif
252 }
253 
254 /**********************************************************************************************************************
255  * Stream like API
256  **********************************************************************************************************************/
263 void IRrecv::begin(uint_fast8_t aReceivePin, bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin) {
264 
265  setReceivePin(aReceivePin);
266 #if !defined(NO_LED_FEEDBACK_CODE)
267  bool tEnableLEDFeedback = DO_NOT_ENABLE_LED_FEEDBACK;
268  if (aEnableLEDFeedback) {
269  tEnableLEDFeedback = LED_FEEDBACK_ENABLED_FOR_RECEIVE;
270  }
271  setLEDFeedback(aFeedbackLEDPin, tEnableLEDFeedback);
272 #else
273  (void) aEnableLEDFeedback;
274  (void) aFeedbackLEDPin;
275 #endif
276 
277 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
278  pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);
279 #endif
280  start();
281 }
282 
286 void IRrecv::setReceivePin(uint_fast8_t aReceivePinNumber) {
287  irparams.IRReceivePin = aReceivePinNumber;
288 #if defined(__AVR__)
289  irparams.IRReceivePinMask = digitalPinToBitMask(aReceivePinNumber);
290  irparams.IRReceivePinPortInputRegister = portInputRegister(digitalPinToPort(aReceivePinNumber));
291 #endif
292  // Set pin mode once. pinModeFast makes no difference here :-(
293  pinMode(aReceivePinNumber, INPUT); // Seems to be at least required by ESP32
294 }
295 
299 void IRrecv::registerReceiveCompleteCallback(void (*aReceiveCompleteCallbackFunction)(void)) {
300  irparams.ReceiveCompleteCallbackFunction = aReceiveCompleteCallbackFunction;
301 }
302 
309 
310  // Setup for cyclic 50 us interrupt
311  timerConfigForReceive(); // no interrupts enabled here!
312 
313  // Initialize state machine state
314  resume();
315 
316  // Timer interrupt is enabled after state machine reset
317  timerEnableReceiveInterrupt(); // Enables the receive sample timer interrupt which consumes a small amount of CPU every 50 us.
318 #ifdef _IR_MEASURE_TIMING
319  pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);
320 #endif
321 }
326  start();
327 }
328 
334 void IRrecv::start(uint32_t aMicrosecondsToAddToGapCounter) {
335  irparams.TickCounterForISR += aMicrosecondsToAddToGapCounter / MICROS_PER_TICK;
336  start();
337 }
338 void IRrecv::startWithTicksToAdd(uint16_t aTicksToAddToGapCounter) {
339  irparams.TickCounterForISR += aTicksToAddToGapCounter;
340  start();
341 }
342 
347 #if defined(SEND_PWM_BY_TIMER) && !defined(SEND_PWM_DOES_NOT_USE_RECEIVE_TIMER)
348  start();
349 #endif
350 }
351 
355 void IRrecv::stop() {
357 }
362  stop();
363 }
367 void IRrecv::end() {
368  stop();
369 }
370 
377 }
378 
383  // check allows to call resume at arbitrary places or more than once
386  }
387 #if defined(SEND_PWM_BY_TIMER)
388 // TIMER_ENABLE_RECEIVE_INTR; // normally it is stopped by send()
389 #endif
390 }
391 
397 
398  if (irparams.OverflowFlag) {
399  // Copy overflow flag to decodedIRData.flags and reset it
400  irparams.OverflowFlag = false;
401  irparams.rawlen = 0; // otherwise we have OverflowFlag again at next ISR call
403 #if defined(LOCAL_DEBUG)
404  Serial.print(F("Overflow happened, try to increase the \"RAW_BUFFER_LENGTH\" value of "));
405  Serial.print(RAW_BUFFER_LENGTH);
406  Serial.println(F(" with #define RAW_BUFFER_LENGTH=<biggerValue>"));
407 #endif
408 
409  } else {
411  // save last protocol, command and address for repeat handling (where the are copied back :-))
412  lastDecodedProtocol = decodedIRData.protocol; // repeat patterns can be equal between protocols (e.g. NEC and LG), so we must keep the original one
415 
416  }
422 }
423 
429 }
430 
436  return NULL;
437  }
438  if (decode()) {
439  return &decodedIRData;
440  } else {
441  return NULL;
442  }
443 }
444 
453  return false;
454  }
455 
456  initDecodedIRData(); // sets IRDATA_FLAGS_WAS_OVERFLOW
457 
459  /*
460  * Set OverflowFlag flag and return true here, to let the loop call resume or print raw data.
461  */
463  return true;
464  }
465 
466 #if defined(DECODE_NEC)
467  IR_TRACE_PRINTLN(F("Attempting NEC decode"));
468  if (decodeNEC()) {
469  return true;
470  }
471 #endif
472 
473 #if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO)
474  IR_TRACE_PRINTLN(F("Attempting Panasonic/Kaseikyo decode"));
475  if (decodeKaseikyo()) {
476  return true;
477  }
478 #endif
479 
480 #if defined(DECODE_DENON)
481  IR_TRACE_PRINTLN(F("Attempting Denon/Sharp decode"));
482  if (decodeDenon()) {
483  return true;
484  }
485 #endif
486 
487 #if defined(DECODE_SONY)
488  IR_TRACE_PRINTLN(F("Attempting Sony decode"));
489  if (decodeSony()) {
490  return true;
491  }
492 #endif
493 
494 #if defined(DECODE_RC5)
495  IR_TRACE_PRINTLN(F("Attempting RC5 decode"));
496  if (decodeRC5()) {
497  return true;
498  }
499 #endif
500 
501 #if defined(DECODE_RC6)
502  IR_TRACE_PRINTLN(F("Attempting RC6 decode"));
503  if (decodeRC6()) {
504  return true;
505  }
506 #endif
507 
508 #if defined(DECODE_LG)
509  IR_TRACE_PRINTLN(F("Attempting LG decode"));
510  if (decodeLG()) {
511  return true;
512  }
513 #endif
514 
515 #if defined(DECODE_JVC)
516  IR_TRACE_PRINTLN(F("Attempting JVC decode"));
517  if (decodeJVC()) {
518  return true;
519  }
520 #endif
521 
522 #if defined(DECODE_SAMSUNG)
523  IR_TRACE_PRINTLN(F("Attempting Samsung decode"));
524  if (decodeSamsung()) {
525  return true;
526  }
527 #endif
528  /*
529  * Start of the exotic protocols
530  */
531 
532 #if defined(DECODE_BEO)
533  IR_TRACE_PRINTLN(F("Attempting Bang & Olufsen decode"));
534  if (decodeBangOlufsen()) {
535  return true;
536  }
537 #endif
538 
539 #if defined(DECODE_WHYNTER)
540  IR_TRACE_PRINTLN(F("Attempting Whynter decode"));
541  if (decodeWhynter()) {
542  return true;
543  }
544 #endif
545 
546 #if defined(DECODE_LEGO_PF)
547  IR_TRACE_PRINTLN(F("Attempting Lego Power Functions"));
548  if (decodeLegoPowerFunctions()) {
549  return true;
550  }
551 #endif
552 
553 #if defined(DECODE_BOSEWAVE)
554  IR_TRACE_PRINTLN(F("Attempting Bosewave decode"));
555  if (decodeBoseWave()) {
556  return true;
557  }
558 #endif
559 
560 #if defined(DECODE_MAGIQUEST)
561  IR_TRACE_PRINTLN(F("Attempting MagiQuest decode"));
562  if (decodeMagiQuest()) {
563  return true;
564  }
565 #endif
566 
567  /*
568  * Try the universal decoder for pulse distance protocols
569  */
570 #if defined(DECODE_DISTANCE_WIDTH)
571  IR_TRACE_PRINTLN(F("Attempting universal Distance Width decode"));
572  if (decodeDistanceWidth()) {
573  return true;
574  }
575 #endif
576 
577  /*
578  * Last resort is the universal hash decode which always return true
579  */
580 #if defined(DECODE_HASH)
581  IR_TRACE_PRINTLN(F("Hash decode"));
582  // decodeHash returns a hash on any input.
583  // Thus, it needs to be last in the list.
584  // If you add any decodes, add them before this.
585  if (decodeHash()) {
586  return true;
587  }
588 #endif
589 
590  /*
591  * Return true here, to let the loop decide to call resume or to print raw data.
592  */
593  return true;
594 }
595 
596 /**********************************************************************************************************************
597  * Common decode functions
598  **********************************************************************************************************************/
622 bool IRrecv::decodePulseDistanceWidthData(uint_fast8_t aNumberOfBits, uint_fast8_t aStartOffset, unsigned int aOneMarkMicros,
623  unsigned int aZeroMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroSpaceMicros, bool aMSBfirst) {
624 
625  unsigned int *tRawBufPointer = &decodedIRData.rawDataPtr->rawbuf[aStartOffset];
626 
627  bool isPulseDistanceProtocol = (aOneMarkMicros == aZeroMarkMicros); // If true, we have a constant mark -> pulse distance protocol
628 
629  IRRawDataType tDecodedData = 0; // For MSB first tDecodedData is shifted left each loop
630  IRRawDataType tMask = 1UL; // Mask is only used for LSB first
631 
632  for (uint_fast8_t i = aNumberOfBits; i > 0; i--) {
633  // get one mark and space pair
634  unsigned int tMarkTicks;
635  unsigned int tSpaceTicks;
636 
637  if (isPulseDistanceProtocol) {
638  /*
639  * Pulse distance here, it is not required to check constant mark duration (aOneMarkMicros) and zero space duration.
640  */
641 #if defined DECODE_STRICT_CHECKS
642  tMarkTicks = *tRawBufPointer++;
643 #else
644  (void) aZeroSpaceMicros;
645  tRawBufPointer++;
646 #endif
647  tSpaceTicks = *tRawBufPointer++; // maybe buffer overflow for last bit, but we do not evaluate this value :-)
648 
649 #if defined DECODE_STRICT_CHECKS
650  // Check for constant length mark
651  if (!matchMark(tMarkTicks, aOneMarkMicros)) {
652 # if defined(LOCAL_DEBUG)
653  Serial.print(F("Mark="));
654  Serial.print(tMarkTicks * MICROS_PER_TICK);
655  Serial.print(F(" is not "));
656  Serial.print(aOneMarkMicros);
657  Serial.print(F(". Index="));
658  Serial.print(aNumberOfBits - i);
659  Serial.print(' ');
660 # endif
661  return false;
662  }
663 #endif
664 
665  } else {
666  /*
667  * Pulse width here, it is not required to check (constant) space duration and zero mark duration.
668  */
669  tMarkTicks = *tRawBufPointer++;
670 #if defined DECODE_STRICT_CHECKS
671  tSpaceTicks = *tRawBufPointer++; // maybe buffer overflow for last bit, but we do not evaluate this value :-)
672 #else
673  (void) aZeroMarkMicros;
674  (void) aZeroSpaceMicros;
675  tRawBufPointer++;
676 #endif
677  }
678 
679  if (aMSBfirst) {
680  tDecodedData <<= 1;
681  }
682 
683  bool tBitValue;
684  if (isPulseDistanceProtocol) {
685  // Check for variable length space indicating a 1 or 0
686  tBitValue = matchSpace(tSpaceTicks, aOneSpaceMicros);
687  } else {
688  // Check for variable length mark indicating a 1 or 0
689  tBitValue = matchMark(tMarkTicks, aOneMarkMicros);
690  }
691  if (tBitValue) {
692  // It's a 1 -> set the bit
693  if (aMSBfirst) {
694  tDecodedData |= 1;
695  } else {
696  tDecodedData |= tMask;
697  }
698  IR_TRACE_PRINTLN('1');
699  } else {
700 #if defined DECODE_STRICT_CHECKS
701  /*
702  * Additionally check length of length parameter which determine a zero
703  */
704  if (isPulseDistanceProtocol) {
705  if (!matchSpace(tSpaceTicks, aZeroSpaceMicros)) {
706 # if defined(LOCAL_DEBUG)
707  Serial.print(F("Space="));
708  Serial.print(tSpaceTicks * MICROS_PER_TICK);
709  Serial.print(F(" is not "));
710  Serial.print(aOneSpaceMicros);
711  Serial.print(F(" or "));
712  Serial.print(aZeroSpaceMicros);
713  Serial.print(F(". Index="));
714  Serial.print(aNumberOfBits - i);
715  Serial.print(' ');
716 # endif
717  return false;
718  }
719  } else {
720  if (!matchMark(tMarkTicks, aZeroMarkMicros)) {
721 # if defined(LOCAL_DEBUG)
722  Serial.print(F("Mark="));
723  Serial.print(tMarkTicks * MICROS_PER_TICK);
724  Serial.print(F(" is not "));
725  Serial.print(aOneMarkMicros);
726  Serial.print(F(" or "));
727  Serial.print(aZeroMarkMicros);
728  Serial.print(F(". Index="));
729  Serial.print(aNumberOfBits - i);
730  Serial.print(' ');
731 # endif
732  return false;
733  }
734  }
735 #endif
736  // do not set the bit
737  IR_TRACE_PRINTLN('0');
738  }
739 #if defined DECODE_STRICT_CHECKS
740  // If we have no stop bit, assume that last space, which is not recorded, is correct, since we can not check it
741  if (aZeroSpaceMicros == aOneSpaceMicros
742  && tRawBufPointer < &decodedIRData.rawDataPtr->rawbuf[decodedIRData.rawDataPtr->rawlen]) {
743  // Check for constant length space (of pulse width protocol) here
744  if (!matchSpace(tSpaceTicks, aOneSpaceMicros)) {
745 # if defined(LOCAL_DEBUG)
746  Serial.print(F("Space="));
747  Serial.print(tSpaceTicks * MICROS_PER_TICK);
748  Serial.print(F(" is not "));
749  Serial.print(aOneSpaceMicros);
750  Serial.print(F(". Index="));
751  Serial.print(aNumberOfBits - i);
752  Serial.print(' ');
753 # endif
754  return false;
755  }
756  }
757 #endif
758  tMask <<= 1;
759  }
760  decodedIRData.decodedRawData = tDecodedData;
761  return true;
762 }
763 
768 bool IRrecv::decodePulseDistanceWidthData(PulseDistanceWidthProtocolConstants *aProtocolConstants, uint_fast8_t aNumberOfBits,
769  uint_fast8_t aStartOffset) {
770 
771  return decodePulseDistanceWidthData(aNumberOfBits, aStartOffset, aProtocolConstants->OneMarkMicros,
772  aProtocolConstants->ZeroMarkMicros, aProtocolConstants->OneSpaceMicros, aProtocolConstants->ZeroSpaceMicros,
773  aProtocolConstants->isMSBFirst);
774 }
775 
776 /*
777  * Static variables for the getBiphaselevel function
778  */
779 uint_fast8_t sBiphaseDecodeRawbuffOffset; // Index into raw timing array
780 unsigned int sBiphaseCurrentTimingIntervals; // 1, 2 or 3. Number of aBiphaseTimeUnit intervals of the current rawbuf[sBiphaseDecodeRawbuffOffset] timing.
781 uint_fast8_t sBiphaseUsedTimingIntervals; // Number of already used intervals of sCurrentTimingIntervals.
782 unsigned int sBiphaseTimeUnit;
783 
784 void IRrecv::initBiphaselevel(uint_fast8_t aRCDecodeRawbuffOffset, unsigned int aBiphaseTimeUnit) {
785  sBiphaseDecodeRawbuffOffset = aRCDecodeRawbuffOffset;
786  sBiphaseTimeUnit = aBiphaseTimeUnit;
788 }
789 
806 uint_fast8_t IRrecv::getBiphaselevel() {
807  uint_fast8_t tLevelOfCurrentInterval; // 0 (SPACE) or 1 (MARK)
808 
810  return SPACE; // After end of recorded buffer, assume space.
811  }
812 
813  tLevelOfCurrentInterval = (sBiphaseDecodeRawbuffOffset) & 1; // on odd rawbuf offsets we have mark timings
814 
815  /*
816  * Setup data if sUsedTimingIntervals is 0
817  */
818  if (sBiphaseUsedTimingIntervals == 0) {
819  unsigned int tCurrentTimingWith = decodedIRData.rawDataPtr->rawbuf[sBiphaseDecodeRawbuffOffset];
820  unsigned int tMarkExcessCorrection = (tLevelOfCurrentInterval == MARK) ? MARK_EXCESS_MICROS : -MARK_EXCESS_MICROS;
821 
822  if (matchTicks(tCurrentTimingWith, (sBiphaseTimeUnit) + tMarkExcessCorrection)) {
824  } else if (matchTicks(tCurrentTimingWith, (2 * sBiphaseTimeUnit) + tMarkExcessCorrection)) {
826  } else if (matchTicks(tCurrentTimingWith, (3 * sBiphaseTimeUnit) + tMarkExcessCorrection)) {
828  } else {
829  return -1;
830  }
831  }
832 
833 // We use another interval from tCurrentTimingIntervals
835 
836 // keep track of current timing offset
838  // we have used all intervals of current timing, switch to next timing value
841  }
842 
843  IR_TRACE_PRINTLN(tLevelOfCurrentInterval);
844 
845  return tLevelOfCurrentInterval;
846 }
847 
848 #if defined(DECODE_HASH)
849 /**********************************************************************************************************************
850  * Internal Hash decode function
851  **********************************************************************************************************************/
857 uint_fast8_t IRrecv::compare(unsigned int oldval, unsigned int newval) {
858  if (newval * 10 < oldval * 8) {
859  return 0;
860  }
861  if (oldval * 10 < newval * 8) {
862  return 2;
863  }
864  return 1;
865 }
866 
867 #define FNV_PRIME_32 16777619
868 #define FNV_BASIS_32 2166136261
869 
870 
888 bool IRrecv::decodeHash() {
889  unsigned long hash = FNV_BASIS_32; // the result is the same no matter if we use a long or unsigned long variable
890 
891 // Require at least 6 samples to prevent triggering on noise
892  if (decodedIRData.rawDataPtr->rawlen < 6) {
893  return false;
894  }
895 #if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR
896  uint_fast8_t i;
897 #else
898  unsigned int i;
899 #endif
900  for (i = 1; (i + 2) < decodedIRData.rawDataPtr->rawlen; i++) {
901  uint_fast8_t value = compare(decodedIRData.rawDataPtr->rawbuf[i], decodedIRData.rawDataPtr->rawbuf[i + 2]);
902  // Add value into the hash
903  hash = (hash * FNV_PRIME_32) ^ value;
904  }
905 
909 
910  return true;
911 }
912 
913 bool IRrecv::decodeHashOld(decode_results *aResults) {
914  unsigned long hash = FNV_BASIS_32;
915 
916 // Require at least 6 samples to prevent triggering on noise
917  if (aResults->rawlen < 6) {
918  return false;
919  }
920 
921  for (uint8_t i = 3; i < aResults->rawlen; i++) {
922  uint_fast8_t value = compare(aResults->rawbuf[i - 2], aResults->rawbuf[i]);
923  // Add value into the hash
924  hash = (hash * FNV_PRIME_32) ^ value;
925  }
926 
927  aResults->value = hash;
928  aResults->bits = 32;
929  aResults->decode_type = UNKNOWN;
931 
932  return true;
933 }
934 #endif // DECODE_HASH
935 
936 /**********************************************************************************************************************
937  * Match functions
938  **********************************************************************************************************************/
939 
940 /*
941  * returns true if values do match
942  */
944 // Check header "mark" and "space"
945  if (!matchMark(decodedIRData.rawDataPtr->rawbuf[1], aProtocolConstants->HeaderMarkMicros)) {
946 #if defined(LOCAL_TRACE)
947  Serial.print(::getProtocolString(aProtocolConstants->ProtocolIndex));
948  Serial.println(F(": Header mark length is wrong"));
949 #endif
950  return false;
951  }
952  if (!matchSpace(decodedIRData.rawDataPtr->rawbuf[2], aProtocolConstants->HeaderSpaceMicros)) {
953 #if defined(LOCAL_TRACE)
954  Serial.print(::getProtocolString(aProtocolConstants->ProtocolIndex));
955  Serial.println(F(": Header space length is wrong"));
956 #endif
957  return false;
958  }
959  return true;
960 }
961 
962 void IRrecv::checkForRepeatSpaceAndSetFlag(unsigned int aMediumRepeatSpaceMillis) {
964  < ((aMediumRepeatSpaceMillis + (aMediumRepeatSpaceMillis / 4)) * (1000 / MICROS_PER_TICK))) {
966  }
967 }
968 
973 bool matchTicks(unsigned int aMeasuredTicks, unsigned int aMatchValueMicros) {
974 #if defined(LOCAL_TRACE)
975  Serial.print(F("Testing: "));
976  Serial.print(TICKS_LOW(aMatchValueMicros), DEC);
977  Serial.print(F(" <= "));
978  Serial.print(aMeasuredTicks, DEC);
979  Serial.print(F(" <= "));
980  Serial.print(TICKS_HIGH(aMatchValueMicros), DEC);
981 #endif
982  bool passed = ((aMeasuredTicks >= TICKS_LOW(aMatchValueMicros)) && (aMeasuredTicks <= TICKS_HIGH(aMatchValueMicros)));
983 #if defined(LOCAL_TRACE)
984  if (passed) {
985  Serial.println(F(" => passed"));
986  } else {
987  Serial.println(F(" => FAILED"));
988  }
989 #endif
990  return passed;
991 }
992 
993 bool MATCH(unsigned int measured_ticks, unsigned int desired_us) {
994  return matchTicks(measured_ticks, desired_us);
995 }
996 
1000 bool matchMark(unsigned int aMeasuredTicks, unsigned int aMatchValueMicros) {
1001 #if defined(LOCAL_TRACE)
1002  Serial.print(F("Testing mark (actual vs desired): "));
1003  Serial.print(aMeasuredTicks * MICROS_PER_TICK, DEC);
1004  Serial.print(F("us vs "));
1005  Serial.print(aMatchValueMicros, DEC);
1006  Serial.print(F("us: "));
1007  Serial.print(TICKS_LOW(aMatchValueMicros + MARK_EXCESS_MICROS) * MICROS_PER_TICK, DEC);
1008  Serial.print(F(" <= "));
1009  Serial.print(aMeasuredTicks * MICROS_PER_TICK, DEC);
1010  Serial.print(F(" <= "));
1011  Serial.print(TICKS_HIGH(aMatchValueMicros + MARK_EXCESS_MICROS) * MICROS_PER_TICK, DEC);
1012 #endif
1013  // compensate for marks exceeded by demodulator hardware
1014  bool passed = ((aMeasuredTicks >= TICKS_LOW(aMatchValueMicros + MARK_EXCESS_MICROS))
1015  && (aMeasuredTicks <= TICKS_HIGH(aMatchValueMicros + MARK_EXCESS_MICROS)));
1016 #if defined(LOCAL_TRACE)
1017  if (passed) {
1018  Serial.println(F(" => passed"));
1019  } else {
1020  Serial.println(F(" => FAILED"));
1021  }
1022 #endif
1023  return passed;
1024 }
1025 
1026 bool MATCH_MARK(unsigned int measured_ticks, unsigned int desired_us) {
1027  return matchMark(measured_ticks, desired_us);
1028 }
1029 
1033 bool matchSpace(unsigned int aMeasuredTicks, unsigned int aMatchValueMicros) {
1034 #if defined(LOCAL_TRACE)
1035  Serial.print(F("Testing space (actual vs desired): "));
1036  Serial.print(aMeasuredTicks * MICROS_PER_TICK, DEC);
1037  Serial.print(F("us vs "));
1038  Serial.print(aMatchValueMicros, DEC);
1039  Serial.print(F("us: "));
1040  Serial.print(TICKS_LOW(aMatchValueMicros - MARK_EXCESS_MICROS) * MICROS_PER_TICK, DEC);
1041  Serial.print(F(" <= "));
1042  Serial.print(aMeasuredTicks * MICROS_PER_TICK, DEC);
1043  Serial.print(F(" <= "));
1044  Serial.print(TICKS_HIGH(aMatchValueMicros - MARK_EXCESS_MICROS) * MICROS_PER_TICK, DEC);
1045 #endif
1046  // compensate for spaces shortened by demodulator hardware
1047  bool passed = ((aMeasuredTicks >= TICKS_LOW(aMatchValueMicros - MARK_EXCESS_MICROS))
1048  && (aMeasuredTicks <= TICKS_HIGH(aMatchValueMicros - MARK_EXCESS_MICROS)));
1049 #if defined(LOCAL_TRACE)
1050  if (passed) {
1051  Serial.println(F(" => passed"));
1052  } else {
1053  Serial.println(F(" => FAILED"));
1054  }
1055 #endif
1056  return passed;
1057 }
1058 
1059 bool MATCH_SPACE(unsigned int measured_ticks, unsigned int desired_us) {
1060  return matchSpace(measured_ticks, desired_us);
1061 }
1062 
1067  return MARK_EXCESS_MICROS;
1068 }
1069 
1070 /*
1071  * Check if protocol is not detected and detected space between two transmissions
1072  * is smaller than known value for protocols (Sony with around 24 ms)
1073  * @return true, if CheckForRecordGapsMicros() has printed a message, i.e. gap < 15ms (RECORD_GAP_MICROS_WARNING_THRESHOLD)
1074  */
1075 bool IRrecv::checkForRecordGapsMicros(Print *aSerial) {
1076  /*
1077  * Check if protocol is not detected and detected space between two transmissions
1078  * is smaller than known value for protocols (Sony with around 24 ms)
1079  */
1082  aSerial->println();
1083  aSerial->print(F("Space of "));
1084  aSerial->print(decodedIRData.rawDataPtr->rawbuf[0] * MICROS_PER_TICK);
1085  aSerial->print(F(" us between two detected transmission is smaller than the minimal gap of "));
1086  aSerial->print(RECORD_GAP_MICROS_WARNING_THRESHOLD);
1087  aSerial->println(F(" us known for implemented protocols like NEC, Sony, RC% etc.."));
1088  aSerial->println(F("But it can be OK for some yet unsupported protocols, and especially for repeats."));
1089  aSerial->println(F("If you get unexpected results, try to increase the RECORD_GAP_MICROS in IRremote.h."));
1090  aSerial->println();
1091  return true;
1092  }
1093  return false;
1094 }
1095 
1096 /**********************************************************************************************************************
1097  * Print functions
1098  * Since a library should not allocate the "Serial" object, all functions require a pointer to a Print object.
1099  **********************************************************************************************************************/
1100 void IRrecv::printActiveIRProtocols(Print *aSerial) {
1101 // call no class function with same name
1102  ::printActiveIRProtocols(aSerial);
1103 }
1104 void printActiveIRProtocols(Print *aSerial) {
1105 #if defined(DECODE_NEC)
1106  aSerial->print(F("NEC/NEC2/Onkyo/Apple, "));
1107 #endif
1108 #if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO)
1109  aSerial->print(F("Panasonic/Kaseikyo, "));
1110 #endif
1111 #if defined(DECODE_DENON)
1112  aSerial->print(F("Denon/Sharp, "));
1113 #endif
1114 #if defined(DECODE_SONY)
1115  aSerial->print(F("Sony, "));
1116 #endif
1117 #if defined(DECODE_RC5)
1118  aSerial->print(F("RC5, "));
1119 #endif
1120 #if defined(DECODE_RC6)
1121  aSerial->print(F("RC6, "));
1122 #endif
1123 #if defined(DECODE_LG)
1124  aSerial->print(F("LG, "));
1125 #endif
1126 #if defined(DECODE_JVC)
1127  aSerial->print(F("JVC, "));
1128 #endif
1129 #if defined(DECODE_SAMSUNG)
1130  aSerial->print(F("Samsung, "));
1131 #endif
1132  /*
1133  * Start of the exotic protocols
1134  */
1135 #if defined(DECODE_BEO)
1136  aSerial->print(F("Bang & Olufsen, "));
1137 #endif
1138 #if defined(DECODE_WHYNTER)
1139  aSerial->print(F("Whynter, "));
1140 #endif
1141 #if defined(DECODE_LEGO_PF)
1142  aSerial->print(F("Lego Power Functions, "));
1143 #endif
1144 #if defined(DECODE_BOSEWAVE)
1145  aSerial->print(F("Bosewave , "));
1146 #endif
1147 #if defined(DECODE_MAGIQUEST)
1148  aSerial->print(F("MagiQuest, "));
1149 #endif
1150 #if defined(DECODE_DISTANCE_WIDTH)
1151  aSerial->print(F("Universal Pulse Distance Width, "));
1152 #endif
1153 #if defined(DECODE_HASH)
1154  aSerial->print(F("Hash "));
1155 #endif
1156 #if defined(NO_DECODER) // for sending raw only
1157  (void)aSerial; // to avoid compiler warnings
1158 #endif
1159 }
1160 
1171 bool IRrecv::printIRResultShort(Print *aSerial, bool aPrintRepeatGap, bool aCheckForRecordGapsMicros) {
1172 // call no class function with same name
1173  ::printIRResultShort(aSerial, &decodedIRData, aPrintRepeatGap);
1174  if (aCheckForRecordGapsMicros && decodedIRData.protocol != UNKNOWN) {
1175  return checkForRecordGapsMicros(aSerial);
1176  }
1177  return false;
1178 }
1179 
1186 void IRrecv::printIRSendUsage(Print *aSerial) {
1189 #if defined(DECODE_DISTANCE_WIDTH)
1190  aSerial->print(F("Send with:"));
1191  uint_fast8_t tNumberOfArrayData = 0;
1193 # if __INT_WIDTH__ < 32
1194  tNumberOfArrayData = ((decodedIRData.numberOfBits - 1) / 32) + 1;
1195  if(tNumberOfArrayData > 1) {
1196  aSerial->println();
1197  aSerial->print(F(" uint32_t tRawData[]={0x"));
1198 # else
1199  tNumberOfArrayData = ((decodedIRData.numberOfBits - 1) / 64) + 1;
1200  if(tNumberOfArrayData > 1) {
1201  aSerial->println();
1202  aSerial->print(F(" uint64_t tRawData[]={0x"));
1203 # endif
1204  for (uint_fast8_t i = 0; i < tNumberOfArrayData; ++i) {
1205 # if (__INT_WIDTH__ < 32)
1206  aSerial->print(decodedIRData.decodedRawDataArray[i], HEX);
1207 # else
1208  PrintULL::print(aSerial, decodedIRData.decodedRawDataArray[i], HEX);
1209 # endif
1210  if (i != tNumberOfArrayData - 1) {
1211  aSerial->print(F(", 0x"));
1212  }
1213  }
1214  aSerial->println(F("};"));
1215  aSerial->print(F(" "));
1216  }
1217  }
1218  aSerial->print(F(" IrSender.send"));
1219 #else
1220  aSerial->print(F("Send with: IrSender.send"));
1221 #endif
1222 
1223 #if defined(DECODE_DISTANCE_WIDTH)
1225 #endif
1226  aSerial->print(getProtocolString());
1227  aSerial->print(F("(0x"));
1228 #if defined(DECODE_MAGIQUEST)
1229  if (decodedIRData.protocol == MAGIQUEST) {
1230 # if (__INT_WIDTH__ < 32)
1231  aSerial->print(decodedIRData.decodedRawData, HEX);
1232 # else
1233  PrintULL::print(aSerial, decodedIRData.decodedRawData, HEX);
1234 # endif
1235  } else {
1236  aSerial->print(decodedIRData.address, HEX);
1237  }
1238 #else
1239  /*
1240  * New decoders have address and command
1241  */
1242  aSerial->print(decodedIRData.address, HEX);
1243 #endif
1244 
1245  aSerial->print(F(", 0x"));
1246  aSerial->print(decodedIRData.command, HEX);
1247  if (decodedIRData.protocol == SONY) {
1248  aSerial->print(F(", 2, "));
1249  aSerial->print(decodedIRData.numberOfBits);
1250  } else {
1251  aSerial->print(F(", <numberOfRepeats>"));
1252  }
1253 
1254 #if defined(DECODE_DISTANCE_WIDTH)
1255  } else {
1256  if(tNumberOfArrayData > 1) {
1257  aSerial->print("PulseDistanceWidthFromArray(38, ");
1258  } else {
1259  aSerial->print("PulseDistanceWidth(38, ");
1260  }
1261  aSerial->print("PulseDistanceWidthFromArray(38, ");
1262  aSerial->print((decodedIRData.extra >> 8) * MICROS_PER_TICK); // aHeaderMarkMicros
1263  aSerial->print(F(", "));
1264  aSerial->print((decodedIRData.extra & 0xFF) * MICROS_PER_TICK);// aHeaderSpaceMicros
1265  aSerial->print(F(", "));
1266 
1267  // address = tMarkTicksLong (if tMarkTicksLong == 0, then tMarkTicksShort) << 8) | tSpaceTicksLong
1268  // command = tMarkTicksShort << 8) | tSpaceTicksShort
1269  aSerial->print((decodedIRData.address >> 8) * MICROS_PER_TICK);// aOneMarkMicros
1270  aSerial->print(F(", "));
1272  aSerial->print((decodedIRData.address & 0xFF) * MICROS_PER_TICK);// aOneSpaceMicros
1273  } else {
1274  aSerial->print((decodedIRData.command & 0xFF) * MICROS_PER_TICK);// aOneSpaceMicros
1275  }
1276  aSerial->print(F(", "));
1277  aSerial->print((decodedIRData.command >> 8) * MICROS_PER_TICK);// aZeroMarkMicros
1278  aSerial->print(F(", "));
1280  aSerial->print((decodedIRData.command & 0xFF) * MICROS_PER_TICK);// aZeroSpaceMicros
1281  }else {
1282  aSerial->print((decodedIRData.address & 0xFF) * MICROS_PER_TICK);// aZeroSpaceMicros
1283  }
1284  if(tNumberOfArrayData > 1) {
1285  aSerial->print(F(", &tRawData[0], "));
1286  } else {
1287  aSerial->print(F(", 0x"));
1288 # if (__INT_WIDTH__ < 32)
1289  aSerial->print(decodedIRData.decodedRawData, HEX);
1290 # else
1291  PrintULL::print(aSerial, decodedIRData.decodedRawData, HEX);
1292 # endif
1293  aSerial->print(F(", "));
1294  }
1295  aSerial->print(decodedIRData.numberOfBits);// aNumberOfBits
1297  aSerial->print(F(", PROTOCOL_IS_MSB_FIRST"));
1298  } else {
1299  aSerial->print(F(", PROTOCOL_IS_LSB_FIRST"));
1300  }
1302  aSerial->print(F(", SEND_STOP_BIT"));
1303  } else {
1304  aSerial->print(F(", SEND_NO_STOP_BIT")); // assume no stop bit like for Magiquest.
1305  }
1306  aSerial->print(F(", <millisofRepeatPeriod>, <numberOfRepeats>"));
1307  }
1308 #endif
1309  aSerial->print(F(");"));
1311  aSerial->print(
1312  F(
1313  " Because we have non standard extra data, you may have to use the send function, which accepts raw data like sendNECRaw() or sendRC6Raw(). Extra=0x"));
1314  aSerial->print(decodedIRData.extra, HEX);
1315  }
1316  aSerial->println();
1317  }
1318 }
1319 
1326 void IRrecv::printIRResultMinimal(Print *aSerial) {
1327  aSerial->print(F("P="));
1328  aSerial->print(decodedIRData.protocol);
1329  if (decodedIRData.protocol == UNKNOWN) {
1330 #if defined(DECODE_HASH)
1331  aSerial->print(F(" #=0x"));
1332 # if (__INT_WIDTH__ < 32)
1333  aSerial->print(decodedIRData.decodedRawData, HEX);
1334 # else
1335  PrintULL::print(aSerial, decodedIRData.decodedRawData, HEX);
1336 # endif
1337 #endif
1338  aSerial->print(' ');
1339  aSerial->print((decodedIRData.rawDataPtr->rawlen + 1) / 2, DEC);
1340  aSerial->println(F(" bits received"));
1341  } else {
1342  /*
1343  * New decoders have address and command
1344  */
1345  aSerial->print(F(" A=0x"));
1346  aSerial->print(decodedIRData.address, HEX);
1347 
1348  aSerial->print(F(" C=0x"));
1349  aSerial->print(decodedIRData.command, HEX);
1350 
1351  aSerial->print(F(" Raw=0x"));
1352 #if (__INT_WIDTH__ < 32)
1353  aSerial->print(decodedIRData.decodedRawData, HEX);
1354 #else
1355  PrintULL::print(aSerial, decodedIRData.decodedRawData, HEX);
1356 #endif
1357 
1359  aSerial->print(F(" R"));
1360  }
1361  }
1362 }
1363 
1370 void IRrecv::printIRResultRawFormatted(Print *aSerial, bool aOutputMicrosecondsInsteadOfTicks) {
1371 // Print Raw data
1372  aSerial->print(F("rawData["));
1373  aSerial->print(decodedIRData.rawDataPtr->rawlen, DEC);
1374  aSerial->println(F("]: "));
1375 
1376  /*
1377  * Print initial gap
1378  */
1379  aSerial->print(F(" -"));
1380  if (aOutputMicrosecondsInsteadOfTicks) {
1381  aSerial->println((uint32_t) decodedIRData.rawDataPtr->rawbuf[0] * MICROS_PER_TICK, DEC);
1382  } else {
1383  aSerial->println(decodedIRData.rawDataPtr->rawbuf[0], DEC);
1384  }
1385 #if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR
1386  uint_fast8_t i;
1387 #else
1388  unsigned int i;
1389 #endif
1390 
1391 // Newline is printed every 8. value, if tCounterForNewline % 8 == 0
1392  uint_fast8_t tCounterForNewline = 6; // first newline is after the 2 values of the start bit
1393 
1394 // check if we have a protocol with no or 8 start bits
1395 #if defined(DECODE_DENON) || defined(DECODE_MAGIQUEST)
1396  if (
1397 # if defined(DECODE_DENON)
1399 # endif
1400 # if defined(DECODE_MAGIQUEST)
1402 # endif
1403  false) {
1404  tCounterForNewline = 0; // no or 8 start bits
1405  }
1406 #endif
1407 
1408  uint32_t tDuration;
1409  uint16_t tSumOfDurationTicks = 0;
1410  for (i = 1; i < decodedIRData.rawDataPtr->rawlen; i++) {
1411  auto tCurrentTicks = decodedIRData.rawDataPtr->rawbuf[i];
1412  if (aOutputMicrosecondsInsteadOfTicks) {
1413  tDuration = tCurrentTicks * MICROS_PER_TICK;
1414  } else {
1415  tDuration = tCurrentTicks;
1416  }
1417  tSumOfDurationTicks += tCurrentTicks; // compute length of protocol frame
1418 
1419  if (!(i & 1)) { // even
1420  aSerial->print('-');
1421  } else { // odd
1422  aSerial->print(F(" +"));
1423  }
1424 
1425  // padding only for big values
1426  if (aOutputMicrosecondsInsteadOfTicks && tDuration < 1000) {
1427  aSerial->print(' ');
1428  }
1429  if (aOutputMicrosecondsInsteadOfTicks && tDuration < 100) {
1430  aSerial->print(' ');
1431  }
1432  if (tDuration < 10) {
1433  aSerial->print(' ');
1434  }
1435  aSerial->print(tDuration, DEC);
1436 
1437  if ((i & 1) && (i + 1) < decodedIRData.rawDataPtr->rawlen) {
1438  aSerial->print(','); //',' not required for last one
1439  }
1440 
1441  tCounterForNewline++;
1442  if ((tCounterForNewline % 8) == 0) {
1443  aSerial->println();
1444  }
1445  }
1446 
1447  aSerial->println();
1448  aSerial->print("Sum: ");
1449  if (aOutputMicrosecondsInsteadOfTicks) {
1450  aSerial->println((uint32_t) tSumOfDurationTicks * MICROS_PER_TICK, DEC);
1451  } else {
1452  aSerial->println(tSumOfDurationTicks, DEC);
1453  }
1454 }
1455 
1467 void IRrecv::compensateAndPrintIRResultAsCArray(Print *aSerial, bool aOutputMicrosecondsInsteadOfTicks) {
1468 // Start declaration
1469  if (aOutputMicrosecondsInsteadOfTicks) {
1470  aSerial->print(F("uint16_t rawData[")); // variable type, array name
1471  } else {
1472  aSerial->print(F("uint8_t rawTicks[")); // variable type, array name
1473  }
1474 
1475  aSerial->print(decodedIRData.rawDataPtr->rawlen - 1, DEC); // array size
1476  aSerial->print(F("] = {")); // Start declaration
1477 
1478 // Dump data
1479 #if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR
1480  uint_fast8_t i;
1481 #else
1482  unsigned int i;
1483 #endif
1484  for (i = 1; i < decodedIRData.rawDataPtr->rawlen; i++) {
1485  uint32_t tDuration = decodedIRData.rawDataPtr->rawbuf[i] * MICROS_PER_TICK;
1486 
1487  if (i & 1) {
1488  // Mark
1489  tDuration -= MARK_EXCESS_MICROS;
1490  } else {
1491  tDuration += MARK_EXCESS_MICROS;
1492  }
1493 
1494  if (aOutputMicrosecondsInsteadOfTicks) {
1495  aSerial->print(tDuration);
1496  } else {
1497  unsigned int tTicks = (tDuration + (MICROS_PER_TICK / 2)) / MICROS_PER_TICK;
1498  tTicks = (tTicks > UINT8_MAX) ? UINT8_MAX : tTicks; // uint8_t rawTicks above are 8 bit
1499  aSerial->print(tTicks);
1500  }
1501  if (i + 1 < decodedIRData.rawDataPtr->rawlen)
1502  aSerial->print(','); // ',' not required on last one
1503  if (!(i & 1))
1504  aSerial->print(' ');
1505  }
1506 
1507 // End declaration
1508  aSerial->print(F("};")); //
1509 
1510 // Comment
1511  aSerial->print(F(" // "));
1512  printIRResultShort(aSerial);
1513 
1514 // Newline
1515  aSerial->println("");
1516 }
1517 
1528 
1529 // Store data, skip leading space#
1530 #if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR
1531  uint_fast8_t i;
1532 #else
1533  unsigned int i;
1534 #endif
1535  for (i = 1; i < decodedIRData.rawDataPtr->rawlen; i++) {
1536  uint32_t tDuration = decodedIRData.rawDataPtr->rawbuf[i] * MICROS_PER_TICK;
1537  if (i & 1) {
1538  // Mark
1539  tDuration -= MARK_EXCESS_MICROS;
1540  } else {
1541  tDuration += MARK_EXCESS_MICROS;
1542  }
1543 
1544  unsigned int tTicks = (tDuration + (MICROS_PER_TICK / 2)) / MICROS_PER_TICK;
1545  *aArrayPtr = (tTicks > UINT8_MAX) ? UINT8_MAX : tTicks; // we store it in an 8 bit array
1546  aArrayPtr++;
1547  }
1548 }
1549 
1555 // Now dump "known" codes
1556  if (decodedIRData.protocol != UNKNOWN) {
1557 
1558  /*
1559  * New decoders have address and command
1560  */
1561  aSerial->print(F("uint16_t"));
1562  aSerial->print(F(" address = 0x"));
1563  aSerial->print(decodedIRData.address, HEX);
1564  aSerial->println(';');
1565 
1566  aSerial->print(F("uint16_t"));
1567  aSerial->print(F(" command = 0x"));
1568  aSerial->print(decodedIRData.command, HEX);
1569  aSerial->println(';');
1570 
1571  // All protocols have raw data
1572 #if __INT_WIDTH__ < 32
1573  aSerial->print(F("uint32_t rawData = 0x"));
1574 #else
1575  aSerial->print(F("uint64_t rawData = 0x"));
1576 #endif
1577 #if (__INT_WIDTH__ < 32)
1578  aSerial->print(decodedIRData.decodedRawData, HEX);
1579 #else
1580  PrintULL::print(aSerial, decodedIRData.decodedRawData, HEX);
1581 #endif
1582  aSerial->println(';');
1583  aSerial->println();
1584  }
1585 }
1586 
1587 #if defined(__AVR__)
1588 const __FlashStringHelper* IRrecv::getProtocolString() {
1589 // call no class function with same name
1591 }
1592 #else
1594  // call no class function with same name
1596 }
1597 #endif
1598 
1599 /**********************************************************************************************************************
1600  * The OLD and DEPRECATED decode function with parameter aResults, kept for backward compatibility to old 2.0 tutorials
1601  * This function calls the old MSB first decoders and fills only the 3 variables:
1602  * aResults->value
1603  * aResults->bits
1604  * aResults->decode_type
1605  **********************************************************************************************************************/
1607  static bool sDeprecationMessageSent = false;
1608 
1610  return false;
1611  }
1612 
1613  if (!sDeprecationMessageSent) {
1614 #if !(defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__))
1615  Serial.println(
1616  "The function decode(&results)) is deprecated and may not work as expected! Just use decode() without a parameter and IrReceiver.decodedIRData.<fieldname> .");
1617 #endif
1618  sDeprecationMessageSent = true;
1619  }
1620 
1621 // copy for usage by legacy programs
1622  aResults->rawbuf = irparams.rawbuf;
1623  aResults->rawlen = irparams.rawlen;
1624  if (irparams.OverflowFlag) {
1625  // Copy overflow flag to decodedIRData.flags
1626  irparams.OverflowFlag = false;
1627  irparams.rawlen = 0; // otherwise we have OverflowFlag again at next ISR call
1628  IR_DEBUG_PRINTLN(F("Overflow happened"));
1629  }
1630  aResults->overflow = irparams.OverflowFlag;
1631  aResults->value = 0;
1632 
1634 
1635 #if defined(DECODE_NEC)
1636  IR_DEBUG_PRINTLN(F("Attempting old NEC decode"));
1637  if (decodeNECMSB(aResults)) {
1638  return true;
1639  }
1640 #endif
1641 
1642 #if defined(DECODE_SONY)
1643  IR_DEBUG_PRINTLN(F("Attempting old Sony decode"));
1644  if (decodeSonyMSB(aResults)) {
1645  return true;
1646  }
1647 #endif
1648 
1649 #if defined(DECODE_RC5)
1650  IR_DEBUG_PRINTLN(F("Attempting RC5 decode"));
1651  if (decodeRC5()) {
1652  aResults->bits = decodedIRData.numberOfBits;
1653  aResults->value = decodedIRData.decodedRawData;
1654  aResults->decode_type = RC5;
1655 
1656  return true;
1657  }
1658 #endif
1659 
1660 #if defined(DECODE_RC6)
1661  IR_DEBUG_PRINTLN(F("Attempting RC6 decode"));
1662  if (decodeRC6()) {
1663  aResults->bits = decodedIRData.numberOfBits;
1664  aResults->value = decodedIRData.decodedRawData;
1665  aResults->decode_type = RC6;
1666  return true;
1667  }
1668 #endif
1669 
1670 // Removed bool IRrecv::decodePanasonicMSB(decode_results *aResults) since implementations was wrong (wrong length), and nobody recognized it
1671 
1672 #if defined(DECODE_LG)
1673  IR_DEBUG_PRINTLN(F("Attempting old LG decode"));
1674  if (decodeLGMSB(aResults)) {return true;}
1675 #endif
1676 
1677 #if defined(DECODE_JVC)
1678  IR_DEBUG_PRINTLN(F("Attempting old JVC decode"));
1679  if (decodeJVCMSB(aResults)) {
1680  return true;
1681  }
1682 #endif
1683 
1684 #if defined(DECODE_SAMSUNG)
1685  IR_DEBUG_PRINTLN(F("Attempting old SAMSUNG decode"));
1686  if (decodeSAMSUNG(aResults)) {
1687  return true;
1688  }
1689 #endif
1690 
1691 #if defined(DECODE_DENON)
1692  IR_DEBUG_PRINTLN(F("Attempting old Denon decode"));
1693  if (decodeDenonOld(aResults)) {
1694  return true;
1695  }
1696 #endif
1697 
1698 // decodeHash returns a hash on any input.
1699 // Thus, it needs to be last in the list.
1700 // If you add any decodes, add them before this.
1701  if (decodeHashOld(aResults)) {
1702  return true;
1703  }
1704 // Throw away and start over
1705  resume();
1706  return false;
1707 }
1708 
1710 #if defined(LOCAL_TRACE)
1711 #undef LOCAL_TRACE
1712 #endif
1713 #if defined(LOCAL_DEBUG)
1714 #undef LOCAL_DEBUG
1715 #endif
1716 #endif // _IR_RECEIVE_HPP
IRData::address
uint16_t address
Decoded address, Distance protocol (tMarkTicksLong (if tMarkTicksLong == 0, then tMarkTicksShort) << ...
Definition: IRProtocol.h:117
timerConfigForReceive
void timerConfigForReceive()
Configures the timer to be able to generate the receive sample interrupt, which consumes a small amou...
Definition: IRTimer.hpp:101
MICROS_PER_TICK
#define MICROS_PER_TICK
microseconds per clock interrupt tick
Definition: IRremote.hpp:258
decode_results
Results returned from old decoders !!!deprecated!!!
Definition: IRremoteInt.h:155
digitalReadFast
#define digitalReadFast
Definition: digitalWriteFast.h:377
DECODE_MAGIQUEST
#define DECODE_MAGIQUEST
Definition: IRremote.hpp:120
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:355
IRrecv::lastDecodedProtocol
decode_type_t lastDecodedProtocol
Definition: IRremoteInt.h:308
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:181
IRrecv::disableIRIn
void disableIRIn()
Alias for stop().
Definition: IRReceive.hpp:361
IRrecv::enableIRIn
void enableIRIn()
Alias for start().
Definition: IRReceive.hpp:325
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:159
pinModeFast
#define pinModeFast
Definition: digitalWriteFast.h:355
IRrecv::checkForRecordGapsMicros
bool checkForRecordGapsMicros(Print *aSerial)
Definition: IRReceive.hpp:1075
IRrecv::compare
uint_fast8_t compare(unsigned int oldval, unsigned int newval)
digitalWriteFast
#define digitalWriteFast
Definition: digitalWriteFast.h:323
IRrecv::registerReceiveCompleteCallback
void registerReceiveCompleteCallback(void(*aReceiveCompleteCallbackFunction)(void))
Sets the function to call if a protocol message has arrived.
Definition: IRReceive.hpp:299
IRrecv
Main class for receiving IR signals.
Definition: IRremoteInt.h:172
IRrecv::decodeDistanceWidth
bool decodeDistanceWidth()
Definition: ir_DistanceWidthProtocol.hpp:139
SONY
@ SONY
Definition: IRProtocol.h:64
sBiphaseCurrentTimingIntervals
unsigned int sBiphaseCurrentTimingIntervals
Definition: IRReceive.hpp:780
PULSE_WIDTH
@ PULSE_WIDTH
Definition: IRProtocol.h:42
decode_results::overflow
bool overflow
Definition: IRremoteInt.h:168
IRDATA_FLAGS_IS_REPEAT
#define IRDATA_FLAGS_IS_REPEAT
Definition: IRProtocol.h:94
PulseDistanceWidthProtocolConstants::ProtocolIndex
decode_type_t ProtocolIndex
Definition: IRProtocol.h:75
IRrecv::restartAfterSend
void restartAfterSend()
Restarts receiver after send.
Definition: IRReceive.hpp:346
MATCH
bool MATCH(unsigned int measured_ticks, unsigned int desired_us)
Definition: IRReceive.hpp:993
IRrecv::IRrecv
IRrecv()
Instantiate the IRrecv class.
Definition: IRReceive.hpp:70
sBiphaseDecodeRawbuffOffset
uint_fast8_t sBiphaseDecodeRawbuffOffset
Definition: IRReceive.hpp:779
TICKS_LOW
#define TICKS_LOW(us)
Definition: IRremoteInt.h:376
IRrecv::printIRResultAsCVariables
void printIRResultAsCVariables(Print *aSerial)
Print results as C variables to be used for sendXXX()
Definition: IRReceive.hpp:1554
MATCH_SPACE
bool MATCH_SPACE(unsigned int measured_ticks, unsigned int desired_us)
Definition: IRReceive.hpp:1059
decode_results::rawbuf
unsigned int * rawbuf
Definition: IRremoteInt.h:166
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:126
IRDATA_FLAGS_IS_AUTO_REPEAT
#define IRDATA_FLAGS_IS_AUTO_REPEAT
Definition: IRProtocol.h:95
IRrecv::initBiphaselevel
void initBiphaselevel(uint_fast8_t aRCDecodeRawbuffOffset, unsigned int aBiphaseTimeUnit)
Definition: IRReceive.hpp:784
decode_results::bits
uint8_t bits
Definition: IRremoteInt.h:161
decode_results::decode_type
decode_type_t decode_type
Definition: IRremoteInt.h:158
IRData::decodedRawData
IRRawDataType decodedRawData
Up to 32/64 bit decoded raw data, to be used for send functions.
Definition: IRProtocol.h:122
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:105
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:263
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:177
IRrecv::decodeSonyMSB
bool decodeSonyMSB(decode_results *aResults)
Definition: ir_Sony.hpp:154
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:95
IRrecv::read
IRData * read()
If IR receiver data is available, returns pointer to IrReceiver.decodedIRData, else NULL.
Definition: IRReceive.hpp:434
IRrecv::getBiphaselevel
uint_fast8_t getBiphaselevel()
Gets the level of one time interval (aBiphaseTimeUnit) at a time from the raw buffer.
Definition: IRReceive.hpp:806
MAGIQUEST
@ MAGIQUEST
Definition: IRProtocol.h:69
irparams_struct::rawlen
uint_fast8_t rawlen
counter of entries in rawbuf
Definition: IRremoteInt.h:109
IRrecv::decodeHashOld
bool decodeHashOld(decode_results *aResults)
timerDisableReceiveInterrupt
void timerDisableReceiveInterrupt()
Disables the receive sample timer interrupt.
Definition: IRTimer.hpp:113
IRrecv::decodePulseDistanceWidthData
bool decodePulseDistanceWidthData(PulseDistanceWidthProtocolConstants *aProtocolConstants, uint_fast8_t aNumberOfBits, uint_fast8_t aStartOffset=3)
Decode pulse distance protocols for PulseDistanceWidthProtocolConstants.
Definition: IRReceive.hpp:768
IRrecv::decodeLGMSB
bool decodeLGMSB(decode_results *aResults)
Definition: ir_LG.hpp:298
irparams
struct irparams_struct irparams
Definition: IRReceive.hpp:64
decode_results::value
uint32_t value
Definition: IRremoteInt.h:160
IRrecv::decodeSAMSUNG
bool decodeSAMSUNG(decode_results *aResults)
Definition: ir_Samsung.hpp:310
IRrecv::decodeBangOlufsen
bool decodeBangOlufsen()
Definition: ir_BangOlufsen.hpp:286
IRrecv::decodeLegoPowerFunctions
bool decodeLegoPowerFunctions()
Definition: ir_Lego.hpp:127
irparams_struct::OverflowFlag
bool OverflowFlag
Raw buffer OverflowFlag occurred.
Definition: IRremoteInt.h:107
PulseDistanceWidthProtocolConstants
Definition: IRProtocol.h:74
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
IRrecv::decodedIRData
IRData decodedIRData
Definition: IRremoteInt.h:305
IRData
Data structure for the user application, available as decodedIRData.
Definition: IRProtocol.h:115
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
matchSpace
bool matchSpace(unsigned int aMeasuredTicks, unsigned int aMatchValueMicros)
Compensate for spaces shortened by demodulator hardware.
Definition: IRReceive.hpp:1033
PulseDistanceWidthProtocolConstants::ZeroMarkMicros
unsigned int ZeroMarkMicros
Definition: IRProtocol.h:81
IRrecv::decodeSamsung
bool decodeSamsung()
Definition: ir_Samsung.hpp:212
IRData::flags
uint8_t flags
See IRDATA_FLAGS_* definitions above.
Definition: IRProtocol.h:121
MATCH_MARK
bool MATCH_MARK(unsigned int measured_ticks, unsigned int desired_us)
Definition: IRReceive.hpp:1026
sBiphaseTimeUnit
unsigned int sBiphaseTimeUnit
Definition: IRReceive.hpp:782
IRrecv::printIRResultShort
bool printIRResultShort(Print *aSerial, bool aPrintRepeatGap=true, bool aCheckForRecordGapsMicros=true)
Function to print values and flags of IrReceiver.decodedIRData in one line.
Definition: IRReceive.hpp:1171
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:99
DO_NOT_ENABLE_LED_FEEDBACK
#define DO_NOT_ENABLE_LED_FEEDBACK
Definition: IRremoteInt.h:338
IRrecv::checkForRepeatSpaceAndSetFlag
void checkForRepeatSpaceAndSetFlag(unsigned int aMediumRepeatSpaceMicros)
Definition: IRReceive.hpp:962
IRrecv::checkHeader
bool checkHeader(PulseDistanceWidthProtocolConstants *aProtocolConstants)
Definition: IRReceive.hpp:943
sBiphaseUsedTimingIntervals
uint_fast8_t sBiphaseUsedTimingIntervals
Definition: IRReceive.hpp:781
irparams_struct::rawbuf
unsigned int rawbuf[RAW_BUFFER_LENGTH]
raw data / tick counts per mark/space, first entry is the length of the gap between previous and curr...
Definition: IRremoteInt.h:113
PulseDistanceWidthProtocolConstants::HeaderSpaceMicros
unsigned int HeaderSpaceMicros
Definition: IRProtocol.h:78
IRrecv::printActiveIRProtocols
static void printActiveIRProtocols(Print *aSerial)
Definition: IRReceive.hpp:1100
printActiveIRProtocols
void printActiveIRProtocols(Print *aSerial)
Definition: IRReceive.hpp:1104
IRData::command
uint16_t command
Decoded command, Distance protocol (tMarkTicksShort << 8) | tSpaceTicksShort.
Definition: IRProtocol.h:118
IR_REC_STATE_STOP
#define IR_REC_STATE_STOP
Definition: IRremoteInt.h:89
IR_REC_STATE_MARK
#define IR_REC_STATE_MARK
Definition: IRremoteInt.h:87
IRrecv::decodeHash
bool decodeHash()
IRrecv::isIdle
bool isIdle()
Returns status of reception.
Definition: IRReceive.hpp:375
timerResetInterruptPending
void timerResetInterruptPending()
timerEnableReceiveInterrupt
void timerEnableReceiveInterrupt()
Enables the receive sample timer interrupt, which consumes a small amount of CPU every 50 us.
Definition: IRTimer.hpp:106
getMarkExcessMicros
int getMarkExcessMicros()
Getter function for MARK_EXCESS_MICROS.
Definition: IRReceive.hpp:1066
LED_FEEDBACK_ENABLED_FOR_RECEIVE
#define LED_FEEDBACK_ENABLED_FOR_RECEIVE
Definition: IRremoteInt.h:340
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:1467
matchTicks
bool matchTicks(unsigned int aMeasuredTicks, unsigned int aMatchValueMicros)
Match function without compensating for marks exceeded or spaces shortened by demodulator hardware Cu...
Definition: IRReceive.hpp:973
irparams_struct::TickCounterForISR
volatile uint_fast16_t TickCounterForISR
Counts 50uS ticks. The value is copied into the rawbuf array on every transition.
Definition: IRremoteInt.h:103
irparams_struct::StateForISR
volatile uint8_t StateForISR
State Machine state.
Definition: IRremoteInt.h:97
IRrecv::setReceivePin
void setReceivePin(uint_fast8_t aReceivePinNumber)
Sets / changes the receiver pin number.
Definition: IRReceive.hpp:286
IRrecv::decodeDenonOld
bool decodeDenonOld(decode_results *aResults)
Definition: ir_Denon.hpp:286
IRRawDataType
uint32_t IRRawDataType
Definition: IRremoteInt.h:117
IRrecv::start
void start()
Start the receiving process.
Definition: IRReceive.hpp:308
IRrecv::compensateAndStoreIRResultInArray
void compensateAndStoreIRResultInArray(uint8_t *aArrayPtr)
Store the decodedIRData to be used for sendRaw().
Definition: IRReceive.hpp:1527
IRrecv::printIRResultMinimal
void printIRResultMinimal(Print *aSerial)
Function to print protocol number, address, command, raw data and repeat flag of IrReceiver....
Definition: IRReceive.hpp:1326
IR_TRACE_PRINTLN
#define IR_TRACE_PRINTLN(...)
Definition: IRremoteInt.h:145
IRrecv::initDecodedIRData
void initDecodedIRData()
Is internally called by decode before calling decoders.
Definition: IRReceive.hpp:396
DENON
@ DENON
Definition: IRProtocol.h:45
DECODE_DENON
#define DECODE_DENON
Definition: IRremote.hpp:106
IRDATA_FLAGS_IS_MSB_FIRST
#define IRDATA_FLAGS_IS_MSB_FIRST
Value is mainly determined by the (known) protocol.
Definition: IRProtocol.h:100
IRrecv::lastDecodedCommand
uint32_t lastDecodedCommand
Definition: IRremoteInt.h:310
TICKS_HIGH
#define TICKS_HIGH(us)
Definition: IRremoteInt.h:377
PulseDistanceWidthProtocolConstants::OneMarkMicros
unsigned int OneMarkMicros
Definition: IRProtocol.h:79
IRrecv::decodeRC5
bool decodeRC5()
Try to decode data as RC5 protocol.
Definition: ir_RC5_RC6.hpp:157
IRrecv::decodeBoseWave
bool decodeBoseWave()
Definition: ir_BoseWave.hpp:63
IRDATA_FLAGS_EMPTY
#define IRDATA_FLAGS_EMPTY
Definition: IRProtocol.h:93
RC5
@ RC5
Definition: IRProtocol.h:58
IRrecv::available
bool available()
Returns true if IR receiver data is available.
Definition: IRReceive.hpp:427
IRData::extra
uint16_t extra
Contains upper 16 bit of Magiquest WandID, Kaseikyo unknown vendor ID and Distance protocol (HeaderMa...
Definition: IRProtocol.h:119
PulseDistanceWidthProtocolConstants::HeaderMarkMicros
unsigned int HeaderMarkMicros
Definition: IRProtocol.h:77
IRrecv::decodeMagiQuest
bool decodeMagiQuest()
Definition: ir_MagiQuest.hpp:151
INPUT_MARK
#define INPUT_MARK
Sensor output for a mark ("flash")
Definition: IRremote.hpp:192
FeedbackLEDControl
struct FeedbackLEDControlStruct FeedbackLEDControl
The feedback LED control instance.
Definition: IRFeedbackLED.hpp:47
IRrecv::end
void end()
Alias for stop().
Definition: IRReceive.hpp:367
SPACE
#define SPACE
Definition: IRremoteInt.h:39
IRrecv::decodeNECMSB
bool decodeNECMSB(decode_results *aResults)
Definition: ir_NEC.hpp:323
IRrecv::decodeNEC
bool decodeNEC()
Decodes also Onkyo and Apple.
Definition: ir_NEC.hpp:225
PulseDistanceWidthProtocolConstants::OneSpaceMicros
unsigned int OneSpaceMicros
Definition: IRProtocol.h:80
RC6
@ RC6
Definition: IRProtocol.h:59
IRrecv::printIRSendUsage
void printIRSendUsage(Print *aSerial)
Function to print values and flags of IrReceiver.decodedIRData in one line.
Definition: IRReceive.hpp:1186
IRrecv::decodeDenon
bool decodeDenon()
Definition: ir_Denon.hpp:158
IRrecv::decodeLG
bool decodeLG()
Definition: ir_LG.hpp:184
IRrecv::decode
bool decode()
The main decode function, attempts to decode the recently receive IR signal.
Definition: IRReceive.hpp:451
IRrecv::decodeJVC
bool decodeJVC()
Definition: ir_JVC.hpp:121
UNKNOWN
@ UNKNOWN
Definition: IRProtocol.h:41
RAW_BUFFER_LENGTH
#define RAW_BUFFER_LENGTH
The length of the buffer where the IR timing data is stored before decoding 100 is sufficient for mos...
Definition: IRremoteInt.h:74
IRrecv::lastDecodedAddress
uint32_t lastDecodedAddress
Definition: IRremoteInt.h:309
IRrecv::decodeKaseikyo
bool decodeKaseikyo()
Definition: ir_Kaseikyo.hpp:191
IR_DEBUG_PRINTLN
#define IR_DEBUG_PRINTLN(...)
If DEBUG, print the arguments as a line, otherwise do nothing.
Definition: IRremoteInt.h:137
PulseDistanceWidthProtocolConstants::isMSBFirst
bool isMSBFirst
Definition: IRProtocol.h:83
matchMark
bool matchMark(unsigned int aMeasuredTicks, unsigned int aMatchValueMicros)
Compensate for marks exceeded by demodulator hardware.
Definition: IRReceive.hpp:1000
PulseDistanceWidthProtocolConstants::ZeroSpaceMicros
unsigned int ZeroSpaceMicros
Definition: IRProtocol.h:82
decode_results::rawlen
uint_fast8_t rawlen
Definition: IRremoteInt.h:167
IRData::protocol
decode_type_t protocol
UNKNOWN, NEC, SONY, RC5, PULSE_DISTANCE, ...
Definition: IRProtocol.h:116
IRrecv::decodeRC6
bool decodeRC6()
Try to decode data as RC6 protocol.
Definition: ir_RC5_RC6.hpp:401
IR_REC_STATE_SPACE
#define IR_REC_STATE_SPACE
Definition: IRremoteInt.h:88
IRrecv::getProtocolString
const char * getProtocolString()
Definition: IRReceive.hpp:1593
IRrecv::resume
void resume()
Restart the ISR (Interrupt Service Routine) state machine, to enable receiving of the next IR frame.
Definition: IRReceive.hpp:382
MARK
#define MARK
Definition: IRremoteInt.h:38
IRrecv::startWithTicksToAdd
void startWithTicksToAdd(uint16_t aTicksToAddToGapCounter)
Definition: IRReceive.hpp:338
IrReceiver
IRrecv IrReceiver
The receiver instance.
Definition: IRReceive.hpp:59
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:1370
IR_REC_STATE_IDLE
#define IR_REC_STATE_IDLE
Definition: IRremoteInt.h:86
getProtocolString
const char * getProtocolString(decode_type_t aProtocol)
Definition: IRProtocol.hpp:100
IRrecv::decodeJVCMSB
bool decodeJVCMSB(decode_results *aResults)
Definition: ir_JVC.hpp:178
setLEDFeedback
void setLEDFeedback(uint8_t aFeedbackLEDPin, uint8_t aEnableLEDFeedback)
Enable 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:63
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:98