Go to the documentation of this file.
32 #ifndef _IR_RC5_RC6_HPP
33 #define _IR_RC5_RC6_HPP
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
86 #define RC5_BITS (RC5_COMMAND_FIELD_BIT + RC5_TOGGLE_BIT + RC5_ADDRESS_BITS + RC5_COMMAND_BITS) // 13
88 #define RC5_UNIT 889 // 32 periods of 36 kHz (888.8888)
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
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
105 void IRsend::sendRC5(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats,
bool aEnableAutomaticToggle) {
120 if (aEnableAutomaticToggle) {
131 while (tNumberOfCommands > 0) {
138 if (tNumberOfCommands > 0) {
159 uint32_t tDecodedRawData = 0;
189 if ((tStartLevel ==
SPACE) && (tEndLevel ==
MARK)) {
191 tDecodedRawData = (tDecodedRawData << 1) | 1;
192 }
else if ((tStartLevel ==
MARK) && (tEndLevel ==
SPACE)) {
194 tDecodedRawData = (tDecodedRawData << 1) | 0;
196 #if defined(LOCAL_DEBUG)
197 Serial.print(F(
"RC5: "));
198 Serial.println(F(
"no transition found, decode failed"));
208 tValue.
ULong = tDecodedRawData;
256 #define MIN_RC6_SAMPLES 1
258 #define RC6_RPT_LENGTH 46000
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
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
271 #define RC6_UNIT 444 // 16 periods of 36 kHz (444.4444)
273 #define RC6_HEADER_MARK (6 * RC6_UNIT) // 2666
274 #define RC6_HEADER_SPACE (2 * RC6_UNIT) // 889
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
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
301 uint32_t mask = 1UL << (aNumberOfBitsToSend - 1);
302 for (uint_fast8_t i = 1; mask; i++, mask >>= 1) {
305 if (aRawData & mask) {
335 uint64_t mask = 1ULL << (aNumberOfBitsToSend - 1);
336 for (uint_fast8_t i = 1; mask; i++, mask >>= 1) {
339 if (aRawData & mask) {
354 void IRsend::sendRC6(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats,
bool aEnableAutomaticToggle) {
361 if (aEnableAutomaticToggle) {
372 #if defined(LOCAL_DEBUG)
373 Serial.print(F(
"RC6: "));
374 Serial.print(F(
"sLastSendToggleValue="));
376 Serial.print(F(
" RawData="));
377 Serial.println(tIRRawData.
ULong, HEX);
381 while (tNumberOfCommands > 0) {
388 if (tNumberOfCommands > 0) {
400 void IRsend::sendRC6A(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats, uint16_t aCustomer,
401 bool aEnableAutomaticToggle) {
409 if (aEnableAutomaticToggle) {
421 uint64_t tRawData = tIRRawData.
ULong + 0x0600000000;
423 #if defined(LOCAL_DEBUG)
424 Serial.print(F(
"RC6A: "));
425 Serial.print(F(
"sLastSendToggleValue="));
427 Serial.print(F(
" RawData="));
428 Serial.println(tIRRawData.
ULong, HEX);
432 while (tNumberOfCommands > 0) {
439 if (tNumberOfCommands > 0) {
451 uint32_t tDecodedRawData = 0;
494 #if defined(LOCAL_DEBUG)
495 Serial.print(F(
"RC6: "));
496 Serial.println(F(
"Toggle mark or space length is wrong"));
506 #if defined(LOCAL_DEBUG)
507 Serial.print(F(
"RC6: "));
508 Serial.println(F(
"Toggle mark or space length is wrong"));
517 if ((tStartLevel ==
MARK) && (tEndLevel ==
SPACE)) {
519 tDecodedRawData = (tDecodedRawData << 1) | 1;
520 }
else if ((tStartLevel ==
SPACE) && (tEndLevel ==
MARK)) {
522 tDecodedRawData = (tDecodedRawData << 1) | 0;
524 #if defined(LOCAL_DEBUG)
525 Serial.print(F(
"RC6: "));
526 Serial.println(F(
"Decode failed"));
537 tValue.
ULong = tDecodedRawData;
540 if (tBitIndex < 35) {
549 if (tBitIndex > 20) {
589 for (uint32_t mask = 1UL << (nbits - 1); mask; mask >>= 1) {
607 uint8_t addressBits = 5;
608 uint8_t commandBits = 7;
615 uint8_t cmdBit6 = (1UL << (commandBits - 1)) & cmd;
627 static int toggleBit = 1;
629 if (toggleBit == 0) {
644 for (uint_fast8_t mask = 1UL << (addressBits - 1); mask; mask >>= 1) {
655 for (uint_fast8_t mask = 1UL << (commandBits - 1); mask; mask >>= 1) {
667 #if defined(LOCAL_DEBUG)
670 #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
irparams_struct * rawDataPtr
Pointer of the raw timing data to be decoded. Mainly the OverflowFlag and the data buffer filled by r...
IRRawDataType decodedRawData
Up to 32/64 bit decoded raw data, to be used for send 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.
#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
bool matchMark(uint16_t aMeasuredTicks, uint16_t aMatchValueMicros)
Compensate for marks exceeded by demodulator hardware.
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)
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.
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...
#define RC5_MAXIMUM_REPEAT_DISTANCE
void enableIROut(uint_fast8_t aFrequencyKHz)
Enables IR output.