35 #if defined(DEBUG) && !defined(LOCAL_DEBUG)
41 #if defined(TRACE) && !defined(LOCAL_TRACE)
56 #if defined(IR_SEND_PIN)
57 #define sendPin IR_SEND_PIN
68 #if !defined(IR_SEND_PIN)
72 #if !defined(NO_LED_FEEDBACK_CODE)
77 #if defined(IR_SEND_PIN)
83 # if !defined(NO_LED_FEEDBACK_CODE)
86 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
96 void IRsend::begin(
bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin) {
97 #if !defined(NO_LED_FEEDBACK_CODE)
99 if(aEnableLEDFeedback) {
104 (void) aEnableLEDFeedback;
105 (void) aFeedbackLEDPin;
109 #else // defined(IR_SEND_PIN)
112 # if !defined(NO_LED_FEEDBACK_CODE)
123 # if !defined(NO_LED_FEEDBACK_CODE)
138 void IRsend::begin(uint_fast8_t aSendPin,
bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin) {
139 #if defined(IR_SEND_PIN)
145 #if !defined(NO_LED_FEEDBACK_CODE)
147 if (aEnableLEDFeedback) {
152 (void) aEnableLEDFeedback;
153 (void) aFeedbackLEDPin;
156 #endif // defined(IR_SEND_PIN)
172 auto tProtocol = aIRSendData->
protocol;
173 auto tAddress = aIRSendData->
address;
174 auto tCommand = aIRSendData->
command;
214 if (tProtocol ==
NEC) {
217 }
else if (tProtocol ==
SAMSUNG) {
226 }
else if (tProtocol ==
SONY) {
232 }
else if (tProtocol ==
DENON) {
235 }
else if (tProtocol ==
SHARP) {
238 }
else if (tProtocol ==
LG) {
241 }
else if (tProtocol ==
JVC) {
244 }
else if (tProtocol ==
RC5) {
247 }
else if (tProtocol ==
RC6) {
262 }
else if (tProtocol ==
NEC2) {
265 }
else if (tProtocol ==
ONKYO) {
268 }
else if (tProtocol ==
APPLE) {
271 #if !defined(EXCLUDE_EXOTIC_PROTOCOLS)
279 }
else if (tProtocol ==
FAST) {
283 }
else if (tProtocol ==
LEGO_PF) {
335 if (aProtocol ==
NEC) {
338 }
else if (aProtocol ==
SAMSUNG) {
347 }
else if (aProtocol ==
SONY) {
353 }
else if (aProtocol ==
DENON) {
356 }
else if (aProtocol ==
SHARP) {
359 }
else if (aProtocol ==
LG) {
362 }
else if (aProtocol ==
JVC) {
365 }
else if (aProtocol ==
RC5) {
368 }
else if (aProtocol ==
RC6) {
383 }
else if (aProtocol ==
NEC2) {
386 }
else if (aProtocol ==
ONKYO) {
389 }
else if (aProtocol ==
APPLE) {
392 #if !defined(EXCLUDE_EXOTIC_PROTOCOLS)
396 }
else if (aProtocol ==
FAST) {
400 }
else if (aProtocol ==
LEGO_PF) {
414 void IRsend::sendRaw(
const uint16_t aBufferWithMicroseconds[], uint_fast16_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz) {
421 for (uint_fast16_t i = 0; i < aLengthOfBuffer; i++) {
424 space(aBufferWithMicroseconds[i]);
426 mark(aBufferWithMicroseconds[i]);
435 void IRsend::sendRaw(
const uint8_t aBufferWithTicks[], uint_fast16_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz) {
439 for (uint_fast16_t i = 0; i < aLengthOfBuffer; i++) {
455 uint_fast8_t aIRFrequencyKilohertz) {
456 #if !defined(__AVR__)
457 sendRaw(aBufferWithMicroseconds, aLengthOfBuffer, aIRFrequencyKilohertz);
464 for (uint_fast16_t i = 0; i < aLengthOfBuffer; i++) {
465 auto duration = pgm_read_word(&aBufferWithMicroseconds[i]);
469 # if defined(LOCAL_DEBUG)
470 Serial.print(F(
"S="));
474 # if defined(LOCAL_DEBUG)
475 Serial.print(F(
"M="));
478 # if defined(LOCAL_DEBUG)
479 Serial.println(duration);
489 void IRsend::sendRaw_P(
const uint8_t aBufferWithTicks[], uint_fast16_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz) {
490 #if !defined(__AVR__)
491 sendRaw(aBufferWithTicks, aLengthOfBuffer, aIRFrequencyKilohertz);
496 uint_fast16_t duration;
497 for (uint_fast16_t i = 0; i < aLengthOfBuffer; i++) {
498 duration = pgm_read_byte(&aBufferWithTicks[i]) * (uint_fast16_t)
MICROS_PER_TICK;
502 # if defined(LOCAL_DEBUG)
503 Serial.print(F(
"S="));
507 # if defined(LOCAL_DEBUG)
508 Serial.print(F(
"M="));
513 # if defined(LOCAL_DEBUG)
514 Serial.println(duration);
526 uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, uint16_t aZeroSpaceMicros,
527 IRRawDataType *aDecodedRawDataArray, uint16_t aNumberOfBits,
bool aMSBFirst,
bool aSendStopBit,
528 uint16_t aRepeatPeriodMillis, int_fast8_t aNumberOfRepeats) {
536 aZeroMarkMicros, aZeroSpaceMicros, aDecodedRawDataArray, aNumberOfBits, tFlags, aRepeatPeriodMillis,
aNumberOfRepeats);
540 IRRawDataType *aDecodedRawDataArray, uint16_t aNumberOfBits, uint8_t aFlags, uint16_t aRepeatPeriodMillis,
541 int_fast8_t aNumberOfRepeats) {
545 aDistanceWidthTimingInfo->
ZeroSpaceMicros, aDecodedRawDataArray, aNumberOfBits, aFlags, aRepeatPeriodMillis,
550 uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, uint16_t aZeroSpaceMicros,
551 IRRawDataType *aDecodedRawDataArray, uint16_t aNumberOfBits, uint8_t aFlags, uint16_t aRepeatPeriodMillis,
552 int_fast8_t aNumberOfRepeats) {
560 #if defined(LOCAL_DEBUG)
562 Serial.print(F(
"Data[0]=0x"));
563 Serial.print(aDecodedRawDataArray[0], HEX);
564 if (tNumberOf32Or64BitChunks > 1) {
565 Serial.print(F(
" Data[1]=0x"));
566 Serial.print(aDecodedRawDataArray[1], HEX);
568 Serial.print(F(
" #="));
569 Serial.println(aNumberOfBits);
573 while (tNumberOfCommands > 0) {
574 unsigned long tStartOfFrameMillis = millis();
577 mark(aHeaderMarkMicros);
578 space(aHeaderSpaceMicros);
580 for (uint_fast8_t i = 0; i < tNumberOf32Or64BitChunks; ++i) {
581 uint8_t tNumberOfBitsForOneSend;
585 if (i == (tNumberOf32Or64BitChunks - 1)) {
587 tNumberOfBitsForOneSend = aNumberOfBits;
596 tNumberOfBitsForOneSend, tFlags);
602 if (tNumberOfCommands > 0) {
606 auto tFrameDurationMillis = millis() - tStartOfFrameMillis;
607 if (aRepeatPeriodMillis > tFrameDurationMillis) {
608 delay(aRepeatPeriodMillis - tFrameDurationMillis);
621 IRRawDataType *aDecodedRawDataArray, uint16_t aNumberOfBits, int_fast8_t aNumberOfRepeats) {
635 #if defined(LOCAL_DEBUG)
637 Serial.print(F(
"Data[0]=0x"));
638 Serial.print(aDecodedRawDataArray[0], HEX);
639 if (tNumberOf32Or64BitChunks > 1) {
640 Serial.print(F(
" Data[1]=0x"));
641 Serial.print(aDecodedRawDataArray[1], HEX);
643 Serial.print(F(
" #="));
644 Serial.println(aNumberOfBits);
649 while (tNumberOfCommands > 0) {
650 auto tStartOfFrameMillis = millis();
651 auto tNumberOfBits = aNumberOfBits;
656 uint8_t tOriginalFlags = aProtocolConstants->
Flags;
658 for (uint_fast8_t i = 0; i < tNumberOf32Or64BitChunks; ++i) {
659 uint8_t tNumberOfBitsForOneSend;
662 if (i == (tNumberOf32Or64BitChunks - 1)) {
664 tNumberOfBitsForOneSend = tNumberOfBits;
665 tFlags = tOriginalFlags;
682 if (tNumberOfCommands > 0) {
686 auto tFrameDurationMillis = millis() - tStartOfFrameMillis;
703 uint_fast8_t aNumberOfBits, int_fast8_t aNumberOfRepeats) {
705 #if defined(LOCAL_DEBUG)
706 Serial.print(F(
"Data=0x"));
707 Serial.print(aData, HEX);
708 Serial.print(F(
" #="));
709 Serial.println(aNumberOfBits);
730 while (tNumberOfCommands > 0) {
731 unsigned long tStartOfFrameMillis = millis();
747 if (tNumberOfCommands > 0) {
748 auto tCurrentFrameDurationMillis = millis() - tStartOfFrameMillis;
769 uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, uint16_t aZeroSpaceMicros,
IRRawDataType aData,
770 uint_fast8_t aNumberOfBits,
bool aMSBFirst,
bool aSendStopBit, uint16_t aRepeatPeriodMillis, int_fast8_t aNumberOfRepeats,
771 void (*aSpecialSendRepeatFunction)()) {
777 sendPulseDistanceWidth(aFrequencyKHz, aHeaderMarkMicros, aHeaderSpaceMicros, aOneMarkMicros, aOneSpaceMicros, aZeroMarkMicros,
778 aZeroSpaceMicros, aData, aNumberOfBits, tFlags, aRepeatPeriodMillis,
aNumberOfRepeats, aSpecialSendRepeatFunction);
782 uint16_t aOneMarkMicros, uint16_t aOneSpaceMicros, uint16_t aZeroMarkMicros, uint16_t aZeroSpaceMicros,
IRRawDataType aData,
783 uint_fast8_t aNumberOfBits, uint8_t aFlags, uint16_t aRepeatPeriodMillis, int_fast8_t aNumberOfRepeats,
784 void (*aSpecialSendRepeatFunction)()) {
787 if (aSpecialSendRepeatFunction != NULL) {
788 aSpecialSendRepeatFunction();
799 while (tNumberOfCommands > 0) {
800 unsigned long tStartOfFrameMillis = millis();
802 if (tNumberOfCommands < ((uint_fast8_t)
aNumberOfRepeats + 1) && aSpecialSendRepeatFunction != NULL) {
804 aSpecialSendRepeatFunction();
807 mark(aHeaderMarkMicros);
808 space(aHeaderSpaceMicros);
815 if (tNumberOfCommands > 0) {
819 auto tFrameDurationMillis = millis() - tStartOfFrameMillis;
820 if (aRepeatPeriodMillis > tFrameDurationMillis) {
821 delay(aRepeatPeriodMillis - tFrameDurationMillis);
833 uint_fast8_t aNumberOfBits) {
845 uint16_t aZeroSpaceMicros,
IRRawDataType aData, uint_fast8_t aNumberOfBits,
bool aMSBFirst,
bool aSendStopBit) {
854 uint16_t aZeroSpaceMicros,
IRRawDataType aData, uint_fast8_t aNumberOfBits, uint8_t aFlags) {
856 #if defined(LOCAL_DEBUG)
857 Serial.print(aData, HEX);
859 Serial.println(aNumberOfBits);
865 for (uint_fast8_t i = aNumberOfBits; i > 0; i--) {
867 #if defined(LOCAL_TRACE)
870 mark(aOneMarkMicros);
871 space(aOneSpaceMicros);
873 #if defined(LOCAL_TRACE)
876 mark(aZeroMarkMicros);
877 space(aZeroSpaceMicros);
891 #if defined(LOCAL_TRACE)
894 mark(aZeroMarkMicros);
896 #if defined(LOCAL_TRACE)
914 #if defined(LOCAL_TRACE)
920 uint32_t tMask = 1UL << aNumberOfBits;
921 uint_fast8_t tLastBitValue = 1;
922 bool tNextBitIsOne = 1;
923 for (uint_fast8_t i = aNumberOfBits + 1; i > 0; i--) {
924 bool tCurrentBitIsOne = tNextBitIsOne;
926 tNextBitIsOne = ((aData & tMask) != 0) || (i == 1);
927 if (tCurrentBitIsOne) {
928 #if defined(LOCAL_TRACE)
931 space(aBiphaseTimeUnit);
933 mark(aBiphaseTimeUnit);
936 mark(2 * aBiphaseTimeUnit);
941 #if defined(LOCAL_TRACE)
944 if (!tLastBitValue) {
945 mark(aBiphaseTimeUnit);
947 space(aBiphaseTimeUnit);
971 #if defined(SEND_PWM_BY_TIMER) || defined(USE_NO_SEND_PWM)
972 # if !defined(NO_LED_FEEDBACK_CODE)
979 #if defined(SEND_PWM_BY_TIMER)
988 #elif defined(USE_NO_SEND_PWM)
992 # if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) && !defined(OUTPUT_OPEN_DRAIN)
1000 # if !defined(NO_LED_FEEDBACK_CODE)
1007 #else // defined(SEND_PWM_BY_TIMER)
1011 unsigned long tStartMicros = micros();
1012 unsigned long tNextPeriodEnding = tStartMicros;
1013 unsigned long tMicros;
1014 # if !defined(NO_LED_FEEDBACK_CODE)
1015 bool FeedbackLedIsActive =
false;
1024 # if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN)
1025 # if defined(OUTPUT_OPEN_DRAIN)
1040 # if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) && !defined(OUTPUT_OPEN_DRAIN)
1041 # if defined(OUTPUT_OPEN_DRAIN)
1056 # if !defined(NO_LED_FEEDBACK_CODE)
1060 if (!FeedbackLedIsActive) {
1061 FeedbackLedIsActive =
true;
1075 #if defined(__AVR__) // micros() for STM sometimes give decreasing values if interrupts are disabled. See https://github.com/stm32duino/Arduino_Core_STM32/issues/1680
1079 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
1089 #if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
1096 uint16_t tDeltaMicros = tMicros - tStartMicros;
1097 #if defined(__AVR__)
1100 # if !defined(NO_LED_FEEDBACK_CODE)
1101 if (tDeltaMicros >= aMarkMicros - (30 + (112 / CLOCKS_PER_MICRO))) {
1108 if (tDeltaMicros >= aMarkMicros - (112 / CLOCKS_PER_MICRO)) {
1110 if (tDeltaMicros >= aMarkMicros) {
1111 # if !defined(NO_LED_FEEDBACK_CODE)
1117 #if defined(__AVR__)
1122 }
while (tMicros < tNextPeriodEnding);
1133 #if defined(SEND_PWM_BY_TIMER)
1135 #elif defined(USE_NO_SEND_PWM)
1136 # if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) && !defined(OUTPUT_OPEN_DRAIN)
1143 # if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN)
1144 # if defined(OUTPUT_OPEN_DRAIN)
1154 #if !defined(NO_LED_FEEDBACK_CODE)
1174 #if defined(ESP32) || defined(ESP8266)
1179 if (aMicroseconds > 16383) {
1180 delay(aMicroseconds / 1000UL);
1182 delayMicroseconds(
static_cast<uint16_t
>(aMicroseconds % 1000UL));
1184 delayMicroseconds(aMicroseconds);
1188 # if defined(__AVR__)
1189 unsigned long start = micros() - (64 / clockCyclesPerMicrosecond());
1191 unsigned long start = micros();
1194 while (micros() - start < aMicroseconds) {
1206 #if defined(SEND_PWM_BY_TIMER)
1209 #elif defined(USE_NO_SEND_PWM)
1210 (void) aFrequencyKHz;
1214 # if defined(IR_SEND_PIN)
1220 #endif // defined(SEND_PWM_BY_TIMER)
1222 #if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) && defined(OUTPUT_OPEN_DRAIN) // the mode INPUT for mimicking open drain is set at IRLedOff()
1223 # if defined(IR_SEND_PIN)
1232 # if defined(__AVR__) || !defined(SEND_PWM_BY_TIMER)
1233 # if defined(IR_SEND_PIN)
1239 #endif // defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN)
1242 #if defined(SEND_PWM_BY_TIMER)
1244 void IRsend::enableHighFrequencyIROut(uint_fast16_t aFrequencyKHz) {
1248 # if defined(__AVR__)
1249 # if defined(IR_SEND_PIN)
1263 #if defined(_IR_MEASURE_TIMING)
1264 #undef _IR_MEASURE_TIMING
1266 #if defined(LOCAL_TRACE)
1269 #if defined(LOCAL_DEBUG)
1272 #endif // _IR_SEND_HPP