IRremote
ir_RC5_RC6.hpp
Go to the documentation of this file.
1 /*
2  * ir_RC5_RC6.hpp
3  *
4  * Contains functions for receiving and sending RC5, RC5X, RC6 protocols
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) 2020-2025 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_RC5_RC6_HPP
33 #define _IR_RC5_RC6_HPP
34 
35 #if defined(DEBUG)
36 #define LOCAL_DEBUG
37 #else
38 //#define LOCAL_DEBUG // This enables debug output only for this file
39 #endif
40 
44 uint8_t sLastSendToggleValue = 1; // To start first command with toggle 0
45 //uint8_t sLastReceiveToggleValue = 3; // 3 -> start value
46 
47 //==============================================================================
48 // RRRR CCCC 55555
49 // R R C 5
50 // RRRR C 5555
51 // R R C 5
52 // R R CCCC 5555
53 //==============================================================================
54 /*
55  Protocol=RC5 Address=0x11 Command=0x36 Raw-Data=0x1476 13 bits MSB first
56  + 900,- 900
57  +1800,-1750 +1800,- 850 + 900,- 850 + 900,-1750
58  + 950,- 850 + 900,- 850 +1800,-1750 + 950,- 850
59  +1800
60  Sum: 23100
61 
62  RC5X with 7.th MSB of command set
63  Protocol=RC5 Address=0x11 Command=0x76 Toggle=1 Raw-Data=0xC76 13 bits MSB first
64  +1800,-1750
65  + 850,- 900 +1800,- 850 + 950,- 850 + 900,-1750
66  + 900,- 850 + 950,- 850 +1800,-1750 + 900,- 850
67  +1800
68  Sum: 23050
69  */
70 //
71 // see: https://www.sbprojects.net/knowledge/ir/rc5.php
72 // https://en.wikipedia.org/wiki/Manchester_code
73 // https://en.wikipedia.org/wiki/RC-5
74 // https://forum.arduino.cc/t/sending-rc-5-extended-code-using-irsender/1045841/10 - Protocol Maranz Extended
75 // mark->space => 0
76 // space->mark => 1
77 // MSB first 1 start bit, 1 field bit, 1 toggle bit + 5 bit address + 6 bit command, no stop bit
78 // Field bit is 1 for RC5 and inverted 7. command bit for RC5X. That way the first 64 commands of RC5X remain compatible with the original RC5.
79 // SF TAAA AACC CCCC
80 // IR duty factor is 25%,
81 //
82 #define RC5_ADDRESS_BITS 5
83 #define RC5_COMMAND_BITS 6
84 #define RC5_COMMAND_FIELD_BIT 1
85 #define RC5_TOGGLE_BIT 1
86 
87 #define RC5_BITS (RC5_COMMAND_FIELD_BIT + RC5_TOGGLE_BIT + RC5_ADDRESS_BITS + RC5_COMMAND_BITS) // 13
88 
89 #define RC5_UNIT 889 // 32 periods of 36 kHz (888.8888)
90 
91 #define MIN_RC5_MARKS ((RC5_BITS + 1) / 2) // 7 - Divided by 2 to handle the bit sequence of 01010101 which gives one mark and space for each 2 bits
92 
93 #define RC5_DURATION (15L * RC5_UNIT) // 13335
94 #define RC5_REPEAT_PERIOD (128L * RC5_UNIT) // 113792
95 #define RC5_REPEAT_DISTANCE (RC5_REPEAT_PERIOD - RC5_DURATION) // 100 ms
96 #define RC5_MAXIMUM_REPEAT_DISTANCE (RC5_REPEAT_DISTANCE + (RC5_REPEAT_DISTANCE / 4)) // Just a guess
97 
98 /************************************
99  * Start of send and decode functions
100  ************************************/
101 
106 void IRsend::sendRC5(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle) {
107  // Set IR carrier frequency
109 
110  uint16_t tIRData = ((aAddress & 0x1F) << RC5_COMMAND_BITS);
111 
112  if (aCommand < 0x40) {
113  // Auto discovery of RC5X, set field bit to 1
114  tIRData |= 1 << (RC5_TOGGLE_BIT + RC5_ADDRESS_BITS + RC5_COMMAND_BITS);
115  } else {
116  // Mask bit 7 of command and let field bit 0
117  aCommand &= 0x3F;
118  }
119  tIRData |= aCommand;
120 
121  if (aEnableAutomaticToggle) {
122  if (sLastSendToggleValue == 0) {
124  // set toggled bit
125  tIRData |= 1 << (RC5_ADDRESS_BITS + RC5_COMMAND_BITS);
126  } else {
128  }
129  }
130 
131  uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1;
132  while (tNumberOfCommands > 0) {
133 
134  // start bit is sent by sendBiphaseData
135  sendBiphaseData(RC5_UNIT, tIRData, RC5_BITS);
136 
137  tNumberOfCommands--;
138  // skip last delay!
139  if (tNumberOfCommands > 0) {
140  // send repeated command in a fixed raster
142  }
143  }
144 }
145 
159  uint8_t tBitIndex;
160  uint32_t tDecodedRawData = 0;
161 
162  // Set Biphase decoding start values
163  initBiphaselevel(1, RC5_UNIT); // Skip gap space
164 
165  // Check we have the right amount of data (11 to 26). The +2 is for initial gap and start bit mark.
166  if (decodedIRData.rawlen < ((RC5_BITS + 1) / 2) + 2 && (RC5_BITS + 2) < decodedIRData.rawlen) {
167  // no debug output, since this check is mainly to determine the received protocol
168  IR_DEBUG_PRINT(F("RC5: "));
169  IR_DEBUG_PRINT(F("Data length="));
171  IR_DEBUG_PRINTLN(F(" is not between 9 and 15"));
172  return false;
173  }
174 
175 // Check start bit, the first space is included in the gap
176  if (getBiphaselevel() != MARK) {
177  IR_DEBUG_PRINT(F("RC5: "));
178  IR_DEBUG_PRINTLN(F("first getBiphaselevel() is not MARK"));
179  return false;
180  }
181 
182  /*
183  * Get data bits - MSB first
184  */
185  for (tBitIndex = 0; sBiphaseDecodeRawbuffOffset < decodedIRData.rawlen; tBitIndex++) {
186  // get next 2 levels and check for transition
187  uint8_t tStartLevel = getBiphaselevel();
188  uint8_t tEndLevel = getBiphaselevel();
189 
190  if ((tStartLevel == SPACE) && (tEndLevel == MARK)) {
191  // we have a space to mark transition here
192  tDecodedRawData = (tDecodedRawData << 1) | 1;
193  } else if ((tStartLevel == MARK) && (tEndLevel == SPACE)) {
194  // we have a mark to space transition here
195  tDecodedRawData = (tDecodedRawData << 1) | 0;
196  } else {
197 #if defined(LOCAL_DEBUG)
198  Serial.print(F("RC5: "));
199  Serial.println(F("no transition found, decode failed"));
200 #endif
201  return false;
202  }
203  }
204 
205  // Success
206  decodedIRData.numberOfBits = tBitIndex; // must be RC5_BITS
207 
208  LongUnion tValue;
209  tValue.ULong = tDecodedRawData;
210  decodedIRData.decodedRawData = tDecodedRawData;
211  decodedIRData.command = tValue.UByte.LowByte & 0x3F;
212  decodedIRData.address = (tValue.UWord.LowWord >> RC5_COMMAND_BITS) & 0x1F;
213 
214  // Get the inverted 7. command bit for RC5X, the inverted value is always 1 for RC5 and serves as a second start bit.
215  if ((tValue.UWord.LowWord & (1 << (RC5_TOGGLE_BIT + RC5_ADDRESS_BITS + RC5_COMMAND_BITS))) == 0) {
216  decodedIRData.command += 0x40;
217  }
218 
220  if (tValue.UByte.MidLowByte & 0x8) {
222  }
224 
225  // check for repeat
227 
228  return true;
229 }
230 
231 //+=============================================================================
232 // RRRR CCCC 6666
233 // R R C 6
234 // RRRR C 6666
235 // R R C 6 6
236 // R R CCCC 666
237 //+=============================================================================
238 //
239 /*
240  Protocol=RC6 Address=0xF1 Command=0x76 Raw-Data=0xF176 20 bits MSB first
241  +2650,- 850
242  + 500,- 850 + 500,- 400 + 450,- 450 + 450,- 850
243  +1400,- 400 + 450,- 450 + 450,- 450 + 450,- 900
244  + 450,- 450 + 450,- 400 + 950,- 850 + 900,- 450
245  + 450,- 450 + 450,- 850 + 950,- 400 + 450,- 900
246  + 450
247  Sum: 23150
248  */
249 // Frame RC6: 1 start bit + 1 Bit "1" + 3 mode bits (000) + 1 toggle bit + 8 address + 8 command bits + 2666us pause - 22 bits incl. start bit
250 // Frame RC6A: 1 start bit + 1 Bit "1" + 3 mode bits (110) + 1 toggle bit + "1" + 14 customer bits + 8 system bits + 8 command bits + 2666us pause - 37 bits incl. start bit
251 // !!! toggle bit has another timing :-( !!!
252 // mark->space => 1
253 // space->mark => 0
254 // https://www.sbprojects.net/knowledge/ir/rc6.php
255 // https://www.mikrocontroller.net/articles/IRMP_-_english#RC6_.2B_RC6A
256 // https://en.wikipedia.org/wiki/Manchester_code
257 #define MIN_RC6_SAMPLES 1
258 
259 #define RC6_RPT_LENGTH 46000
260 
261 #define RC6_LEADING_BIT 1
262 #define RC6_MODE_BITS 3 // never seen others than all 0 for Philips TV
263 #define RC6_TOGGLE_BIT 1 // toggles at every key press. Can be used to distinguish repeats from 2 key presses and has another timing :-(.
264 #define RC6_TOGGLE_BIT_INDEX RC6_MODE_BITS // fourth position, index = 3
265 #define RC6_ADDRESS_BITS 8
266 #define RC6_COMMAND_BITS 8
267 #define RC6_CUSTOMER_BITS 14
268 
269 #define RC6_BITS (RC6_LEADING_BIT + RC6_MODE_BITS + RC6_TOGGLE_BIT + RC6_ADDRESS_BITS + RC6_COMMAND_BITS) // 21
270 #define RC6A_BITS (RC6_LEADING_BIT + RC6_MODE_BITS + RC6_TOGGLE_BIT + 1 + RC6_CUSTOMER_BITS + RC6_ADDRESS_BITS + RC6_COMMAND_BITS) // 36
271 
272 #define RC6_UNIT 444 // 16 periods of 36 kHz (444.4444)
273 
274 #define RC6_HEADER_MARK (6 * RC6_UNIT) // 2666
275 #define RC6_HEADER_SPACE (2 * RC6_UNIT) // 889
276 
277 #define RC6_TRAILING_SPACE (6 * RC6_UNIT) // 2666
278 #define MIN_RC6_MARKS 4 + ((RC6_ADDRESS_BITS + RC6_COMMAND_BITS) / 2) // 12, 4 are for preamble
279 
280 #define RC6_REPEAT_DISTANCE 107000 // just a guess but > 2.666ms
281 #define RC6_MAXIMUM_REPEAT_DISTANCE (RC6_REPEAT_DISTANCE + (RC6_REPEAT_DISTANCE / 4)) // Just a guess
282 
286 void IRsend::sendRC6(uint32_t aRawData, uint8_t aNumberOfBitsToSend) {
287  sendRC6Raw(aRawData, aNumberOfBitsToSend);
288 }
289 void IRsend::sendRC6Raw(uint32_t aRawData, uint8_t aNumberOfBitsToSend) {
290 // Set IR carrier frequency
292 
293 // Header
296 
297 // Start bit
298  mark(RC6_UNIT);
299  space(RC6_UNIT);
300 
301 // Data MSB first
302  uint32_t mask = 1UL << (aNumberOfBitsToSend - 1);
303  for (uint_fast8_t i = 1; mask; i++, mask >>= 1) {
304  // The fourth bit we send is the "double width toggle bit"
305  unsigned int t = (i == (RC6_TOGGLE_BIT_INDEX + 1)) ? (RC6_UNIT * 2) : (RC6_UNIT);
306  if (aRawData & mask) {
307  mark(t);
308  space(t);
309  } else {
310  space(t);
311  mark(t);
312  }
313  }
314 }
315 
320 void IRsend::sendRC6(uint64_t aRawData, uint8_t aNumberOfBitsToSend) {
321  sendRC6Raw(aRawData, aNumberOfBitsToSend);
322 }
323 void IRsend::sendRC6Raw(uint64_t aRawData, uint8_t aNumberOfBitsToSend) {
324 // Set IR carrier frequency
326 
327 // Header
330 
331 // Start bit
332  mark(RC6_UNIT);
333  space(RC6_UNIT);
334 
335 // Data MSB first
336  uint64_t mask = 1ULL << (aNumberOfBitsToSend - 1);
337  for (uint_fast8_t i = 1; mask; i++, mask >>= 1) {
338  // The fourth bit we send is the "double width toggle bit"
339  unsigned int t = (i == (RC6_TOGGLE_BIT_INDEX + 1)) ? (RC6_UNIT * 2) : (RC6_UNIT);
340  if (aRawData & mask) {
341  mark(t);
342  space(t);
343  } else {
344  space(t);
345  mark(t);
346  }
347  }
348 }
349 
355 void IRsend::sendRC6(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle) {
356 
357  LongUnion tIRRawData;
358  tIRRawData.UByte.LowByte = aCommand;
359  tIRRawData.UByte.MidLowByte = aAddress;
360 
361  tIRRawData.UWord.HighWord = 0; // must clear high word
362  if (aEnableAutomaticToggle) {
363  if (sLastSendToggleValue == 0) {
365  // set toggled bit
366  IR_DEBUG_PRINT(F("Set Toggle "));
367  tIRRawData.UByte.MidHighByte = 1; // 3 Mode bits are 0
368  } else {
370  }
371  }
372 
373 #if defined(LOCAL_DEBUG)
374  Serial.print(F("RC6: "));
375  Serial.print(F("sLastSendToggleValue="));
376  Serial.print (sLastSendToggleValue);
377  Serial.print(F(" RawData="));
378  Serial.println(tIRRawData.ULong, HEX);
379 #endif
380 
381  uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1;
382  while (tNumberOfCommands > 0) {
383 
384  // start and leading bits are sent by sendRC6
385  sendRC6Raw(tIRRawData.ULong, RC6_BITS - 1); // -1 since the leading bit is additionally sent by sendRC6
386 
387  tNumberOfCommands--;
388  // skip last delay!
389  if (tNumberOfCommands > 0) {
390  // send repeated command in a fixed raster
392  }
393  }
394 }
395 
401 void IRsend::sendRC6A(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, uint16_t aCustomer,
402  bool aEnableAutomaticToggle) {
403 
404  LongUnion tIRRawData;
405  tIRRawData.UByte.LowByte = aCommand;
406  tIRRawData.UByte.MidLowByte = aAddress;
407 
408  tIRRawData.UWord.HighWord = aCustomer | 0x400; // bit 31 is always 1
409 
410  if (aEnableAutomaticToggle) {
411  if (sLastSendToggleValue == 0) {
413  // set toggled bit
414  IR_DEBUG_PRINT(F("Set Toggle "));
415  tIRRawData.UByte.HighByte |= 0x80; // toggle bit is bit 32
416  } else {
418  }
419  }
420 
421  // Set mode bits
422  uint64_t tRawData = tIRRawData.ULong + 0x0600000000;
423 
424 #if defined(LOCAL_DEBUG)
425  Serial.print(F("RC6A: "));
426  Serial.print(F("sLastSendToggleValue="));
427  Serial.print (sLastSendToggleValue);
428  Serial.print(F(" RawData="));
429  Serial.println(tIRRawData.ULong, HEX);
430 #endif
431 
432  uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1;
433  while (tNumberOfCommands > 0) {
434 
435  // start and leading bits are sent by sendRC6
436  sendRC6Raw(tRawData, RC6A_BITS - 1); // -1 since the leading bit is additionally sent by sendRC6
437 
438  tNumberOfCommands--;
439  // skip last delay!
440  if (tNumberOfCommands > 0) {
441  // send repeated command in a fixed raster
443  }
444  }
445 }
446 
451  uint8_t tBitIndex;
452  uint32_t tDecodedRawData = 0;
453 
454  // Check we have the right amount of data (). The +3 for initial gap, start bit mark and space
456  IR_DEBUG_PRINT(F("RC6: "));
457  IR_DEBUG_PRINT(F("Data length="));
459  IR_DEBUG_PRINTLN(F(" is not between 15 and 25"));
460  return false;
461  }
462 
463  // Check header "mark" and "space", this must be done for repeat and data
466  // no debug output, since this check is mainly to determine the received protocol
467  IR_DEBUG_PRINT(F("RC6: "));
468  IR_DEBUG_PRINTLN(F("Header mark or space length is wrong"));
469  return false;
470  }
471 
472  // Set Biphase decoding start values
473  initBiphaselevel(3, RC6_UNIT); // Skip gap-space and start-bit mark + space
474 
475 // Process first bit, which is known to be a 1 (mark->space)
476  if (getBiphaselevel() != MARK) {
477  IR_DEBUG_PRINT(F("RC6: "));
478  IR_DEBUG_PRINTLN(F("first getBiphaselevel() is not MARK"));
479  return false;
480  }
481  if (getBiphaselevel() != SPACE) {
482  IR_DEBUG_PRINT(F("RC6: "));
483  IR_DEBUG_PRINTLN(F("second getBiphaselevel() is not SPACE"));
484  return false;
485  }
486 
487  for (tBitIndex = 0; sBiphaseDecodeRawbuffOffset < decodedIRData.rawlen; tBitIndex++) {
488  uint8_t tStartLevel; // start level of coded bit
489  uint8_t tEndLevel; // end level of coded bit
490 
491  tStartLevel = getBiphaselevel();
492  if (tBitIndex == RC6_TOGGLE_BIT_INDEX) {
493  // Toggle bit is double wide; make sure second half is equal first half
494  if (tStartLevel != getBiphaselevel()) {
495 #if defined(LOCAL_DEBUG)
496  Serial.print(F("RC6: "));
497  Serial.println(F("Toggle mark or space length is wrong"));
498 #endif
499  return false;
500  }
501  }
502 
503  tEndLevel = getBiphaselevel();
504  if (tBitIndex == RC6_TOGGLE_BIT_INDEX) {
505  // Toggle bit is double wide; make sure second half matches
506  if (tEndLevel != getBiphaselevel()) {
507 #if defined(LOCAL_DEBUG)
508  Serial.print(F("RC6: "));
509  Serial.println(F("Toggle mark or space length is wrong"));
510 #endif
511  return false;
512  }
513  }
514 
515  /*
516  * Determine tDecodedRawData bit value by checking the transition type
517  */
518  if ((tStartLevel == MARK) && (tEndLevel == SPACE)) {
519  // we have a mark to space transition here
520  tDecodedRawData = (tDecodedRawData << 1) | 1; // inverted compared to RC5
521  } else if ((tStartLevel == SPACE) && (tEndLevel == MARK)) {
522  // we have a space to mark transition here
523  tDecodedRawData = (tDecodedRawData << 1) | 0;
524  } else {
525 #if defined(LOCAL_DEBUG)
526  Serial.print(F("RC6: "));
527  Serial.println(F("Decode failed"));
528 #endif
529  // we have no transition here or one level is -1 -> error
530  return false; // Error
531  }
532  }
533 
534 // Success
535  decodedIRData.numberOfBits = tBitIndex;
536 
537  LongUnion tValue;
538  tValue.ULong = tDecodedRawData;
539  decodedIRData.decodedRawData = tDecodedRawData;
540 
541  if (tBitIndex < 35) {
542  // RC6 8 address bits, 8 command bits
546  // Check for toggle flag
547  if ((tValue.UByte.MidHighByte & 1) != 0) {
549  }
550  if (tBitIndex > 20) {
552  }
554 
555  } else {
556  // RC6A
560  decodedIRData.extra = tValue.UWord.HighWord & 0x3FFF; // Mask to 14 bits, remove toggle and constant 1
561  if ((tValue.UByte.HighByte & 0x80) != 0) {
563  }
565  }
566 
567  // check for repeat, do not check toggle bit yet
569 
570  return true;
571 }
572 
573 /*********************************************************************************
574  * Old deprecated functions, kept for backward compatibility to old 2.0 tutorials
575  *********************************************************************************/
576 
580 void IRsend::sendRC5(uint32_t data, uint8_t nbits) {
581  // Set IR carrier frequency
583 
584  // Start
585  mark(RC5_UNIT);
586  space(RC5_UNIT);
587  mark(RC5_UNIT);
588 
589  // Data - Biphase code MSB first
590  for (uint32_t mask = 1UL << (nbits - 1); mask; mask >>= 1) {
591  if (data & mask) {
592  space(RC5_UNIT); // 1 is space, then mark
593  mark(RC5_UNIT);
594  } else {
595  mark(RC5_UNIT);
596  space(RC5_UNIT);
597  }
598  }
599 }
600 
601 /*
602  * Not longer required, use sendRC5(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle) instead
603  */
604 void IRsend::sendRC5ext(uint8_t addr, uint8_t cmd, bool toggle) {
605 // Set IR carrier frequency
607 
608  uint8_t addressBits = 5;
609  uint8_t commandBits = 7;
610 // unsigned long nbits = addressBits + commandBits;
611 
612 // Start
613  mark(RC5_UNIT);
614 
615 // Bit #6 of the command part, but inverted!
616  uint8_t cmdBit6 = (1UL << (commandBits - 1)) & cmd;
617  if (cmdBit6) {
618  // Inverted (1 -> 0 = mark-to-space)
619  mark(RC5_UNIT);
620  space(RC5_UNIT);
621  } else {
622  space(RC5_UNIT);
623  mark(RC5_UNIT);
624  }
625  commandBits--;
626 
627 // Toggle bit
628  static int toggleBit = 1;
629  if (toggle) {
630  if (toggleBit == 0) {
631  toggleBit = 1;
632  } else {
633  toggleBit = 0;
634  }
635  }
636  if (toggleBit) {
637  space(RC5_UNIT);
638  mark(RC5_UNIT);
639  } else {
640  mark(RC5_UNIT);
641  space(RC5_UNIT);
642  }
643 
644 // Address
645  for (uint_fast8_t mask = 1UL << (addressBits - 1); mask; mask >>= 1) {
646  if (addr & mask) {
647  space(RC5_UNIT); // 1 is space, then mark
648  mark(RC5_UNIT);
649  } else {
650  mark(RC5_UNIT);
651  space(RC5_UNIT);
652  }
653  }
654 
655 // Command
656  for (uint_fast8_t mask = 1UL << (commandBits - 1); mask; mask >>= 1) {
657  if (cmd & mask) {
658  space(RC5_UNIT); // 1 is space, then mark
659  mark(RC5_UNIT);
660  } else {
661  mark(RC5_UNIT);
662  space(RC5_UNIT);
663  }
664  }
665 }
666 
668 #if defined(LOCAL_DEBUG)
669 #undef LOCAL_DEBUG
670 #endif
671 #endif // _IR_RC5_RC6_HPP
IRData::address
uint16_t address
Decoded address, Distance protocol (tMarkTicksLong (if tMarkTicksLong == 0, then tMarkTicksShort) << ...
Definition: IRremoteInt.h:152
MICROS_PER_TICK
#define MICROS_PER_TICK
microseconds per clock interrupt tick
Definition: IRremote.hpp:207
LongUnion
Union to specify parts / manifestations of a 32 bit Long without casts and shifts.
Definition: LongUnion.h:59
RC5_RC6_KHZ
#define RC5_RC6_KHZ
Definition: IRProtocol.h:196
IRData::numberOfBits
uint16_t numberOfBits
Number of bits received for data (address + command + parity) - to determine protocol length if diffe...
Definition: IRremoteInt.h:161
IRsend::aNumberOfRepeats
void int_fast8_t aNumberOfRepeats
Definition: IRremoteInt.h:538
MICROS_IN_ONE_MILLI
#define MICROS_IN_ONE_MILLI
Definition: IRremote.hpp:212
LongUnion::UByte
struct LongUnion::@4 UByte
IRsend::sendRC6Raw
void sendRC6Raw(uint32_t data, uint8_t nbits)
Definition: ir_RC5_RC6.hpp:289
IRsend::mark
void mark(uint16_t aMarkMicros)
Sends an IR mark for the specified number of microseconds.
Definition: IRSend.hpp:1153
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:355
sLastSendToggleValue
uint8_t sLastSendToggleValue
Definition: ir_RC5_RC6.hpp:44
sBiphaseDecodeRawbuffOffset
uint_fast8_t sBiphaseDecodeRawbuffOffset
Definition: IRReceive.hpp:1129
RC5_UNIT
#define RC5_UNIT
Definition: ir_RC5_RC6.hpp:89
LongUnion::LowByte
uint8_t LowByte
Definition: LongUnion.h:61
RC6_BITS
#define RC6_BITS
Definition: ir_RC5_RC6.hpp:269
LongUnion::HighByte
uint8_t HighByte
Definition: LongUnion.h:64
RC5_REPEAT_DISTANCE
#define RC5_REPEAT_DISTANCE
Definition: ir_RC5_RC6.hpp:95
IRData::decodedRawData
IRRawDataType decodedRawData
Up to 32/64 bit decoded raw data, to be used for send<protocol>Raw functions.
Definition: IRremoteInt.h:155
IRrecv::checkForRepeatSpaceTicksAndSetFlag
void checkForRepeatSpaceTicksAndSetFlag(uint16_t aMaximumRepeatSpaceTicks)
Definition: IRReceive.hpp:1333
IR_DEBUG_PRINT
#define IR_DEBUG_PRINT(...)
If DEBUG, print the arguments, otherwise do nothing.
Definition: IRremoteInt.h:186
LongUnion::LowWord
uint16_t LowWord
Definition: LongUnion.h:80
matchSpace
bool matchSpace(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros)
Compensate for spaces shortened by demodulator hardware.
Definition: IRReceive.hpp:1459
IRrecv::getBiphaselevel
uint_fast8_t getBiphaselevel()
Gets the level of one time interval (aBiphaseTimeUnit) at a time from the raw buffer.
Definition: IRReceive.hpp:1156
RC5_ADDRESS_BITS
#define RC5_ADDRESS_BITS
Definition: ir_RC5_RC6.hpp:82
RC6_HEADER_SPACE
#define RC6_HEADER_SPACE
Definition: ir_RC5_RC6.hpp:275
LongUnion::MidLowByte
uint8_t MidLowByte
Definition: LongUnion.h:62
MIN_RC6_MARKS
#define MIN_RC6_MARKS
Definition: ir_RC5_RC6.hpp:278
LongUnion::HighWord
uint16_t HighWord
Definition: LongUnion.h:81
IRrecv::decodedIRData
IRData decodedIRData
Definition: IRremoteInt.h:409
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:152
IRData::flags
uint8_t flags
IRDATA_FLAGS_IS_REPEAT, IRDATA_FLAGS_WAS_OVERFLOW etc. See IRDATA_FLAGS_* definitions above.
Definition: IRremoteInt.h:162
IRsend::sendRC5ext
void sendRC5ext(uint8_t addr, uint8_t cmd, bool toggle)
Definition: ir_RC5_RC6.hpp:604
RC5_COMMAND_BITS
#define RC5_COMMAND_BITS
Definition: ir_RC5_RC6.hpp:83
RC6_HEADER_MARK
#define RC6_HEADER_MARK
Definition: ir_RC5_RC6.hpp:274
RC5_BITS
#define RC5_BITS
Definition: ir_RC5_RC6.hpp:87
IRData::command
uint16_t command
Decoded command, Distance protocol (tMarkTicksShort << 8) | tSpaceTicksShort.
Definition: IRremoteInt.h:153
RC6_MAXIMUM_REPEAT_DISTANCE
#define RC6_MAXIMUM_REPEAT_DISTANCE
Definition: ir_RC5_RC6.hpp:281
matchMark
bool matchMark(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros)
Compensate for marks exceeded by demodulator hardware.
Definition: IRReceive.hpp:1411
RC5_TOGGLE_BIT
#define RC5_TOGGLE_BIT
Definition: ir_RC5_RC6.hpp:85
irparams_struct::rawbuf
IRRawbufType rawbuf[RAW_BUFFER_LENGTH]
raw data / tick counts per mark/space. With 8 bit we can only store up to 12.7 ms....
Definition: IRremoteInt.h:140
LongUnion::ULong
uint32_t ULong
Definition: LongUnion.h:95
IRrecv::irparams
irparams_struct irparams
Definition: IRremoteInt.h:408
IRDATA_FLAGS_IS_MSB_FIRST
#define IRDATA_FLAGS_IS_MSB_FIRST
Value is mainly determined by the (known) protocol.
Definition: IRProtocol.h:155
IRrecv::decodeRC5
bool decodeRC5()
Try to decode data as RC5 protocol.
Definition: ir_RC5_RC6.hpp:158
RC6A
@ RC6A
Definition: IRProtocol.h:113
RC6_REPEAT_DISTANCE
#define RC6_REPEAT_DISTANCE
Definition: ir_RC5_RC6.hpp:280
IRDATA_FLAGS_TOGGLE_BIT
#define IRDATA_FLAGS_TOGGLE_BIT
Is set if RC5 or RC6 toggle bit is set.
Definition: IRProtocol.h:150
RC5
@ RC5
Definition: IRProtocol.h:111
IRData::extra
uint16_t extra
Contains upper 16 bit of Magiquest WandID, Kaseikyo unknown vendor ID and Distance protocol (HeaderMa...
Definition: IRremoteInt.h:154
RC6_TOGGLE_BIT_INDEX
#define RC6_TOGGLE_BIT_INDEX
Definition: ir_RC5_RC6.hpp:264
IRsend::space
static void space(uint16_t aSpaceMicros)
Sends an IR space for the specified number of microseconds.
Definition: IRSend.hpp:1364
IRsend::sendRC5
void sendRC5(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle=true)
Definition: ir_RC5_RC6.hpp:106
IRrecv::initBiphaselevel
void initBiphaselevel(uint_fast8_t aRCDecodeRawbuffOffset, uint16_t aBiphaseTimeUnit)
Definition: IRReceive.hpp:1134
SPACE
#define SPACE
Definition: IRremoteInt.h:39
IRData::rawlen
IRRawlenType rawlen
Counter of entries in rawbuf of last received frame.
Definition: IRremoteInt.h:170
LongUnion::MidHighByte
uint8_t MidHighByte
Definition: LongUnion.h:63
RC6
@ RC6
Definition: IRProtocol.h:112
LongUnion::UWord
struct LongUnion::@6 UWord
RC6_UNIT
#define RC6_UNIT
Definition: ir_RC5_RC6.hpp:272
IRsend::sendRC6A
void sendRC6A(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, uint16_t aCustomer, 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:401
IR_DEBUG_PRINTLN
#define IR_DEBUG_PRINTLN(...)
If DEBUG, print the arguments as a line, otherwise do nothing.
Definition: IRremoteInt.h:190
IRData::protocol
decode_type_t protocol
UNKNOWN, NEC, SONY, RC5, PULSE_DISTANCE, ...
Definition: IRremoteInt.h:151
IRrecv::decodeRC6
bool decodeRC6()
Try to decode data as RC6 protocol.
Definition: ir_RC5_RC6.hpp:450
IRsend::sendBiphaseData
void sendBiphaseData(uint16_t 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:1093
MARK
#define MARK
Definition: IRremoteInt.h:38
IRsend::aCommand
void aCommand
Definition: IRremoteInt.h:688
RC5_MAXIMUM_REPEAT_DISTANCE
#define RC5_MAXIMUM_REPEAT_DISTANCE
Definition: ir_RC5_RC6.hpp:96
IRsend::enableIROut
void enableIROut(uint_fast8_t aFrequencyKHz)
Enables IR output.
Definition: IRSend.hpp:1404
RC6A_BITS
#define RC6A_BITS
Definition: ir_RC5_RC6.hpp:270