33 #ifndef _IR_RECEIVE_HPP
34 #define _IR_RECEIVE_HPP
42 #if defined(TRACE) && !defined(LOCAL_TRACE)
74 #if !defined(NO_LED_FEEDBACK_CODE)
82 #if !defined(NO_LED_FEEDBACK_CODE)
95 #if !defined(NO_LED_FEEDBACK_CODE)
98 (void) aFeedbackLEDPin;
120 #if defined(ESP8266) || defined(ESP32)
121 #pragma GCC diagnostic push
122 #pragma GCC diagnostic ignored "-Wvolatile"
126 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
131 #if defined(TIMER_REQUIRES_RESET_INTR_PENDING)
137 uint8_t tIRInputLevel = *
irparams.IRReceivePinPortInputRegister &
irparams.IRReceivePinMask;
162 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
186 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
222 #if !defined(IR_REMOTE_DISABLE_RECEIVE_COMPLETE_CALLBACK)
235 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
247 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
256 #if !defined(NO_LED_FEEDBACK_CODE)
262 #ifdef _IR_MEASURE_TIMING
271 #if defined(TIMER_INTR_NAME) || defined(ISR)
272 # if defined(TIMER_INTR_NAME)
273 ISR (TIMER_INTR_NAME)
293 void IRrecv::begin(uint_fast8_t aReceivePin,
bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin) {
296 #if !defined(NO_LED_FEEDBACK_CODE)
298 if (aEnableLEDFeedback) {
303 (void) aEnableLEDFeedback;
304 (void) aFeedbackLEDPin;
307 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
319 # if defined(__digitalPinToBit)
320 if (__builtin_constant_p(aReceivePinNumber)) {
321 irparams.IRReceivePinMask = 1UL << (__digitalPinToBit(aReceivePinNumber));
323 irparams.IRReceivePinMask = digitalPinToBitMask(aReceivePinNumber);
326 irparams.IRReceivePinMask = digitalPinToBitMask(aReceivePinNumber);
328 # if defined(__digitalPinToPINReg)
332 if (__builtin_constant_p(aReceivePinNumber)) {
333 irparams.IRReceivePinPortInputRegister = __digitalPinToPINReg(aReceivePinNumber);
335 irparams.IRReceivePinPortInputRegister = portInputRegister(digitalPinToPort(aReceivePinNumber));
338 irparams.IRReceivePinPortInputRegister = portInputRegister(digitalPinToPort(aReceivePinNumber));
343 if (__builtin_constant_p(aReceivePinNumber)) {
350 #if !defined(IR_REMOTE_DISABLE_RECEIVE_COMPLETE_CALLBACK)
374 #ifdef _IR_MEASURE_TIMING
391 #ifdef _IR_MEASURE_TIMING
416 #ifdef _IR_MEASURE_TIMING
428 #ifdef _IR_MEASURE_TIMING
432 #if defined(ESP8266) || defined(ESP32)
433 #pragma GCC diagnostic push
440 #if defined(SEND_PWM_BY_TIMER) && !defined(SEND_PWM_DOES_NOT_USE_RECEIVE_TIMER)
499 #if defined(LOCAL_DEBUG)
500 Serial.print(F(
"Overflow happened, try to increase the \"RAW_BUFFER_LENGTH\" value of "));
502 Serial.println(F(
" with #define RAW_BUFFER_LENGTH=<biggerValue>"));
570 #if defined(DECODE_NEC) || defined(DECODE_ONKYO)
577 #if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO)
584 #if defined(DECODE_DENON)
591 #if defined(DECODE_SONY)
598 #if defined(DECODE_RC5)
605 #if defined(DECODE_RC6)
612 #if defined(DECODE_LG)
619 #if defined(DECODE_JVC)
626 #if defined(DECODE_SAMSUNG)
636 #if defined(DECODE_BEO)
643 #if defined(DECODE_FAST)
650 #if defined(DECODE_WHYNTER)
657 #if defined(DECODE_LEGO_PF)
664 #if defined(DECODE_BOSEWAVE)
671 #if defined(DECODE_MAGIQUEST)
681 #if defined(DECODE_DISTANCE_WIDTH)
691 #if defined(DECODE_HASH)
732 uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros,
bool aMSBfirst) {
736 bool isPulseDistanceProtocol = (aOneMarkMicros == aZeroMarkMicros);
741 for (uint_fast8_t i = aNumberOfBits; i > 0; i--) {
743 unsigned int tMarkTicks;
744 unsigned int tSpaceTicks;
747 if (isPulseDistanceProtocol) {
753 tSpaceTicks = *tRawBufPointer++;
754 tBitValue =
matchSpace(tSpaceTicks, aOneSpaceMicros);
761 tMarkTicks = *tRawBufPointer++;
762 tBitValue =
matchMark(tMarkTicks, aOneMarkMicros);
775 tDecodedData |= tMask;
792 uint16_t aZeroMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroSpaceMicros,
bool aMSBfirst) {
794 (void) aZeroSpaceMicros;
796 bool isPulseDistanceProtocol = (aOneMarkMicros == aZeroMarkMicros);
801 for (uint_fast8_t i = aNumberOfBits; i > 0; i--) {
803 unsigned int tMarkTicks;
804 unsigned int tSpaceTicks;
807 if (isPulseDistanceProtocol) {
812 (void) aZeroSpaceMicros;
814 tSpaceTicks = *tRawBufPointer++;
815 tBitValue =
matchSpace(tSpaceTicks, aOneSpaceMicros);
820 tMarkTicks = *tRawBufPointer++;
821 tBitValue =
matchMark(tMarkTicks, aOneMarkMicros);
834 tDecodedData |= tMask;
857 uint16_t aZeroMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroSpaceMicros,
bool aMSBfirst) {
861 bool isPulseDistanceProtocol = (aOneMarkMicros == aZeroMarkMicros);
866 for (uint_fast8_t i = aNumberOfBits; i > 0; i--) {
868 unsigned int tMarkTicks;
869 unsigned int tSpaceTicks;
872 if (isPulseDistanceProtocol) {
876 tMarkTicks = *tRawBufPointer++;
877 tSpaceTicks = *tRawBufPointer++;
878 tBitValue =
matchSpace(tSpaceTicks, aOneSpaceMicros);
881 if (!
matchMark(tMarkTicks, aOneMarkMicros)) {
882 #if defined(LOCAL_DEBUG)
883 Serial.print(F(
"Mark="));
885 Serial.print(F(
" is not "));
886 Serial.print(aOneMarkMicros);
887 Serial.print(F(
". Index="));
888 Serial.print(aNumberOfBits - i);
900 tMarkTicks = *tRawBufPointer++;
901 tBitValue =
matchMark(tMarkTicks, aOneMarkMicros);
902 tSpaceTicks = *tRawBufPointer++;
914 tDecodedData |= tMask;
922 if (isPulseDistanceProtocol) {
923 if (!
matchSpace(tSpaceTicks, aZeroSpaceMicros)) {
924 #if defined(LOCAL_DEBUG)
925 Serial.print(F(
"Space="));
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);
938 if (!
matchMark(tMarkTicks, aZeroMarkMicros)) {
939 #if defined(LOCAL_DEBUG)
940 Serial.print(F(
"Mark="));
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);
957 if (aZeroSpaceMicros == aOneSpaceMicros
960 if (!
matchSpace(tSpaceTicks, aOneSpaceMicros)) {
961 #if defined(LOCAL_DEBUG)
962 Serial.print(F(
"Space="));
964 Serial.print(F(
" is not "));
965 Serial.print(aOneSpaceMicros);
966 Serial.print(F(
". Index="));
967 Serial.print(aNumberOfBits - i);
988 aProtocolConstants->
Flags);
992 uint_fast8_t aNumberOfBits,
IRRawlenType aStartOffset) {
994 memcpy_P(&tTemporaryPulseDistanceWidthProtocolConstants, aProtocolConstantsPGM,
995 sizeof(tTemporaryPulseDistanceWidthProtocolConstants));
1031 uint_fast8_t tLevelOfCurrentInterval;
1069 return tLevelOfCurrentInterval;
1075 #define FNV_PRIME_32 16777619
1076 #define FNV_BASIS_32 2166136261
1084 if (newval * 10 < oldval * 8) {
1087 if (oldval * 10 < newval * 8) {
1139 if (aResults->
rawlen < 6) {
1143 for (uint8_t i = 3; i < aResults->
rawlen; i++) {
1149 aResults->
value = hash;
1150 aResults->
bits = 32;
1167 #if defined(LOCAL_TRACE)
1169 Serial.println(F(
": Header mark length is wrong"));
1174 #if defined(LOCAL_TRACE)
1176 Serial.println(F(
": Header space length is wrong"));
1186 #if defined(LOCAL_TRACE)
1188 Serial.println(F(
": Header mark length is wrong"));
1193 #if defined(LOCAL_TRACE)
1195 Serial.println(F(
": Header space length is wrong"));
1209 #
if defined(ENABLE_COMPLETE_REPEAT_CHECK)
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);
1232 bool passed = ((aMeasuredTicks >=
TICKS_LOW(aMatchValueMicros)) && (aMeasuredTicks <=
TICKS_HIGH(aMatchValueMicros)));
1233 #if defined(LOCAL_TRACE)
1235 Serial.println(F(
" => passed"));
1237 Serial.println(F(
" => FAILED"));
1243 bool MATCH(uint16_t measured_ticks, uint16_t desired_us) {
1244 return matchTicks(measured_ticks, desired_us);
1251 bool matchMark(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros) {
1252 #if defined(LOCAL_TRACE)
1253 Serial.print(F(
"Testing mark (actual vs desired): "));
1255 Serial.print(F(
"us vs "));
1256 Serial.print(aMatchValueMicros, DEC);
1257 Serial.print(F(
"us: "));
1259 Serial.print(F(
" <= "));
1261 Serial.print(F(
" <= "));
1267 #if defined(LOCAL_TRACE)
1269 Serial.println(F(
" => passed"));
1271 Serial.println(F(
" => FAILED"));
1278 return matchMark(measured_ticks, desired_us);
1285 bool matchSpace(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros) {
1286 #if defined(LOCAL_TRACE)
1287 Serial.print(F(
"Testing space (actual vs desired): "));
1289 Serial.print(F(
"us vs "));
1290 Serial.print(aMatchValueMicros, DEC);
1291 Serial.print(F(
"us: "));
1293 Serial.print(F(
" <= "));
1295 Serial.print(F(
" <= "));
1301 #if defined(LOCAL_TRACE)
1303 Serial.println(F(
" => passed"));
1305 Serial.println(F(
" => FAILED"));
1312 return matchSpace(measured_ticks, desired_us);
1335 aSerial->print(F(
"Space of "));
1337 aSerial->print(F(
" us between two detected transmission is smaller than the minimal gap of "));
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."));
1361 #if defined(DECODE_ONKYO)
1362 aSerial->print(F(
"Onkyo, "));
1363 #elif defined(DECODE_NEC)
1364 aSerial->print(F(
"NEC/NEC2/Onkyo/Apple, "));
1366 #if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO)
1367 aSerial->print(F(
"Panasonic/Kaseikyo, "));
1369 #if defined(DECODE_DENON)
1370 aSerial->print(F(
"Denon/Sharp, "));
1372 #if defined(DECODE_SONY)
1373 aSerial->print(F(
"Sony, "));
1375 #if defined(DECODE_RC5)
1376 aSerial->print(F(
"RC5, "));
1378 #if defined(DECODE_RC6)
1379 aSerial->print(F(
"RC6, "));
1381 #if defined(DECODE_LG)
1382 aSerial->print(F(
"LG, "));
1384 #if defined(DECODE_JVC)
1385 aSerial->print(F(
"JVC, "));
1387 #if defined(DECODE_SAMSUNG)
1388 aSerial->print(F(
"Samsung, "));
1393 #if defined(DECODE_BEO)
1394 aSerial->print(F(
"Bang & Olufsen, "));
1396 #if defined(DECODE_FAST)
1397 aSerial->print(F(
"FAST, "));
1399 #if defined(DECODE_WHYNTER)
1400 aSerial->print(F(
"Whynter, "));
1402 #if defined(DECODE_LEGO_PF)
1403 aSerial->print(F(
"Lego Power Functions, "));
1405 #if defined(DECODE_BOSEWAVE)
1406 aSerial->print(F(
"Bosewave, "));
1408 #if defined(DECODE_MAGIQUEST)
1409 aSerial->print(F(
"MagiQuest, "));
1411 #if defined(DECODE_DISTANCE_WIDTH)
1412 aSerial->print(F(
"Universal Pulse Distance Width, "));
1414 #if defined(DECODE_HASH)
1415 aSerial->print(F(
"Hash "));
1417 #if defined(NO_DECODER) // for sending raw only
1442 aSerial->print(F(
", "));
1444 aSerial->print(F(
", "));
1446 aSerial->print(F(
", "));
1448 aSerial->print(F(
", "));
1450 aSerial->print(F(
", "));
1459 uint8_t tMaximumTick = 0;
1462 if (tMaximumTick < tTick) {
1463 tMaximumTick = tTick;
1466 return tMaximumTick;
1469 uint8_t tMaximumTick = 0;
1472 if (tMaximumTick < tTick) {
1473 tMaximumTick = tTick;
1476 return tMaximumTick;
1483 uint8_t tMaximumTick = 0;
1485 if (aSearchSpaceInsteadOfMark) {
1492 if (tMaximumTick < tTick) {
1493 tMaximumTick = tTick;
1496 return tMaximumTick;
1500 uint16_t tSumOfDurationTicks = 0;
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: "));
1526 if(tNumberOfArrayData > 1) {
1528 aSerial->print(F(
" uint32_t tRawData[]={0x"));
1530 aSerial->print(F(
"Send on a 32 bit platform with: "));
1532 if(tNumberOfArrayData > 1) {
1534 aSerial->print(F(
" uint64_t tRawData[]={0x"));
1536 for (uint_fast8_t i = 0; i < tNumberOfArrayData; ++i) {
1537 # if (__INT_WIDTH__ < 32)
1540 PrintULL::print(aSerial,
decodedIRData.decodedRawDataArray[i], HEX);
1542 if (i != tNumberOfArrayData - 1) {
1543 aSerial->print(F(
", 0x"));
1546 aSerial->println(F(
"};"));
1547 aSerial->print(F(
" "));
1550 aSerial->print(F(
"Send with: "));
1552 aSerial->print(F(
"IrSender.send"));
1555 aSerial->print(F(
"Send with: IrSender.send"));
1558 #if defined(DECODE_DISTANCE_WIDTH)
1562 aSerial->print(F(
"(0x"));
1563 #if defined(DECODE_MAGIQUEST)
1565 # if (__INT_WIDTH__ < 32)
1580 aSerial->print(F(
", 0x"));
1583 aSerial->print(F(
", 2, "));
1586 aSerial->print(F(
", <numberOfRepeats>"));
1589 #if defined(DECODE_DISTANCE_WIDTH)
1594 aSerial->print(F(
"PulseDistanceWidth"));
1595 if(tNumberOfArrayData > 1) {
1596 aSerial->print(F(
"FromArray(38, "));
1598 aSerial->print(F(
"(38, "));
1602 if(tNumberOfArrayData > 1) {
1603 aSerial->print(F(
", &tRawData[0], "));
1605 aSerial->print(F(
", 0x"));
1606 # if (__INT_WIDTH__ < 32)
1611 aSerial->print(F(
", "));
1614 aSerial->print(F(
", PROTOCOL_IS_"));
1617 aSerial->print(
'M');
1619 aSerial->print(
'L');
1621 aSerial->print(F(
"SB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats>"));
1624 #if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO) || defined(DECODE_RC6)
1626 aSerial->print(F(
", 0x"));
1630 aSerial->print(F(
");"));
1642 aSerial->print(F(
"P="));
1645 #if defined(DECODE_HASH)
1646 aSerial->print(F(
" #=0x"));
1647 # if (__INT_WIDTH__ < 32)
1653 aSerial->print(
' ');
1655 aSerial->println(F(
" bits received"));
1660 aSerial->print(F(
" A=0x"));
1663 aSerial->print(F(
" C=0x"));
1666 aSerial->print(F(
" Raw=0x"));
1667 #if (__INT_WIDTH__ < 32)
1674 aSerial->print(F(
" R"));
1683 uint16_t tSumOfDurationTicks = 0;
1687 aSerial->print(F(
"Duration="));
1688 if (aOutputMicrosecondsInsteadOfTicks) {
1689 aSerial->print((uint32_t) tSumOfDurationTicks *
MICROS_PER_TICK, DEC);
1690 aSerial->println(F(
"us"));
1693 aSerial->print(tSumOfDurationTicks, DEC);
1694 aSerial->println(F(
" ticks"));
1707 aSerial->print(F(
"rawData["));
1709 aSerial->println(F(
"]: "));
1714 aSerial->print(F(
" -"));
1715 if (aOutputMicrosecondsInsteadOfTicks) {
1722 uint_fast8_t tCounterForNewline = 6;
1725 #if defined(DECODE_DENON) || defined(DECODE_MAGIQUEST)
1734 tCounterForNewline = 0;
1739 uint16_t tSumOfDurationTicks = 0;
1742 if (aOutputMicrosecondsInsteadOfTicks) {
1745 tDuration = tCurrentTicks;
1747 tSumOfDurationTicks += tCurrentTicks;
1750 aSerial->print(
'-');
1752 aSerial->print(F(
" +"));
1756 if (aOutputMicrosecondsInsteadOfTicks && tDuration < 1000) {
1757 aSerial->print(
' ');
1759 if (aOutputMicrosecondsInsteadOfTicks && tDuration < 100) {
1760 aSerial->print(
' ');
1762 if (tDuration < 10) {
1763 aSerial->print(
' ');
1765 aSerial->print(tDuration, DEC);
1768 aSerial->print(
',');
1771 tCounterForNewline++;
1772 if ((tCounterForNewline % 8) == 0) {
1778 aSerial->print(F(
"Duration="));
1779 if (aOutputMicrosecondsInsteadOfTicks) {
1780 aSerial->print((uint32_t) tSumOfDurationTicks *
MICROS_PER_TICK, DEC);
1781 aSerial->println(F(
"us"));
1784 aSerial->print(tSumOfDurationTicks, DEC);
1785 aSerial->println(F(
" ticks"));
1804 if (aOutputMicrosecondsInsteadOfTicks) {
1805 aSerial->print(F(
"uint16_t rawData["));
1807 aSerial->print(F(
"uint8_t rawTicks["));
1811 aSerial->print(F(
"] = {"));
1824 if (aOutputMicrosecondsInsteadOfTicks) {
1825 aSerial->print(tDuration);
1831 tTicks = (tTicks > UINT8_MAX) ? UINT8_MAX : tTicks;
1832 aSerial->print(tTicks);
1835 if (!(i & 1)) aSerial->print(
' ');
1839 aSerial->print(F(
"};"));
1842 aSerial->print(F(
" // "));
1872 *aArrayPtr = (tTicks > UINT8_MAX) ? UINT8_MAX : tTicks;
1888 aSerial->print(F(
"uint16_t"));
1889 aSerial->print(F(
" address = 0x"));
1891 aSerial->println(
';');
1893 aSerial->print(F(
"uint16_t"));
1894 aSerial->print(F(
" command = 0x"));
1896 aSerial->println(
';');
1899 #if __INT_WIDTH__ < 32
1900 aSerial->print(F(
"uint32_t rawData = 0x"));
1902 aSerial->print(F(
"uint64_t rawData = 0x"));
1904 #if (__INT_WIDTH__ < 32)
1909 aSerial->println(
';');
1914 #if defined(__AVR__)
1952 aResults->
value = 0;
1956 #if defined(DECODE_NEC)
1963 #if defined(DECODE_SONY)
1970 #if defined(DECODE_RC5)
1981 #if defined(DECODE_RC6)
1993 #if defined(DECODE_LG)
1998 #if defined(DECODE_JVC)
2005 #if defined(DECODE_SAMSUNG)
2012 #if defined(DECODE_DENON)
2031 #if defined(_IR_MEASURE_TIMING)
2032 #undef _IR_MEASURE_TIMING
2034 #if defined(LOCAL_TRACE)
2037 #if defined(LOCAL_DEBUG)
2040 #endif // _IR_RECEIVE_HPP