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