Go to the documentation of this file.
32 #ifndef _IR_RC5_RC6_HPP
33 #define _IR_RC5_RC6_HPP
82 #define RC5_ADDRESS_BITS 5
83 #define RC5_COMMAND_BITS 6
84 #define RC5_EXTENSION_BITS 6
85 #define RC5_COMMAND_FIELD_BIT 1
86 #define RC5_TOGGLE_BIT 1
88 #define RC5_BITS (RC5_COMMAND_FIELD_BIT + RC5_TOGGLE_BIT + RC5_ADDRESS_BITS + RC5_COMMAND_BITS) // 13
90 #define RC5_UNIT 889 // 32 periods of 36 kHz (888.8888)
92 #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
94 #define RC5_DURATION (15L * RC5_UNIT) // 13335
95 #define RC5_REPEAT_PERIOD (128L * RC5_UNIT) // 113792
96 #define RC5_REPEAT_DISTANCE (RC5_REPEAT_PERIOD - RC5_DURATION) // 100 ms
97 #define RC5_MAXIMUM_REPEAT_DISTANCE (RC5_REPEAT_DISTANCE + (RC5_REPEAT_DISTANCE / 4)) // Just a guess
109 bool aEnableAutomaticToggle) {
114 uint16_t tIRData = (aAddress & 0x1F);
126 tIRExtData |= (aMarantzExtension & 0x3F);
128 if (aEnableAutomaticToggle) {
139 while (tNumberOfCommands > 0) {
150 if (tNumberOfCommands > 0) {
161 void IRsend::sendRC5(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats,
bool aEnableAutomaticToggle) {
177 if (aEnableAutomaticToggle) {
188 while (tNumberOfCommands > 0) {
195 if (tNumberOfCommands > 0) {
216 uint32_t tDecodedRawData = 0;
246 if ((tStartLevel ==
SPACE) && (tEndLevel ==
MARK)) {
248 tDecodedRawData = (tDecodedRawData << 1) | 1;
249 }
else if ((tStartLevel ==
MARK) && (tEndLevel ==
SPACE)) {
251 tDecodedRawData = (tDecodedRawData << 1) | 0;
253 #if defined(LOCAL_DEBUG)
254 Serial.print(F(
"RC5: "));
255 Serial.println(F(
"no transition found, decode failed"));
265 tValue.
ULong = tDecodedRawData;
313 #define MIN_RC6_SAMPLES 1
315 #define RC6_RPT_LENGTH 46000
317 #define RC6_LEADING_BIT 1
318 #define RC6_MODE_BITS 3 // never seen others than all 0 for Philips TV
319 #define RC6_TOGGLE_BIT 1 // toggles at every key press. Can be used to distinguish repeats from 2 key presses and has another timing :-(.
320 #define RC6_TOGGLE_BIT_INDEX RC6_MODE_BITS // fourth position, index = 3
321 #define RC6_ADDRESS_BITS 8
322 #define RC6_COMMAND_BITS 8
323 #define RC6_CUSTOMER_BITS 14
325 #define RC6_BITS (RC6_LEADING_BIT + RC6_MODE_BITS + RC6_TOGGLE_BIT + RC6_ADDRESS_BITS + RC6_COMMAND_BITS) // 21
326 #define RC6A_BITS (RC6_LEADING_BIT + RC6_MODE_BITS + RC6_TOGGLE_BIT + 1 + RC6_CUSTOMER_BITS + RC6_ADDRESS_BITS + RC6_COMMAND_BITS) // 36
328 #define RC6_UNIT 444 // 16 periods of 36 kHz (444.4444)
330 #define RC6_HEADER_MARK (6 * RC6_UNIT) // 2666
331 #define RC6_HEADER_SPACE (2 * RC6_UNIT) // 889
333 #define RC6_TRAILING_SPACE (6 * RC6_UNIT) // 2666
334 #define MIN_RC6_MARKS 4 + ((RC6_ADDRESS_BITS + RC6_COMMAND_BITS) / 2) // 12, 4 are for preamble
336 #define RC6_REPEAT_DISTANCE 107000 // just a guess but > 2.666ms
337 #define RC6_MAXIMUM_REPEAT_DISTANCE (RC6_REPEAT_DISTANCE + (RC6_REPEAT_DISTANCE / 4)) // Just a guess
358 uint32_t mask = 1UL << (aNumberOfBitsToSend - 1);
359 for (uint_fast8_t i = 1; mask; i++, mask >>= 1) {
362 if (aRawData & mask) {
392 uint64_t mask = 1ULL << (aNumberOfBitsToSend - 1);
393 for (uint_fast8_t i = 1; mask; i++, mask >>= 1) {
396 if (aRawData & mask) {
411 void IRsend::sendRC6(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats,
bool aEnableAutomaticToggle) {
418 if (aEnableAutomaticToggle) {
429 #if defined(LOCAL_DEBUG)
430 Serial.print(F(
"RC6: "));
431 Serial.print(F(
"sLastSendToggleValue="));
433 Serial.print(F(
" RawData="));
434 Serial.println(tIRRawData.
ULong, HEX);
438 while (tNumberOfCommands > 0) {
445 if (tNumberOfCommands > 0) {
457 void IRsend::sendRC6A(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, uint16_t aCustomer,
458 bool aEnableAutomaticToggle) {
466 if (aEnableAutomaticToggle) {
478 uint64_t tRawData = tIRRawData.
ULong + 0x0600000000;
480 #if defined(LOCAL_DEBUG)
481 Serial.print(F(
"RC6A: "));
482 Serial.print(F(
"sLastSendToggleValue="));
484 Serial.print(F(
" RawData="));
485 Serial.println(tIRRawData.
ULong, HEX);
489 while (tNumberOfCommands > 0) {
496 if (tNumberOfCommands > 0) {
508 uint32_t tDecodedRawData = 0;
551 #if defined(LOCAL_DEBUG)
552 Serial.print(F(
"RC6: "));
553 Serial.println(F(
"Toggle mark or space length is wrong"));
563 #if defined(LOCAL_DEBUG)
564 Serial.print(F(
"RC6: "));
565 Serial.println(F(
"Toggle mark or space length is wrong"));
574 if ((tStartLevel ==
MARK) && (tEndLevel ==
SPACE)) {
576 tDecodedRawData = (tDecodedRawData << 1) | 1;
577 }
else if ((tStartLevel ==
SPACE) && (tEndLevel ==
MARK)) {
579 tDecodedRawData = (tDecodedRawData << 1) | 0;
581 #if defined(LOCAL_DEBUG)
582 Serial.print(F(
"RC6: "));
583 Serial.println(F(
"Decode failed"));
594 tValue.
ULong = tDecodedRawData;
597 if (tBitIndex < 35) {
606 if (tBitIndex > 20) {
646 for (uint32_t mask = 1UL << (nbits - 1); mask; mask >>= 1) {
664 uint8_t addressBits = 5;
665 uint8_t commandBits = 7;
672 uint8_t cmdBit6 = (1UL << (commandBits - 1)) & cmd;
684 static int toggleBit = 1;
686 if (toggleBit == 0) {
701 for (uint_fast8_t mask = 1UL << (addressBits - 1); mask; mask >>= 1) {
712 for (uint_fast8_t mask = 1UL << (commandBits - 1); mask; mask >>= 1) {
724 #if defined(LOCAL_DEBUG)
727 #endif // _IR_RC5_RC6_HPP
uint16_t address
Decoded address, Distance protocol (tMarkTicksLong (if tMarkTicksLong == 0, then tMarkTicksShort) << ...
#define MICROS_PER_TICK
microseconds per clock interrupt tick
Union to specify parts / manifestations of a 32 bit Long without casts and shifts.
uint16_t numberOfBits
Number of bits received for data (address + command + parity) - to determine protocol length if diffe...
void int_fast8_t aNumberOfRepeats
#define MICROS_IN_ONE_MILLI
struct LongUnion::@4 UByte
void sendRC6Raw(uint32_t data, uint8_t nbits)
void mark(uint16_t aMarkMicros)
Sends an IR mark for the specified number of microseconds.
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...
uint8_t sLastSendToggleValue
uint_fast8_t sBiphaseDecodeRawbuffOffset
#define RC5_REPEAT_DISTANCE
IRRawDataType decodedRawData
Up to 32/64 bit decoded raw data, to be used for send<protocol>Raw functions.
void checkForRepeatSpaceTicksAndSetFlag(uint16_t aMaximumRepeatSpaceTicks)
#define IR_DEBUG_PRINT(...)
If DEBUG, print the arguments, otherwise do nothing.
bool matchSpace(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros)
Compensate for spaces shortened by demodulator hardware.
uint_fast8_t getBiphaselevel()
Gets the level of one time interval (aBiphaseTimeUnit) at a time from the raw buffer.
void sendRC5Marantz(uint8_t aAddress, uint8_t aCommand, uint8_t aMarantzExtension, int_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle=true)
#define IRDATA_FLAGS_EXTRA_INFO
There is extra info not contained in address and data (e.g. Kaseikyo unknown vendor ID,...
uint8_t flags
IRDATA_FLAGS_IS_REPEAT, IRDATA_FLAGS_WAS_OVERFLOW etc. See IRDATA_FLAGS_* definitions above.
void sendRC5ext(uint8_t addr, uint8_t cmd, bool toggle)
uint16_t command
Decoded command, Distance protocol (tMarkTicksShort << 8) | tSpaceTicksShort.
#define RC6_MAXIMUM_REPEAT_DISTANCE
void sendBiphaseData(uint16_t aBiphaseTimeUnit, uint32_t aData, uint_fast8_t aNumberOfBits, bool aSendStartBit=true)
Sends Biphase (Manchester) coded data MSB first This function concatenates two marks to one longer ma...
bool matchMark(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros)
Compensate for marks exceeded by demodulator hardware.
#define RC5_COMMAND_FIELD_BIT
IRRawbufType rawbuf[RAW_BUFFER_LENGTH]
raw data / tick counts per mark/space. With 8 bit we can only store up to 12.7 ms....
#define IRDATA_FLAGS_IS_MSB_FIRST
Value is mainly determined by the (known) protocol.
bool decodeRC5()
Try to decode data as RC5 protocol.
#define RC6_REPEAT_DISTANCE
#define IRDATA_FLAGS_TOGGLE_BIT
Is set if RC5 or RC6 toggle bit is set.
uint16_t extra
Contains upper 16 bit of Magiquest WandID, Kaseikyo unknown vendor ID and Distance protocol (HeaderMa...
#define RC6_TOGGLE_BIT_INDEX
static void space(uint16_t aSpaceMicros)
Sends an IR space for the specified number of microseconds.
void sendRC5(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, bool aEnableAutomaticToggle=true)
#define RC5_EXTENSION_BITS
void initBiphaselevel(uint_fast8_t aRCDecodeRawbuffOffset, uint16_t aBiphaseTimeUnit)
IRRawlenType rawlen
Counter of entries in rawbuf of last received frame.
struct LongUnion::@6 UWord
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...
#define IR_DEBUG_PRINTLN(...)
If DEBUG, print the arguments as a line, otherwise do nothing.
decode_type_t protocol
UNKNOWN, NEC, SONY, RC5, PULSE_DISTANCE, ...
bool decodeRC6()
Try to decode data as RC6 protocol.
#define RC5_MAXIMUM_REPEAT_DISTANCE
void enableIROut(uint_fast8_t aFrequencyKHz)
Enables IR output.