Go to the documentation of this file.
30 #ifndef _IR_RC5_RC6_HPP
31 #define _IR_RC5_RC6_HPP
33 #if defined(DEBUG) && !defined(LOCAL_DEBUG)
79 #define RC5_ADDRESS_BITS 5
80 #define RC5_COMMAND_BITS 6
81 #define RC5_COMMAND_FIELD_BIT 1
82 #define RC5_TOGGLE_BIT 1
84 #define RC5_BITS (RC5_COMMAND_FIELD_BIT + RC5_TOGGLE_BIT + RC5_ADDRESS_BITS + RC5_COMMAND_BITS) // 13
86 #define RC5_UNIT 889 // 32 periods of 36 kHz (888.8888)
88 #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
90 #define RC5_DURATION (15L * RC5_UNIT) // 13335
91 #define RC5_REPEAT_PERIOD (128L * RC5_UNIT) // 113792
92 #define RC5_REPEAT_DISTANCE (RC5_REPEAT_PERIOD - RC5_DURATION) // 100 ms
93 #define RC5_MAXIMUM_REPEAT_DISTANCE (RC5_REPEAT_DISTANCE + (RC5_REPEAT_DISTANCE / 4)) // Just a guess
103 void IRsend::sendRC5(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats,
bool aEnableAutomaticToggle) {
118 if (aEnableAutomaticToggle) {
129 while (tNumberOfCommands > 0) {
136 if (tNumberOfCommands > 0) {
157 uint32_t tDecodedRawData = 0;
187 if ((tStartLevel ==
SPACE) && (tEndLevel ==
MARK)) {
189 tDecodedRawData = (tDecodedRawData << 1) | 1;
190 }
else if ((tStartLevel ==
MARK) && (tEndLevel ==
SPACE)) {
192 tDecodedRawData = (tDecodedRawData << 1) | 0;
194 #if defined(LOCAL_DEBUG)
195 Serial.print(F(
"RC5: "));
196 Serial.println(F(
"no transition found, decode failed"));
206 tValue.
ULong = tDecodedRawData;
254 #define MIN_RC6_SAMPLES 1
256 #define RC6_RPT_LENGTH 46000
258 #define RC6_LEADING_BIT 1
259 #define RC6_MODE_BITS 3 // never seen others than all 0 for Philips TV
260 #define RC6_TOGGLE_BIT 1 // toggles at every key press. Can be used to distinguish repeats from 2 key presses and has another timing :-(.
261 #define RC6_TOGGLE_BIT_INDEX RC6_MODE_BITS // fourth position, index = 3
262 #define RC6_ADDRESS_BITS 8
263 #define RC6_COMMAND_BITS 8
265 #define RC6_BITS (RC6_LEADING_BIT + RC6_MODE_BITS + RC6_TOGGLE_BIT + RC6_ADDRESS_BITS + RC6_COMMAND_BITS) // 21
267 #define RC6_UNIT 444 // 16 periods of 36 kHz (444.4444)
269 #define RC6_HEADER_MARK (6 * RC6_UNIT) // 2666
270 #define RC6_HEADER_SPACE (2 * RC6_UNIT) // 889
272 #define RC6_TRAILING_SPACE (6 * RC6_UNIT) // 2666
273 #define MIN_RC6_MARKS 4 + ((RC6_ADDRESS_BITS + RC6_COMMAND_BITS) / 2) // 12, 4 are for preamble
275 #define RC6_REPEAT_DISTANCE 107000 // just a guess but > 2.666ms
276 #define RC6_MAXIMUM_REPEAT_DISTANCE (RC6_REPEAT_DISTANCE + (RC6_REPEAT_DISTANCE / 4)) // Just a guess
297 uint32_t mask = 1UL << (aNumberOfBitsToSend - 1);
298 for (uint_fast8_t i = 1; mask; i++, mask >>= 1) {
301 if (aRawData & mask) {
331 uint64_t mask = 1ULL << (aNumberOfBitsToSend - 1);
332 for (uint_fast8_t i = 1; mask; i++, mask >>= 1) {
335 if (aRawData & mask) {
350 void IRsend::sendRC6(uint8_t aAddress, uint8_t aCommand, int_fast8_t aNumberOfRepeats,
bool aEnableAutomaticToggle) {
357 if (aEnableAutomaticToggle) {
368 #if defined(LOCAL_DEBUG)
369 Serial.print(F(
"RC6: "));
370 Serial.print(F(
"sLastSendToggleValue="));
372 Serial.print(F(
" RawData="));
373 Serial.println(tIRRawData.
ULong, HEX);
377 while (tNumberOfCommands > 0) {
384 if (tNumberOfCommands > 0) {
396 uint32_t tDecodedRawData = 0;
439 #if defined(LOCAL_DEBUG)
440 Serial.print(F(
"RC6: "));
441 Serial.println(F(
"Toggle mark or space length is wrong"));
451 #if defined(LOCAL_DEBUG)
452 Serial.print(F(
"RC6: "));
453 Serial.println(F(
"Toggle mark or space length is wrong"));
462 if ((tStartLevel ==
MARK) && (tEndLevel ==
SPACE)) {
464 tDecodedRawData = (tDecodedRawData << 1) | 1;
465 }
else if ((tStartLevel ==
SPACE) && (tEndLevel ==
MARK)) {
467 tDecodedRawData = (tDecodedRawData << 1) | 0;
469 #if defined(LOCAL_DEBUG)
470 Serial.print(F(
"RC6: "));
471 Serial.println(F(
"Decode failed"));
482 tValue.
ULong = tDecodedRawData;
485 if (tBitIndex < 36) {
494 if (tBitIndex > 20) {
532 for (uint32_t mask = 1UL << (nbits - 1); mask; mask >>= 1) {
550 uint8_t addressBits = 5;
551 uint8_t commandBits = 7;
558 uint8_t cmdBit6 = (1UL << (commandBits - 1)) & cmd;
570 static int toggleBit = 1;
572 if (toggleBit == 0) {
587 for (uint_fast8_t mask = 1UL << (addressBits - 1); mask; mask >>= 1) {
598 for (uint_fast8_t mask = 1UL << (commandBits - 1); mask; mask >>= 1) {
610 #if defined(LOCAL_DEBUG)
613 #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.
#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
#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.