IRremote
IRSend.hpp
Go to the documentation of this file.
1 /*
2  * IRSend.hpp
3  *
4  * Contains common functions for sending
5  *
6  * This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
7  *
8  ************************************************************************************
9  * MIT License
10  *
11  * Copyright (c) 2009-2022 Ken Shirriff, Rafi Khan, Armin Joachimsmeyer
12  *
13  * Permission is hereby granted, free of charge, to any person obtaining a copy
14  * of this software and associated documentation files (the "Software"), to deal
15  * in the Software without restriction, including without limitation the rights
16  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17  * copies of the Software, and to permit persons to whom the Software is furnished
18  * to do so, subject to the following conditions:
19  *
20  * The above copyright notice and this permission notice shall be included in all
21  * copies or substantial portions of the Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
24  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
25  * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
27  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
28  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29  *
30  ************************************************************************************
31  */
32 #ifndef _IR_SEND_HPP
33 #define _IR_SEND_HPP
34 
35 #if defined(DEBUG) && !defined(LOCAL_DEBUG)
36 #define LOCAL_DEBUG
37 #else
38 //#define LOCAL_DEBUG // This enables debug output only for this file
39 #endif
40 
41 #if defined(TRACE) && !defined(LOCAL_TRACE)
42 #define LOCAL_TRACE
43 #else
44 //#define LOCAL_TRACE // This enables debug output only for this file
45 #endif
46 
47 /*
48  * This improves readability of code by avoiding a lot of #if defined clauses
49  */
50 #if defined(IR_SEND_PIN)
51 #define sendPin IR_SEND_PIN
52 #endif
53 
58 // The sender instance
60 
61 IRsend::IRsend() { // @suppress("Class members should be properly initialized")
62 #if !defined(IR_SEND_PIN)
63  sendPin = 0;
64 #endif
65 
66 #if !defined(NO_LED_FEEDBACK_CODE)
68 #endif
69 }
70 
71 #if defined(IR_SEND_PIN)
72 
76 void IRsend::begin(){
77 # if !defined(NO_LED_FEEDBACK_CODE)
79 # endif
80 }
81 
87 void IRsend::begin(bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin) {
88 #if !defined(NO_LED_FEEDBACK_CODE)
89  bool tEnableLEDFeedback = DO_NOT_ENABLE_LED_FEEDBACK;
90  if(aEnableLEDFeedback) {
91  tEnableLEDFeedback = LED_FEEDBACK_ENABLED_FOR_SEND;
92  }
93  setLEDFeedback(aFeedbackLEDPin, tEnableLEDFeedback);
94 #else
95  (void) aEnableLEDFeedback;
96  (void) aFeedbackLEDPin;
97 #endif
98 }
99 
100 #else // defined(IR_SEND_PIN)
101 IRsend::IRsend(uint_fast8_t aSendPin) { // @suppress("Class members should be properly initialized")
102  sendPin = aSendPin;
103 # if !defined(NO_LED_FEEDBACK_CODE)
105 # endif
106 }
107 
112 void IRsend::begin(uint_fast8_t aSendPin) {
113  sendPin = aSendPin;
114 # if !defined(NO_LED_FEEDBACK_CODE)
116 # endif
117 }
118 
119 void IRsend::setSendPin(uint_fast8_t aSendPin) {
120  sendPin = aSendPin;
121 }
122 
129 void IRsend::begin(uint_fast8_t aSendPin, bool aEnableLEDFeedback, uint_fast8_t aFeedbackLEDPin) {
130 #if defined(IR_SEND_PIN)
131  (void) aSendPin; // for backwards compatibility
132 #else
133  sendPin = aSendPin;
134 #endif
135 
136 #if !defined(NO_LED_FEEDBACK_CODE)
137  bool tEnableLEDFeedback = DO_NOT_ENABLE_LED_FEEDBACK;
138  if (aEnableLEDFeedback) {
139  tEnableLEDFeedback = LED_FEEDBACK_ENABLED_FOR_SEND;
140  }
141  setLEDFeedback(aFeedbackLEDPin, tEnableLEDFeedback);
142 #else
143  (void) aEnableLEDFeedback;
144  (void) aFeedbackLEDPin;
145 #endif
146 }
147 #endif // defined(IR_SEND_PIN)
148 
155 size_t IRsend::write(IRData *aIRSendData, int_fast8_t aNumberOfRepeats) {
156 
157  auto tProtocol = aIRSendData->protocol;
158  auto tAddress = aIRSendData->address;
159  auto tCommand = aIRSendData->command;
160  bool tIsRepeat = (aIRSendData->flags & IRDATA_FLAGS_IS_REPEAT);
161  if (tIsRepeat) {
162  aNumberOfRepeats = -1; // if aNumberOfRepeats < 0 then only a special repeat frame will be sent
163  }
164 // switch (tProtocol) { // 26 bytes bigger than if, else if, else
165 // case NEC:
166 // sendNEC(tAddress, tCommand, aNumberOfRepeats, tSendRepeat);
167 // break;
168 // case SAMSUNG:
169 // sendSamsung(tAddress, tCommand, aNumberOfRepeats);
170 // break;
171 // case SONY:
172 // sendSony(tAddress, tCommand, aNumberOfRepeats, aIRSendData->numberOfBits);
173 // break;
174 // case PANASONIC:
175 // sendPanasonic(tAddress, tCommand, aNumberOfRepeats);
176 // break;
177 // case DENON:
178 // sendDenon(tAddress, tCommand, aNumberOfRepeats);
179 // break;
180 // case SHARP:
181 // sendSharp(tAddress, tCommand, aNumberOfRepeats);
182 // break;
183 // case JVC:
184 // sendJVC((uint8_t) tAddress, (uint8_t) tCommand, aNumberOfRepeats); // casts are required to specify the right function
185 // break;
186 // case RC5:
187 // sendRC5(tAddress, tCommand, aNumberOfRepeats, !tSendRepeat); // No toggle for repeats
188 // break;
189 // case RC6:
190 // // No toggle for repeats// sendRC6(tAddress, tCommand, aNumberOfRepeats, !tSendRepeat); // No toggle for repeats
191 // break;
192 // default:
193 // break;
194 // }
195 
196  /*
197  * Order of protocols is in guessed relevance :-)
198  */
199  if (tProtocol == NEC) {
200  sendNEC(tAddress, tCommand, aNumberOfRepeats);
201 
202  } else if (tProtocol == SAMSUNG) {
203  sendSamsung(tAddress, tCommand, aNumberOfRepeats);
204 
205  } else if (tProtocol == SAMSUNG48) {
206  sendSamsung48(tAddress, tCommand, aNumberOfRepeats);
207 
208  } else if (tProtocol == SAMSUNG_LG) {
209  sendSamsungLG(tAddress, tCommand, aNumberOfRepeats);
210 
211  } else if (tProtocol == SONY) {
212  sendSony(tAddress, tCommand, aNumberOfRepeats, aIRSendData->numberOfBits);
213 
214  } else if (tProtocol == PANASONIC) {
215  sendPanasonic(tAddress, tCommand, aNumberOfRepeats);
216 
217  } else if (tProtocol == DENON) {
218  sendDenon(tAddress, tCommand, aNumberOfRepeats);
219 
220  } else if (tProtocol == SHARP) {
221  sendSharp(tAddress, tCommand, aNumberOfRepeats);
222 
223  } else if (tProtocol == LG) {
224  sendLG(tAddress, tCommand, aNumberOfRepeats);
225 
226  } else if (tProtocol == JVC) {
227  sendJVC((uint8_t) tAddress, (uint8_t) tCommand, aNumberOfRepeats); // casts are required to specify the right function
228 
229  } else if (tProtocol == RC5) {
230  sendRC5(tAddress, tCommand, aNumberOfRepeats, !tIsRepeat); // No toggle for repeats
231 
232  } else if (tProtocol == RC6) {
233  sendRC6(tAddress, tCommand, aNumberOfRepeats, !tIsRepeat); // No toggle for repeats
234 
235  } else if (tProtocol == KASEIKYO_JVC) {
236  sendKaseikyo_JVC(tAddress, tCommand, aNumberOfRepeats);
237 
238  } else if (tProtocol == KASEIKYO_DENON) {
239  sendKaseikyo_Denon(tAddress, tCommand, aNumberOfRepeats);
240 
241  } else if (tProtocol == KASEIKYO_SHARP) {
242  sendKaseikyo_Sharp(tAddress, tCommand, aNumberOfRepeats);
243 
244  } else if (tProtocol == KASEIKYO_MITSUBISHI) {
245  sendKaseikyo_Mitsubishi(tAddress, tCommand, aNumberOfRepeats);
246 
247  } else if (tProtocol == NEC2) {
248  sendNEC2(tAddress, tCommand, aNumberOfRepeats);
249 
250  } else if (tProtocol == ONKYO) {
251  sendOnkyo(tAddress, tCommand, aNumberOfRepeats);
252 
253  } else if (tProtocol == APPLE) {
254  sendApple(tAddress, tCommand, aNumberOfRepeats);
255 
256 #if !defined(EXCLUDE_EXOTIC_PROTOCOLS)
257  } else if (tProtocol == BOSEWAVE) {
258  sendBoseWave(tCommand, aNumberOfRepeats);
259 
260  } else if (tProtocol == MAGIQUEST) {
261  // we have a 32 bit ID/address
262  sendMagiQuest(aIRSendData->decodedRawData, tCommand);
263 
264  } else if (tProtocol == LEGO_PF) {
265  sendLegoPowerFunctions(tAddress, tCommand, tCommand >> 4, tIsRepeat); // send 5 autorepeats
266 #endif
267 
268  } else {
269  return 0; // Not supported by write. E.g for BANG_OLUFSEN
270  }
271  return 1;
272 }
273 
278 void IRsend::sendRaw(const uint16_t aBufferWithMicroseconds[], uint_fast16_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz) {
279 // Set IR carrier frequency
280  enableIROut(aIRFrequencyKilohertz);
281 
282  /*
283  * Raw data starts with a mark.
284  */
285  for (uint_fast16_t i = 0; i < aLengthOfBuffer; i++) {
286  if (i & 1) {
287  // Odd
288  space(aBufferWithMicroseconds[i]);
289  } else {
290  mark(aBufferWithMicroseconds[i]);
291  }
292  }
293 
294 #if !defined(DISABLE_CODE_FOR_RECEIVER)
296 #endif
297 }
298 
303 void IRsend::sendRaw(const uint8_t aBufferWithTicks[], uint_fast16_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz) {
304 // Set IR carrier frequency
305  enableIROut(aIRFrequencyKilohertz);
306 
307  for (uint_fast16_t i = 0; i < aLengthOfBuffer; i++) {
308  if (i & 1) {
309  // Odd
310  space(aBufferWithTicks[i] * MICROS_PER_TICK);
311  } else {
312  mark(aBufferWithTicks[i] * MICROS_PER_TICK);
313  }
314  }
315  IRLedOff(); // Always end with the LED off
316 #if !defined(DISABLE_CODE_FOR_RECEIVER)
318 #endif
319 }
320 
325 void IRsend::sendRaw_P(const uint16_t aBufferWithMicroseconds[], uint_fast16_t aLengthOfBuffer,
326  uint_fast8_t aIRFrequencyKilohertz) {
327 #if !defined(__AVR__)
328  sendRaw(aBufferWithMicroseconds, aLengthOfBuffer, aIRFrequencyKilohertz); // Let the function work for non AVR platforms
329 #else
330 // Set IR carrier frequency
331  enableIROut(aIRFrequencyKilohertz);
332  /*
333  * Raw data starts with a mark
334  */
335  for (uint_fast16_t i = 0; i < aLengthOfBuffer; i++) {
336  unsigned int duration = pgm_read_word(&aBufferWithMicroseconds[i]);
337  if (i & 1) {
338  // Odd
339  space(duration);
340  } else {
341  mark(duration);
342  }
343  }
344 # if !defined(DISABLE_CODE_FOR_RECEIVER)
346 # endif
347 #endif
348 }
349 
354 void IRsend::sendRaw_P(const uint8_t aBufferWithTicks[], uint_fast16_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz) {
355 #if !defined(__AVR__)
356  sendRaw(aBufferWithTicks, aLengthOfBuffer, aIRFrequencyKilohertz); // Let the function work for non AVR platforms
357 #else
358 // Set IR carrier frequency
359  enableIROut(aIRFrequencyKilohertz);
360 
361  for (uint_fast16_t i = 0; i < aLengthOfBuffer; i++) {
362  unsigned int duration = pgm_read_byte(&aBufferWithTicks[i]) * (unsigned int) MICROS_PER_TICK;
363  if (i & 1) {
364  // Odd
365  space(duration);
366  } else {
367  mark(duration);
368  }
369  }
370  IRLedOff(); // Always end with the LED off
371 # if !defined(DISABLE_CODE_FOR_RECEIVER)
373 # endif
374 #endif
375 }
376 
383 void IRsend::sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, unsigned int aHeaderMarkMicros,
384  unsigned int aHeaderSpaceMicros, unsigned int aOneMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroMarkMicros,
385  unsigned int aZeroSpaceMicros, IRRawDataType *aDecodedRawDataArray, unsigned int aNumberOfBits, bool aMSBFirst,
386  bool aSendStopBit, unsigned int aRepeatPeriodMillis, int_fast8_t aNumberOfRepeats) {
387 
388  // Set IR carrier frequency
389  enableIROut(aFrequencyKHz);
390 
391  uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1;
392  uint_fast8_t tNumberOf32BitChunks = ((aNumberOfBits - 1) / 32) + 1;
393 
394 #if defined(LOCAL_DEBUG)
395  // fist data
396  Serial.print(F("Data[0]=0x"));
397  Serial.print(aDecodedRawDataArray[0], HEX);
398  if (tNumberOf32BitChunks > 1) {
399  Serial.print(F(" Data[1]=0x"));
400  Serial.print(aDecodedRawDataArray[1], HEX);
401  }
402  Serial.print(F(" #="));
403  Serial.println(aNumberOfBits);
404  Serial.flush();
405 #endif
406 
407  while (tNumberOfCommands > 0) {
408  unsigned long tStartOfFrameMillis = millis();
409 
410  // Header
411  mark(aHeaderMarkMicros);
412  space(aHeaderSpaceMicros);
413 
414  for (uint_fast8_t i = 0; i < tNumberOf32BitChunks; ++i) {
415  uint8_t tNumberOfBitsForOneSend;
416  if (aNumberOfBits > 32) {
417  tNumberOfBitsForOneSend = 32;
418  } else {
419  tNumberOfBitsForOneSend = aNumberOfBits;
420  }
421 
422  // Manage stop bit
423  bool tSendStopBit;
424  if (i == (tNumberOf32BitChunks - 1)) {
425  // End of data
426  tSendStopBit = aSendStopBit;
427  } else {
428  // intermediate data
429  tSendStopBit = false;
430  }
431 
432  sendPulseDistanceWidthData(aOneMarkMicros, aOneSpaceMicros, aZeroMarkMicros, aZeroSpaceMicros, aDecodedRawDataArray[i],
433  tNumberOfBitsForOneSend, aMSBFirst, tSendStopBit);
434  aNumberOfBits -= 32;
435  }
436 
437  tNumberOfCommands--;
438  // skip last delay!
439  if (tNumberOfCommands > 0) {
440  /*
441  * Check and fallback for wrong RepeatPeriodMillis parameter. I.e the repeat period must be greater than each frame duration.
442  */
443  auto tFrameDurationMillis = millis() - tStartOfFrameMillis;
444  if (aRepeatPeriodMillis > tFrameDurationMillis) {
445  delay(aRepeatPeriodMillis - tFrameDurationMillis);
446  }
447  }
448  }
449 #if !defined(DISABLE_CODE_FOR_RECEIVER)
451 #endif
452 }
453 
461  IRRawDataType *aDecodedRawDataArray, unsigned int aNumberOfBits, int_fast8_t aNumberOfRepeats) {
462 
463  // Set IR carrier frequency
464  enableIROut(aProtocolConstants->FrequencyKHz);
465 
466  uint_fast8_t tNumberOf32BitChunks = ((aNumberOfBits - 1) / 32) + 1;
467 
468 #if defined(LOCAL_DEBUG)
469  // fist data
470  Serial.print(F("Data[0]=0x"));
471  Serial.print(aDecodedRawDataArray[0], HEX);
472  if (tNumberOf32BitChunks > 1) {
473  Serial.print(F(" Data[1]=0x"));
474  Serial.print(aDecodedRawDataArray[1], HEX);
475  }
476  Serial.print(F(" #="));
477  Serial.println(aNumberOfBits);
478  Serial.flush();
479 #endif
480 
481  uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1;
482  while (tNumberOfCommands > 0) {
483  auto tStartOfFrameMillis = millis();
484  auto tNumberOfBits = aNumberOfBits; // refresh value for repeats
485 
486  // Header
487  mark(aProtocolConstants->HeaderMarkMicros);
488  space(aProtocolConstants->HeaderSpaceMicros);
489  bool tHasStopBit = aProtocolConstants->hasStopBit;
490 
491  for (uint_fast8_t i = 0; i < tNumberOf32BitChunks; ++i) {
492  uint8_t tNumberOfBitsForOneSend;
493 
494  if (i == (tNumberOf32BitChunks - 1)) {
495  // End of data
496  tNumberOfBitsForOneSend = tNumberOfBits;
497  aProtocolConstants->hasStopBit = tHasStopBit;
498  } else {
499  // intermediate data
500  tNumberOfBitsForOneSend = 32;
501  aProtocolConstants->hasStopBit = false;
502  }
503  sendPulseDistanceWidthData(aProtocolConstants, aDecodedRawDataArray[i], tNumberOfBitsForOneSend);
504  tNumberOfBits -= 32;
505  }
506 
507  tNumberOfCommands--;
508  // skip last delay!
509  if (tNumberOfCommands > 0) {
510  /*
511  * Check and fallback for wrong RepeatPeriodMillis parameter. I.e the repeat period must be greater than each frame duration.
512  */
513  auto tFrameDurationMillis = millis() - tStartOfFrameMillis;
514  if (aProtocolConstants->RepeatPeriodMillis > tFrameDurationMillis) {
515  delay(aProtocolConstants->RepeatPeriodMillis - tFrameDurationMillis);
516  }
517  }
518  }
519 #if !defined(DISABLE_CODE_FOR_RECEIVER)
521 #endif
522 }
523 
533  uint_fast8_t aNumberOfBits, int_fast8_t aNumberOfRepeats) {
534 
535  if (aNumberOfRepeats < 0) {
536  if (aProtocolConstants->SpecialSendRepeatFunction != NULL) {
537  aProtocolConstants->SpecialSendRepeatFunction();
538  return;
539  } else {
540  aNumberOfRepeats = 0; // send a plain frame as repeat
541  }
542  }
543 
544  // Set IR carrier frequency
545  enableIROut(aProtocolConstants->FrequencyKHz);
546 
547  uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1;
548  while (tNumberOfCommands > 0) {
549  unsigned long tStartOfFrameMillis = millis();
550 
551  if (tNumberOfCommands < ((uint_fast8_t) aNumberOfRepeats + 1) && aProtocolConstants->SpecialSendRepeatFunction != NULL) {
552  // send special repeat
553  aProtocolConstants->SpecialSendRepeatFunction();
554  } else {
555  /*
556  * Send Header and regular frame
557  */
558  mark(aProtocolConstants->HeaderMarkMicros);
559  space(aProtocolConstants->HeaderSpaceMicros);
560  sendPulseDistanceWidthData(aProtocolConstants, aData, aNumberOfBits);
561  }
562 
563  tNumberOfCommands--;
564  // skip last delay!
565  if (tNumberOfCommands > 0) {
566  /*
567  * Check and fallback for wrong RepeatPeriodMillis parameter. I.e the repeat period must be greater than each frame duration.
568  */
569  auto tFrameDurationMillis = millis() - tStartOfFrameMillis;
570  if (aProtocolConstants->RepeatPeriodMillis > tFrameDurationMillis) {
571  delay(aProtocolConstants->RepeatPeriodMillis - tFrameDurationMillis);
572  }
573  }
574  }
575 #if !defined(DISABLE_CODE_FOR_RECEIVER)
577 #endif
578 }
579 
589 void IRsend::sendPulseDistanceWidth(uint_fast8_t aFrequencyKHz, unsigned int aHeaderMarkMicros, unsigned int aHeaderSpaceMicros,
590  unsigned int aOneMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroMarkMicros, unsigned int aZeroSpaceMicros,
591  IRRawDataType aData, uint_fast8_t aNumberOfBits, bool aMSBFirst, bool aSendStopBit, unsigned int aRepeatPeriodMillis,
592  int_fast8_t aNumberOfRepeats, void (*aSpecialSendRepeatFunction)()) {
593 
594  if (aNumberOfRepeats < 0) {
595  if (aSpecialSendRepeatFunction != NULL) {
596  aSpecialSendRepeatFunction();
597  return;
598  } else {
599  aNumberOfRepeats = 0; // send a plain frame as repeat
600  }
601  }
602 
603  // Set IR carrier frequency
604  enableIROut(aFrequencyKHz);
605 
606  uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1;
607  while (tNumberOfCommands > 0) {
608  unsigned long tStartOfFrameMillis = millis();
609 
610  if (tNumberOfCommands < ((uint_fast8_t) aNumberOfRepeats + 1) && aSpecialSendRepeatFunction != NULL) {
611  // send special repeat
612  aSpecialSendRepeatFunction();
613  } else {
614  // Header and regular frame
615  mark(aHeaderMarkMicros);
616  space(aHeaderSpaceMicros);
617  sendPulseDistanceWidthData(aOneMarkMicros, aOneSpaceMicros, aZeroMarkMicros, aZeroSpaceMicros, aData, aNumberOfBits,
618  aMSBFirst, aSendStopBit);
619  }
620 
621  tNumberOfCommands--;
622  // skip last delay!
623  if (tNumberOfCommands > 0) {
624  /*
625  * Check and fallback for wrong RepeatPeriodMillis parameter. I.e the repeat period must be greater than each frame duration.
626  */
627  auto tFrameDurationMillis = millis() - tStartOfFrameMillis;
628  if (aRepeatPeriodMillis > tFrameDurationMillis) {
629  delay(aRepeatPeriodMillis - tFrameDurationMillis);
630  }
631  }
632  }
633 #if !defined(DISABLE_CODE_FOR_RECEIVER)
635 #endif
636 }
637 
644  uint_fast8_t aNumberOfBits) {
645 
646  sendPulseDistanceWidthData(aProtocolConstants->OneMarkMicros, aProtocolConstants->OneSpaceMicros,
647  aProtocolConstants->ZeroMarkMicros, aProtocolConstants->ZeroSpaceMicros, aData, aNumberOfBits,
648  aProtocolConstants->isMSBFirst, aProtocolConstants->hasStopBit);
649 }
650 
655 void IRsend::sendPulseDistanceWidthData(unsigned int aOneMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroMarkMicros,
656  unsigned int aZeroSpaceMicros, IRRawDataType aData, uint_fast8_t aNumberOfBits, bool aMSBFirst, bool aSendStopBit) {
657 
658 #if defined(LOCAL_DEBUG)
659  // Even printing this short messages (at 115200) disturbs the send timing :-(
660 // Serial.print(aData, HEX);
661 // Serial.print('|');
662 // Serial.println(aNumberOfBits);
663 #endif
664 
665  // For MSBFirst, send data from MSB to LSB until mask bit is shifted out
666  IRRawDataType tMask = 1ULL << (aNumberOfBits - 1);
667  for (uint_fast8_t i = aNumberOfBits; i > 0; i--) {
668  if ((aMSBFirst && (aData & tMask)) || (!aMSBFirst && (aData & 1))) {
669 #if defined(LOCAL_TRACE)
670  Serial.print('1');
671 #endif
672  mark(aOneMarkMicros);
673  space(aOneSpaceMicros);
674  } else {
675 #if defined(LOCAL_TRACE)
676  Serial.print('0');
677 #endif
678  mark(aZeroMarkMicros);
679  space(aZeroSpaceMicros);
680  }
681  if (aMSBFirst) {
682  tMask >>= 1;
683  } else {
684  aData >>= 1;
685  }
686  }
687  if (aSendStopBit) {
688 #if defined(LOCAL_TRACE)
689  Serial.print('S');
690 #endif
691  mark(aZeroMarkMicros); // Use aZeroMarkMicros for stop bits. This seems to be correct for all protocols :-)
692  }
693 #if defined(LOCAL_TRACE)
694  Serial.println();
695 #endif
696 }
697 
706 void IRsend::sendBiphaseData(unsigned int aBiphaseTimeUnit, uint32_t aData, uint_fast8_t aNumberOfBits) {
707 
708  IR_TRACE_PRINT(F("0x"));
709  IR_TRACE_PRINT(aData, HEX);
710 
711 #if defined(LOCAL_TRACE)
712  Serial.print('S');
713 #endif
714 
715 // Data - Biphase code MSB first
716 // prepare for start with sending the start bit, which is 1
717  uint32_t tMask = 1UL << aNumberOfBits; // mask is now set for the virtual start bit
718  uint_fast8_t tLastBitValue = 1; // Start bit is a 1
719  bool tNextBitIsOne = 1; // Start bit is a 1
720  for (uint_fast8_t i = aNumberOfBits + 1; i > 0; i--) {
721  bool tCurrentBitIsOne = tNextBitIsOne;
722  tMask >>= 1;
723  tNextBitIsOne = ((aData & tMask) != 0) || (i == 1); // true for last bit to avoid extension of mark
724  if (tCurrentBitIsOne) {
725 #if defined(LOCAL_TRACE)
726  Serial.print('1');
727 #endif
728  space(aBiphaseTimeUnit);
729  if (tNextBitIsOne) {
730  mark(aBiphaseTimeUnit);
731  } else {
732  // if next bit is 0, extend the current mark in order to generate a continuous signal without short breaks
733  mark(2 * aBiphaseTimeUnit);
734  }
735  tLastBitValue = 1;
736 
737  } else {
738 #if defined(LOCAL_TRACE)
739  Serial.print('0');
740 #endif
741  if (!tLastBitValue) {
742  mark(aBiphaseTimeUnit);
743  }
744  space(aBiphaseTimeUnit);
745  tLastBitValue = 0;
746  }
747  }
748  IR_TRACE_PRINTLN(F(""));
749 }
750 
757 void IRsend::mark(unsigned int aMarkMicros) {
758 
759 #if defined(SEND_PWM_BY_TIMER) || defined(USE_NO_SEND_PWM)
760 # if !defined(NO_LED_FEEDBACK_CODE)
762  setFeedbackLED(true);
763  }
764 # endif
765 #endif
766 
767 #if defined(SEND_PWM_BY_TIMER)
768  /*
769  * Generate hardware PWM signal
770  */
771  enableSendPWMByTimer(); // Enable timer or ledcWrite() generated PWM output
772  customDelayMicroseconds(aMarkMicros);
773  IRLedOff();// disables hardware PWM and manages feedback LED
774  return;
775 
776 #elif defined(USE_NO_SEND_PWM)
777  /*
778  * Here we generate no carrier PWM, just simulate an active low receiver signal.
779  */
780 # if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) && !defined(OUTPUT_OPEN_DRAIN)
781  pinModeFast(sendPin, OUTPUT); // active state for mimicking open drain
782 # else
783  digitalWriteFast(sendPin, LOW); // Set output to active low.
784 # endif
785 
786  customDelayMicroseconds(aMarkMicros);
787  IRLedOff();
788 # if !defined(NO_LED_FEEDBACK_CODE)
790  setFeedbackLED(false);
791  }
792  return;
793 # endif
794 
795 #else // defined(SEND_PWM_BY_TIMER)
796  /*
797  * Generate PWM by bit banging
798  */
799  unsigned long tStartMicros = micros();
800  unsigned long tNextPeriodEnding = tStartMicros;
801  unsigned long tMicros;
802 # if !defined(NO_LED_FEEDBACK_CODE)
803  bool FeedbackLedIsActive = false;
804 # endif
805 
806  do {
807 // digitalToggleFast(_IR_TIMING_TEST_PIN);
808  /*
809  * Output the PWM pulse
810  */
811  noInterrupts(); // do not let interrupts extend the short on period
812 # if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN)
813 # if defined(OUTPUT_OPEN_DRAIN)
814  digitalWriteFast(sendPin, LOW); // set output with pin mode OUTPUT_OPEN_DRAIN to active low
815 # else
816  pinModeFast(sendPin, OUTPUT); // active state for mimicking open drain
817 # endif
818 # else
819  // 3.5 us from FeedbackLed on to pin setting. 5.7 us from call of mark() to pin setting incl. setting of feedback pin.
820  // 4.3 us from do{ to pin setting if sendPin is no constant
821  digitalWriteFast(sendPin, HIGH);
822 # endif
823  delayMicroseconds (periodOnTimeMicros); // this is normally implemented by a blocking wait
824 
825  /*
826  * Output the PWM pause
827  */
828 # if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) && !defined(OUTPUT_OPEN_DRAIN)
829 # if defined(OUTPUT_OPEN_DRAIN)
830  digitalWriteFast(sendPin, HIGH); // Set output with pin mode OUTPUT_OPEN_DRAIN to inactive high.
831 # else
832  pinModeFast(sendPin, INPUT); // to mimic the open drain inactive state
833 # endif
834 
835 # else
837 # endif
838  interrupts(); // Enable interrupts - to keep micros correct- for the longer off period 3.4 us until receive ISR is active (for 7 us + pop's)
839 
840 # if !defined(NO_LED_FEEDBACK_CODE)
841  /*
842  * Delayed call of setFeedbackLED() to get better timing
843  */
844  if (!FeedbackLedIsActive) {
845  FeedbackLedIsActive = true;
847  setFeedbackLED(true);
848  }
849  }
850 # endif
851  /*
852  * PWM pause timing
853  * Minimal pause duration is 4.3 us if NO_LED_FEEDBACK_CODE is defined
854  */
855  tNextPeriodEnding += periodTimeMicros;
856  do {
857  tMicros = micros(); // we have only 4 us resolution for AVR @16MHz
858  /*
859  * Exit the forever loop if aMarkMicros has reached
860  */
861  unsigned int tDeltaMicros = tMicros - tStartMicros;
862 #if defined(__AVR__)
863 // tDeltaMicros += (160 / CLOCKS_PER_MICRO); // adding this once increases program size !
864 # if !defined(NO_LED_FEEDBACK_CODE)
865  if (tDeltaMicros >= aMarkMicros - (30 + (112 / CLOCKS_PER_MICRO))) { // 30 to be constant. Using periodTimeMicros increases program size too much.
866  // reset feedback led in the last pause before end
868  setFeedbackLED(false);
869  }
870  }
871 # endif
872  // Just getting variables and check for end condition takes minimal 3.8 us
873  if (tDeltaMicros >= aMarkMicros - (112 / CLOCKS_PER_MICRO)) { // To compensate for call duration - 112 is an empirical value
874 #else
875  if (tDeltaMicros >= aMarkMicros) {
876 # if !defined(NO_LED_FEEDBACK_CODE)
878  setFeedbackLED(false);
879  }
880 # endif
881 #endif
882  return;
883  }
884  } while (tMicros < tNextPeriodEnding);
885  } while (true);
886 # endif
887 }
888 
895 #if defined(SEND_PWM_BY_TIMER)
896  disableSendPWMByTimer(); // Disable PWM output
897 #elif defined(USE_NO_SEND_PWM)
898 # if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) && !defined(OUTPUT_OPEN_DRAIN)
899  digitalWriteFast(sendPin, LOW); // prepare for all next active states.
900  pinModeFast(sendPin, INPUT);// inactive state for open drain
901 # else
902  digitalWriteFast(sendPin, HIGH); // Set output to inactive high.
903 # endif
904 #else
905 # if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN)
906 # if defined(OUTPUT_OPEN_DRAIN)
907  digitalWriteFast(sendPin, HIGH); // Set output to inactive high.
908 # else
909  pinModeFast(sendPin, INPUT); // inactive state to mimic open drain
910 # endif
911 # else
913 # endif
914 #endif
915 
916 #if !defined(NO_LED_FEEDBACK_CODE)
918  setFeedbackLED(false);
919  }
920 #endif
921 }
922 
927 void IRsend::space(unsigned int aSpaceMicros) {
928  customDelayMicroseconds(aSpaceMicros);
929 }
930 
935 void IRsend::customDelayMicroseconds(unsigned long aMicroseconds) {
936 #if defined(ESP32) || defined(ESP8266)
937  // from https://github.com/crankyoldgit/IRremoteESP8266/blob/00b27cc7ea2e7ac1e48e91740723c805a38728e0/src/IRsend.cpp#L123
938  // Invoke a delay(), where possible, to avoid triggering the WDT.
939  delay(aMicroseconds / 1000UL); // Delay for as many whole milliseconds as we can.
940  // Delay the remaining sub-millisecond.
941  delayMicroseconds(static_cast<uint16_t>(aMicroseconds % 1000UL));
942 #else
943 
944 # if defined(__AVR__)
945  unsigned long start = micros() - (64 / clockCyclesPerMicrosecond()); // - (64 / clockCyclesPerMicrosecond()) for reduced resolution and additional overhead
946 # else
947  unsigned long start = micros();
948 # endif
949 // overflow invariant comparison :-)
950  while (micros() - start < aMicroseconds) {
951  }
952 #endif
953 }
954 
961 void IRsend::enableIROut(uint_fast8_t aFrequencyKHz) {
962 #if defined(SEND_PWM_BY_TIMER)
963  timerConfigForSend(aFrequencyKHz); // must set output pin mode and disable receive interrupt if required, e.g. uses the same resource
964 
965 #elif defined(USE_NO_SEND_PWM)
966  (void) aFrequencyKHz;
967 
968 #else
969  periodTimeMicros = (1000U + (aFrequencyKHz / 2)) / aFrequencyKHz; // rounded value -> 26 for 38.46 kHz, 27 for 37.04 kHz, 25 for 40 kHz.
970 # if defined(IR_SEND_PIN)
971  periodOnTimeMicros = (((periodTimeMicros * IR_SEND_DUTY_CYCLE_PERCENT) + 50) / 100U); // +50 for rounding -> 830/100 for 30% and 16 MHz
972 # else
973 // Heuristics! We require a nanosecond correction for "slow" digitalWrite() functions
974  periodOnTimeMicros = (((periodTimeMicros * IR_SEND_DUTY_CYCLE_PERCENT) + 50 - (PULSE_CORRECTION_NANOS / 10)) / 100U); // +50 for rounding -> 530/100 for 30% and 16 MHz
975 # endif
976 #endif // defined(SEND_PWM_BY_TIMER)
977 
978 #if defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN) && defined(OUTPUT_OPEN_DRAIN) // the mode INPUT for mimicking open drain is set at IRLedOff()
979 # if defined(IR_SEND_PIN)
980  pinModeFast(IR_SEND_PIN, OUTPUT_OPEN_DRAIN);
981 # else
982  pinModeFast(sendPin, OUTPUT_OPEN_DRAIN);
983 # endif
984 #else
985 
986 // For Non AVR platforms pin mode for SEND_PWM_BY_TIMER must be handled by the timerConfigForSend() function
987 // because ESP 2.0.2 ledcWrite does not work if pin mode is set, and RP2040 requires gpio_set_function(IR_SEND_PIN, GPIO_FUNC_PWM);
988 # if defined(__AVR__) || !defined(SEND_PWM_BY_TIMER)
989 # if defined(IR_SEND_PIN)
990  pinModeFast(IR_SEND_PIN, OUTPUT);
991 # else
992  pinModeFast(sendPin, OUTPUT);
993 # endif
994 # endif
995 #endif // defined(USE_OPEN_DRAIN_OUTPUT_FOR_SEND_PIN)
996 }
997 
999  return PULSE_CORRECTION_NANOS;
1000 }
1001 
1003 #if defined(LOCAL_TRACE)
1004 #undef LOCAL_TRACE
1005 #endif
1006 #if defined(LOCAL_DEBUG)
1007 #undef LOCAL_DEBUG
1008 #endif
1009 #endif // _IR_SEND_HPP
IRData::address
uint16_t address
Decoded address, Distance protocol (tMarkTicksLong (if tMarkTicksLong == 0, then tMarkTicksShort) << ...
Definition: IRProtocol.h:117
MICROS_PER_TICK
#define MICROS_PER_TICK
microseconds per clock interrupt tick
Definition: IRremote.hpp:258
ONKYO
@ ONKYO
Definition: IRProtocol.h:51
IRsend::sendApple
void sendApple(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats)
Definition: ir_NEC.hpp:200
IRsend::sendMagiQuest
void sendMagiQuest(uint32_t aWandId, uint16_t aMagnitude)
Definition: ir_MagiQuest.hpp:115
KASEIKYO_DENON
@ KASEIKYO_DENON
Definition: IRProtocol.h:54
setFeedbackLED
void setFeedbackLED(bool aSwitchLedOn)
Flash LED while receiving or sending IR data.
Definition: IRFeedbackLED.hpp:108
JVC
@ JVC
Definition: IRProtocol.h:46
IRData::numberOfBits
uint16_t numberOfBits
Number of bits received for data (address + command + parity) - to determine protocol length if diffe...
Definition: IRProtocol.h:120
IRsend::aNumberOfRepeats
void uint8_t int_fast8_t aNumberOfRepeats
Definition: IRremoteInt.h:474
IRsend::sendPin
uint8_t sendPin
Definition: IRremoteInt.h:562
IRsend::sendKaseikyo_Sharp
void sendKaseikyo_Sharp(uint16_t aAddress, uint8_t aData, int_fast8_t aNumberOfRepeats)
Stub using Kaseikyo with SHARP_VENDOR_ID_CODE.
Definition: ir_Kaseikyo.hpp:177
KASEIKYO_SHARP
@ KASEIKYO_SHARP
Definition: IRProtocol.h:55
IRsend::setSendPin
void setSendPin(uint_fast8_t aSendPin)
Definition: IRSend.hpp:119
pinModeFast
#define pinModeFast
Definition: digitalWriteFast.h:355
IRsend::sendBoseWave
void sendBoseWave(uint8_t aCommand, int_fast8_t aNumberOfRepeats=NO_REPEATS)
Definition: ir_BoseWave.hpp:56
IRsend::sendSony
void sendSony(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, uint8_t numberOfBits=12)
Definition: ir_Sony.hpp:103
digitalWriteFast
#define digitalWriteFast
Definition: digitalWriteFast.h:323
PULSE_CORRECTION_NANOS
#define PULSE_CORRECTION_NANOS
Define to disable carrier PWM generation in software and use (restricted) hardware PWM.
Definition: IRremote.hpp:243
IRsend::mark
void mark(unsigned int aMarkMicros)
Sends an IR mark for the specified number of microseconds.
Definition: IRSend.hpp:757
SONY
@ SONY
Definition: IRProtocol.h:64
IR_SEND_PIN
#define IR_SEND_PIN
Hardware / timer dependent pin number for sending IR if SEND_PWM_BY_TIMER is defined.
Definition: IRTimer.hpp:93
KASEIKYO_JVC
@ KASEIKYO_JVC
Definition: IRProtocol.h:56
IRsend::periodTimeMicros
unsigned int periodTimeMicros
Definition: IRremoteInt.h:564
PulseDistanceWidthProtocolConstants::SpecialSendRepeatFunction
void(* SpecialSendRepeatFunction)()
Definition: IRProtocol.h:86
IRsend::sendRC6
void sendRC6(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle=true)
Assemble raw data for RC6 from parameters and toggle state and send We do not wait for the minimal tr...
Definition: ir_RC5_RC6.hpp:357
IRDATA_FLAGS_IS_REPEAT
#define IRDATA_FLAGS_IS_REPEAT
Definition: IRProtocol.h:94
IRrecv::restartAfterSend
void restartAfterSend()
Restarts receiver after send.
Definition: IRReceive.hpp:346
IRsend::customDelayMicroseconds
static void customDelayMicroseconds(unsigned long aMicroseconds)
Custom delay function that circumvents Arduino's delayMicroseconds 16 bit limit and is (mostly) not e...
Definition: IRSend.hpp:935
IRsend::sendPulseDistanceWidth
void sendPulseDistanceWidth(PulseDistanceWidthProtocolConstants *aProtocolConstants, IRRawDataType aData, uint_fast8_t aNumberOfBits, int_fast8_t aNumberOfRepeats)
Sends PulseDistance frames and repeats.
Definition: IRSend.hpp:532
IRsend::IRsend
IRsend()
Definition: IRSend.hpp:61
SAMSUNG
@ SAMSUNG
Definition: IRProtocol.h:60
BOSEWAVE
@ BOSEWAVE
Definition: IRProtocol.h:67
PulseDistanceWidthProtocolConstants::hasStopBit
bool hasStopBit
Definition: IRProtocol.h:84
IRData::decodedRawData
IRRawDataType decodedRawData
Up to 32/64 bit decoded raw data, to be used for send functions.
Definition: IRProtocol.h:122
IRsend::sendRaw_P
void sendRaw_P(const uint8_t aBufferWithTicks[], uint_fast16_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz)
New function using an 8 byte tick timing array in FLASH to save program memory Raw data starts with a...
Definition: IRSend.hpp:354
IRsend::getPulseCorrectionNanos
unsigned int getPulseCorrectionNanos()
Definition: IRSend.hpp:998
IRsend::sendBiphaseData
void sendBiphaseData(unsigned int aBiphaseTimeUnit, uint32_t aData, uint_fast8_t aNumberOfBits)
Sends Biphase data MSB first Always send start bit, do not send the trailing space of the start bit 0...
Definition: IRSend.hpp:706
IRsend
Main class for sending IR signals.
Definition: IRremoteInt.h:400
IR_TRACE_PRINT
#define IR_TRACE_PRINT(...)
Definition: IRremoteInt.h:144
MAGIQUEST
@ MAGIQUEST
Definition: IRProtocol.h:69
NEC2
@ NEC2
Definition: IRProtocol.h:50
IRsend::sendSamsung
void sendSamsung(uint16_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats)
Here we send Samsung32 If we get a command < 0x100, we send command and then ~command.
Definition: ir_Samsung.hpp:162
IRsend::sendNEC2
void sendNEC2(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats)
Definition: ir_NEC.hpp:177
IRsend::sendRaw
void sendRaw(const uint8_t aBufferWithTicks[], uint_fast16_t aLengthOfBuffer, uint_fast8_t aIRFrequencyKilohertz)
Function using an 8 byte tick timing array to save program memory Raw data starts with a Mark.
Definition: IRSend.hpp:303
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
PANASONIC
@ PANASONIC
Definition: IRProtocol.h:52
SAMSUNG_LG
@ SAMSUNG_LG
Definition: IRProtocol.h:62
IRsend::sendJVC
void sendJVC(unsigned long data, int nbits, bool repeat) __attribute__((deprecated("This old function sends MSB first! Please use sendJVC(aAddress
The JVC protocol repeats by skipping the header mark and space -> this leads to a poor repeat detecti...
Definition: ir_JVC.hpp:91
IRData
Data structure for the user application, available as decodedIRData.
Definition: IRProtocol.h:115
PulseDistanceWidthProtocolConstants::ZeroMarkMicros
unsigned int ZeroMarkMicros
Definition: IRProtocol.h:81
IRsend::sendPulseDistanceWidthFromArray
void sendPulseDistanceWidthFromArray(uint_fast8_t aFrequencyKHz, unsigned int aHeaderMarkMicros, unsigned int aHeaderSpaceMicros, unsigned int aOneMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroMarkMicros, unsigned int aZeroSpaceMicros, IRRawDataType *aDecodedRawDataArray, unsigned int aNumberOfBits, bool aMSBfirst, bool aSendStopBit, unsigned int aRepeatPeriodMillis, int_fast8_t aNumberOfRepeats)
Sends PulseDistance data from array For LSB First the LSB of array[0] is sent first then all bits unt...
Definition: IRSend.hpp:383
IRData::flags
uint8_t flags
See IRDATA_FLAGS_* definitions above.
Definition: IRProtocol.h:121
IRsend::sendSamsungLG
void sendSamsungLG(uint16_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats)
Definition: ir_Samsung.hpp:143
LED_FEEDBACK_ENABLED_FOR_SEND
#define LED_FEEDBACK_ENABLED_FOR_SEND
Definition: IRremoteInt.h:341
DO_NOT_ENABLE_LED_FEEDBACK
#define DO_NOT_ENABLE_LED_FEEDBACK
Definition: IRremoteInt.h:338
IRsend::sendSharp
void sendSharp(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats)
Definition: ir_Denon.hpp:116
IRsend::begin
void begin(uint_fast8_t aSendPin)
Initializes the send pin and enable LED feedback with board specific FEEDBACK_LED_ON() and FEEDBACK_L...
Definition: IRSend.hpp:112
IRsend::sendKaseikyo_JVC
void sendKaseikyo_JVC(uint16_t aAddress, uint8_t aData, int_fast8_t aNumberOfRepeats)
Stub using Kaseikyo with JVC_VENDOR_ID_CODE.
Definition: ir_Kaseikyo.hpp:184
PulseDistanceWidthProtocolConstants::HeaderSpaceMicros
unsigned int HeaderSpaceMicros
Definition: IRProtocol.h:78
IRData::command
uint16_t command
Decoded command, Distance protocol (tMarkTicksShort << 8) | tSpaceTicksShort.
Definition: IRProtocol.h:118
NEC
@ NEC
Definition: IRProtocol.h:49
IRsend::sendPanasonic
void sendPanasonic(uint16_t aAddress, uint8_t aData, int_fast8_t aNumberOfRepeats)
Stub using Kaseikyo with PANASONIC_VENDOR_ID_CODE.
Definition: ir_Kaseikyo.hpp:156
APPLE
@ APPLE
Definition: IRProtocol.h:44
IRsend::write
size_t write(IRData *aIRSendData, int_fast8_t aNumberOfRepeats=NO_REPEATS)
Interprets and sends a IRData structure.
Definition: IRSend.hpp:155
IRsend::sendDenon
void sendDenon(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aSendSharp=false)
Definition: ir_Denon.hpp:120
LEGO_PF
@ LEGO_PF
Definition: IRProtocol.h:68
IRRawDataType
uint32_t IRRawDataType
Definition: IRremoteInt.h:117
IR_TRACE_PRINTLN
#define IR_TRACE_PRINTLN(...)
Definition: IRremoteInt.h:145
KASEIKYO_MITSUBISHI
@ KASEIKYO_MITSUBISHI
Definition: IRProtocol.h:57
DENON
@ DENON
Definition: IRProtocol.h:45
enableSendPWMByTimer
void enableSendPWMByTimer()
Enables output of the PWM signal of the timer at the timer pin.
Definition: IRTimer.hpp:131
IrSender
IRsend IrSender
Definition: IRSend.hpp:59
PulseDistanceWidthProtocolConstants::OneMarkMicros
unsigned int OneMarkMicros
Definition: IRProtocol.h:79
IRsend::space
static void space(unsigned int aSpaceMicros)
Sends an IR space for the specified number of microseconds.
Definition: IRSend.hpp:927
IR_SEND_DUTY_CYCLE_PERCENT
#define IR_SEND_DUTY_CYCLE_PERCENT
Duty cycle in percent for sent signals.
Definition: IRremote.hpp:251
RC5
@ RC5
Definition: IRProtocol.h:58
PulseDistanceWidthProtocolConstants::HeaderMarkMicros
unsigned int HeaderMarkMicros
Definition: IRProtocol.h:77
IRsend::sendSamsung48
void sendSamsung48(uint16_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats)
Here we send Samsung48 We send 2 x (8 bit command and then ~command)
Definition: ir_Samsung.hpp:181
IRsend::sendRC5
void sendRC5(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle=true)
Definition: ir_RC5_RC6.hpp:102
FeedbackLEDControl
struct FeedbackLEDControlStruct FeedbackLEDControl
The feedback LED control instance.
Definition: IRFeedbackLED.hpp:47
disableSendPWMByTimer
void disableSendPWMByTimer()
Disables output of the PWM signal of the timer at the timer pin and set it to inactive.
Definition: IRTimer.hpp:136
IRsend::periodOnTimeMicros
unsigned int periodOnTimeMicros
Definition: IRremoteInt.h:565
IRsend::sendKaseikyo_Mitsubishi
void sendKaseikyo_Mitsubishi(uint16_t aAddress, uint8_t aData, int_fast8_t aNumberOfRepeats)
Stub using Kaseikyo with MITSUBISHI_VENDOR_ID_CODE.
Definition: ir_Kaseikyo.hpp:170
PulseDistanceWidthProtocolConstants::OneSpaceMicros
unsigned int OneSpaceMicros
Definition: IRProtocol.h:80
RC6
@ RC6
Definition: IRProtocol.h:59
IRsend::IRLedOff
void IRLedOff()
Just switch the IR sending LED off to send an IR space A space is "no output", so the PWM output is d...
Definition: IRSend.hpp:894
IRsend::sendPulseDistanceWidthData
void sendPulseDistanceWidthData(PulseDistanceWidthProtocolConstants *aProtocolConstants, IRRawDataType aData, uint_fast8_t aNumberOfBits)
Sends PulseDistance data The output always ends with a space Each additional call costs 16 bytes prog...
Definition: IRSend.hpp:643
IRsend::sendOnkyo
void sendOnkyo(uint16_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats)
Definition: ir_NEC.hpp:187
PulseDistanceWidthProtocolConstants::isMSBFirst
bool isMSBFirst
Definition: IRProtocol.h:83
PulseDistanceWidthProtocolConstants::RepeatPeriodMillis
unsigned int RepeatPeriodMillis
Definition: IRProtocol.h:85
IRsend::sendLegoPowerFunctions
void sendLegoPowerFunctions(uint8_t aChannel, uint8_t tCommand, uint8_t aMode, bool aDoSend5Times=true)
Definition: ir_Lego.hpp:96
PulseDistanceWidthProtocolConstants::ZeroSpaceMicros
unsigned int ZeroSpaceMicros
Definition: IRProtocol.h:82
USE_DEFAULT_FEEDBACK_LED_PIN
#define USE_DEFAULT_FEEDBACK_LED_PIN
Definition: IRremoteInt.h:64
IRData::protocol
decode_type_t protocol
UNKNOWN, NEC, SONY, RC5, PULSE_DISTANCE, ...
Definition: IRProtocol.h:116
timerConfigForSend
void timerConfigForSend(uint8_t aFrequencyKHz)
IF PWM should be generated not by software, but by a timer, this function sets output pin mode,...
Definition: IRTimer.hpp:125
SAMSUNG48
@ SAMSUNG48
Definition: IRProtocol.h:61
IRsend::sendLG
void sendLG(uint8_t aAddress, uint16_t aCommand, int_fast8_t aNumberOfRepeats)
LG uses the NEC repeat.
Definition: ir_LG.hpp:173
PulseDistanceWidthProtocolConstants::FrequencyKHz
uint_fast8_t FrequencyKHz
Definition: IRProtocol.h:76
LG
@ LG
Definition: IRProtocol.h:47
IrReceiver
IRrecv IrReceiver
The receiver instance.
Definition: IRReceive.hpp:59
IRsend::enableIROut
void enableIROut(uint_fast8_t aFrequencyKHz)
Enables IR output.
Definition: IRSend.hpp:961
IRsend::sendKaseikyo_Denon
void sendKaseikyo_Denon(uint16_t aAddress, uint8_t aData, int_fast8_t aNumberOfRepeats)
Stub using Kaseikyo with DENON_VENDOR_ID_CODE.
Definition: ir_Kaseikyo.hpp:163
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
IRsend::sendNEC
void sendNEC(uint16_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats)
NEC Send frame and special repeats There is NO delay after the last sent repeat!
Definition: ir_NEC.hpp:168