2020-12-31 11:51:54 +08:00
/*
2021-09-09 21:53:50 +08:00
* IRReceive . hpp
2021-01-28 07:58:26 +08:00
* This file is exclusively included by IRremote . h to enable easy configuration of library switches
2020-12-31 11:51:54 +08:00
*
2021-03-07 04:18:43 +08:00
* Contains all IRrecv class functions as well as other receiver related functions .
2020-12-31 11:51:54 +08:00
*
2021-03-03 02:59:41 +08:00
* This file is part of Arduino - IRremote https : //github.com/Arduino-IRremote/Arduino-IRremote.
2020-12-31 11:51:54 +08:00
*
2021-01-12 07:23:54 +08:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* MIT License
*
2023-01-08 03:52:51 +08:00
* Copyright ( c ) 2009 - 2023 Ken Shirriff , Rafi Khan , Armin Joachimsmeyer
2021-01-12 07:23:54 +08:00
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the " Software " ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is furnished
* to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR IMPLIED ,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY , FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER LIABILITY , WHETHER IN AN ACTION OF
* CONTRACT , TORT OR OTHERWISE , ARISING FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2020-12-31 11:51:54 +08:00
*/
2022-03-30 17:55:04 +08:00
# ifndef _IR_RECEIVE_HPP
# define _IR_RECEIVE_HPP
2020-12-31 11:51:54 +08:00
2022-11-08 07:36:44 +08:00
# if defined(DEBUG) && !defined(LOCAL_DEBUG)
# define LOCAL_DEBUG
# else
//#define LOCAL_DEBUG // This enables debug output only for this file
# endif
2022-11-09 21:01:52 +08:00
# if defined(TRACE) && !defined(LOCAL_TRACE)
# define LOCAL_TRACE
# else
//#define LOCAL_TRACE // This enables debug output only for this file
# endif
2023-02-24 09:40:21 +08:00
/*
* Low level hardware timing measurement
*/
//#define _IR_MEASURE_TIMING // for ISR
//#define _IR_TIMING_TEST_PIN 7 // "pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);" is executed at start()
//
2022-11-09 21:01:52 +08:00
/*
* Check for additional characteristics of timing like length of mark for a constant mark protocol ,
2022-11-14 22:00:43 +08:00
* where space length determines the bit value . Requires up to 194 additional bytes of program memory .
2022-11-09 21:01:52 +08:00
*/
//#define DECODE_STRICT_CHECKS
2021-03-18 04:52:41 +08:00
/** \addtogroup Receiving Receiving IR data for multiple protocols
* @ {
*/
2021-03-07 04:18:43 +08:00
/**
* The receiver instance
*/
2021-01-17 02:50:36 +08:00
IRrecv IrReceiver ;
2021-03-07 04:18:43 +08:00
/*
* The control structure instance
*/
struct irparams_struct irparams ; // the irparams instance
2021-01-17 02:50:36 +08:00
/**
* Instantiate the IRrecv class . Multiple instantiation is not supported .
2021-03-06 08:21:46 +08:00
* @ param IRReceivePin Arduino pin to use . No sanity check is made .
2021-01-17 02:50:36 +08:00
*/
IRrecv : : IRrecv ( ) {
2021-04-29 23:33:05 +08:00
decodedIRData . rawDataPtr = & irparams ; // for decodePulseDistanceData() etc.
2021-03-09 04:38:06 +08:00
setReceivePin ( 0 ) ;
2021-12-08 07:44:48 +08:00
# if !defined(NO_LED_FEEDBACK_CODE)
2022-02-12 02:14:29 +08:00
setLEDFeedback ( 0 , DO_NOT_ENABLE_LED_FEEDBACK ) ;
2021-03-09 04:38:06 +08:00
# endif
2021-01-17 02:50:36 +08:00
}
2022-05-19 15:51:34 +08:00
IRrecv : : IRrecv ( uint_fast8_t aReceivePin ) {
2021-04-29 23:33:05 +08:00
decodedIRData . rawDataPtr = & irparams ; // for decodePulseDistanceData() etc.
2021-03-09 04:38:06 +08:00
setReceivePin ( aReceivePin ) ;
2021-12-08 07:44:48 +08:00
# if !defined(NO_LED_FEEDBACK_CODE)
2022-02-12 02:14:29 +08:00
setLEDFeedback ( 0 , DO_NOT_ENABLE_LED_FEEDBACK ) ;
2021-03-09 04:38:06 +08:00
# endif
2021-01-17 02:50:36 +08:00
}
2022-08-06 20:39:28 +08:00
2021-01-17 02:50:36 +08:00
/**
* Instantiate the IRrecv class . Multiple instantiation is not supported .
2021-03-18 04:52:41 +08:00
* @ param aReceivePin Arduino pin to use , where a demodulating IR receiver is connected .
* @ param aFeedbackLEDPin if 0 , then take board specific FEEDBACK_LED_ON ( ) and FEEDBACK_LED_OFF ( ) functions
2021-01-17 02:50:36 +08:00
*/
2022-05-19 15:51:34 +08:00
IRrecv : : IRrecv ( uint_fast8_t aReceivePin , uint_fast8_t aFeedbackLEDPin ) {
2021-04-29 23:33:05 +08:00
decodedIRData . rawDataPtr = & irparams ; // for decodePulseDistanceData() etc.
2021-03-09 04:38:06 +08:00
setReceivePin ( aReceivePin ) ;
2021-12-08 07:44:48 +08:00
# if !defined(NO_LED_FEEDBACK_CODE)
2022-02-12 02:14:29 +08:00
setLEDFeedback ( aFeedbackLEDPin , DO_NOT_ENABLE_LED_FEEDBACK ) ;
2021-03-09 04:38:06 +08:00
# else
( void ) aFeedbackLEDPin ;
# endif
2021-01-17 02:50:36 +08:00
}
2022-12-15 08:34:02 +08:00
/**********************************************************************************************************************
* Interrupt Service Routine - Called every 50 us
*
* Duration in ticks of 50 us of alternating SPACE , MARK are recorded in irparams . rawbuf array .
* ' rawlen ' counts the number of entries recorded so far .
* First entry is the SPACE between transmissions .
*
* As soon as one SPACE entry gets longer than RECORD_GAP_TICKS , state switches to STOP ( frame received ) . Timing of SPACE continues .
* A call of resume ( ) switches from STOP to IDLE .
* As soon as first MARK arrives in IDLE , gap width is recorded and new logging starts .
*
* With digitalRead and Feedback LED
* 15 pushs , 1 in , 1 eor before start of code = 2 us @ 16 MHz + * 7.2 us computation time ( 6u s idle time ) + * pop + reti = 2.25 us @ 16 MHz = > 10.3 to 11.5 us @ 16 MHz
* With portInputRegister and mask and Feedback LED code commented
* 9 pushs , 1 in , 1 eor before start of code = 1.25 us @ 16 MHz + * 2.25 us computation time + * pop + reti = 1.5 us @ 16 MHz = > 5 us @ 16 MHz
* = > Minimal CPU frequency is 4 MHz
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# if defined(TIMER_INTR_NAME)
2022-12-23 22:24:10 +08:00
ISR ( TIMER_INTR_NAME ) // for ISR definitions
2022-12-15 08:34:02 +08:00
# else
ISR ( )
// for functions definitions which are called by separate (board specific) ISR
# endif
{
# if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
digitalWriteFast ( _IR_TIMING_TEST_PIN , HIGH ) ; // 2 clock cycles
# endif
// 7 - 8.5 us for ISR body (without pushes and pops) for ATmega328 @16MHz
2022-12-23 22:24:10 +08:00
# if defined(TIMER_REQUIRES_RESET_INTR_PENDING)
timerResetInterruptPending ( ) ; // reset TickCounterForISR interrupt flag if required (currently only for Teensy and ATmega4809)
# endif
2022-12-15 08:34:02 +08:00
// Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on]
# if defined(__AVR__)
uint8_t tIRInputLevel = * irparams . IRReceivePinPortInputRegister & irparams . IRReceivePinMask ;
# else
uint_fast8_t tIRInputLevel = ( uint_fast8_t ) digitalReadFast ( irparams . IRReceivePin ) ;
# endif
/*
* Increase TickCounter and clip it at maximum 0xFFFF / 3.2 seconds at 50 us ticks
*/
if ( irparams . TickCounterForISR < UINT16_MAX ) {
irparams . TickCounterForISR + + ; // One more 50uS tick
}
/*
* Due to a ESP32 compiler bug https : //github.com/espressif/esp-idf/issues/1552 no switch statements are possible for ESP32
* So we change the code to if / else if
*/
// switch (irparams.StateForISR) {
2023-02-20 10:22:15 +08:00
//
2022-12-15 08:34:02 +08:00
if ( irparams . StateForISR = = IR_REC_STATE_IDLE ) {
/*
* Here we are just resumed and maybe in the middle of a transmission
*/
if ( tIRInputLevel = = INPUT_MARK ) {
// check if we did not start in the middle of a transmission by checking the minimum length of leading space
if ( irparams . TickCounterForISR > RECORD_GAP_TICKS ) {
# if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
// digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles
# endif
/*
* Gap between two transmissions just ended ; Record gap duration + start recording transmission
* Initialize all state machine variables
*/
irparams . OverflowFlag = false ;
irparams . rawbuf [ 0 ] = irparams . TickCounterForISR ;
irparams . rawlen = 1 ;
irparams . StateForISR = IR_REC_STATE_MARK ;
} // otherwise stay in idle state
irparams . TickCounterForISR = 0 ; // reset counter in both cases
}
} else if ( irparams . StateForISR = = IR_REC_STATE_MARK ) { // Timing mark
2023-02-10 07:08:42 +08:00
if ( tIRInputLevel ! = INPUT_MARK ) {
/*
* Mark ended here . Record mark time in rawbuf array
*/
2022-12-15 08:34:02 +08:00
# if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
// digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles
# endif
2023-02-10 07:08:42 +08:00
irparams . rawbuf [ irparams . rawlen + + ] = irparams . TickCounterForISR ; // record mark
2022-12-15 08:34:02 +08:00
irparams . StateForISR = IR_REC_STATE_SPACE ;
2023-02-20 10:22:15 +08:00
irparams . TickCounterForISR = 0 ; // This resets the tick counter also at end of frame :-)
2022-12-15 08:34:02 +08:00
}
} else if ( irparams . StateForISR = = IR_REC_STATE_SPACE ) { // Timing space
2023-02-10 07:08:42 +08:00
if ( tIRInputLevel = = INPUT_MARK ) {
/*
* Space ended here . Check for overflow and record space time in rawbuf array
*/
2022-12-15 08:34:02 +08:00
if ( irparams . rawlen > = RAW_BUFFER_LENGTH ) {
// Flag up a read OverflowFlag; Stop the state machine
irparams . OverflowFlag = true ;
irparams . StateForISR = IR_REC_STATE_STOP ;
# if !IR_REMOTE_DISABLE_RECEIVE_COMPLETE_CALLBACK
/*
* Call callback if registered ( not NULL )
*/
if ( irparams . ReceiveCompleteCallbackFunction ! = NULL ) {
irparams . ReceiveCompleteCallbackFunction ( ) ;
}
# endif
} else {
# if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
// digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles
# endif
2023-02-10 07:08:42 +08:00
irparams . rawbuf [ irparams . rawlen + + ] = irparams . TickCounterForISR ; // record space
2022-12-15 08:34:02 +08:00
irparams . StateForISR = IR_REC_STATE_MARK ;
}
irparams . TickCounterForISR = 0 ;
} else if ( irparams . TickCounterForISR > RECORD_GAP_TICKS ) {
/*
2023-02-10 07:08:42 +08:00
* Maximum space duration reached here .
2022-12-15 08:34:02 +08:00
* Current code is ready for processing !
* We received a long space , which indicates gap between codes .
* Switch to IR_REC_STATE_STOP
* Don ' t reset TickCounterForISR ; keep counting width of next leading space
*/
irparams . StateForISR = IR_REC_STATE_STOP ;
# if !IR_REMOTE_DISABLE_RECEIVE_COMPLETE_CALLBACK
/*
* Call callback if registered ( not NULL )
*/
if ( irparams . ReceiveCompleteCallbackFunction ! = NULL ) {
irparams . ReceiveCompleteCallbackFunction ( ) ;
}
# endif
}
} else if ( irparams . StateForISR = = IR_REC_STATE_STOP ) {
/*
* Complete command received
* stay here until resume ( ) is called , which switches state to IR_REC_STATE_IDLE
*/
# if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
// digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles
# endif
if ( tIRInputLevel = = INPUT_MARK ) {
// Reset gap TickCounterForISR, to prepare for detection if we are in the middle of a transmission after call of resume()
irparams . TickCounterForISR = 0 ;
}
}
# if !defined(NO_LED_FEEDBACK_CODE)
if ( FeedbackLEDControl . LedFeedbackEnabled = = LED_FEEDBACK_ENABLED_FOR_RECEIVE ) {
setFeedbackLED ( tIRInputLevel = = INPUT_MARK ) ;
}
# endif
# ifdef _IR_MEASURE_TIMING
digitalWriteFast ( _IR_TIMING_TEST_PIN , LOW ) ; // 2 clock cycles
# endif
}
2021-03-07 04:18:43 +08:00
/**********************************************************************************************************************
* Stream like API
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2021-03-18 04:52:41 +08:00
/**
* Initializes the receive and feedback pin
* @ param aReceivePin The Arduino pin number , where a demodulating IR receiver is connected .
* @ param aEnableLEDFeedback if true / ENABLE_LED_FEEDBACK , then let the feedback led blink on receiving IR signal
* @ param aFeedbackLEDPin if 0 / USE_DEFAULT_FEEDBACK_LED_PIN , then take board specific FEEDBACK_LED_ON ( ) and FEEDBACK_LED_OFF ( ) functions
2021-01-17 02:50:36 +08:00
*/
2022-05-19 15:51:34 +08:00
void IRrecv : : begin ( uint_fast8_t aReceivePin , bool aEnableLEDFeedback , uint_fast8_t aFeedbackLEDPin ) {
2021-03-06 08:21:46 +08:00
2021-03-09 04:38:06 +08:00
setReceivePin ( aReceivePin ) ;
2021-12-08 07:44:48 +08:00
# if !defined(NO_LED_FEEDBACK_CODE)
2022-02-12 02:14:29 +08:00
bool tEnableLEDFeedback = DO_NOT_ENABLE_LED_FEEDBACK ;
2022-05-21 00:54:51 +08:00
if ( aEnableLEDFeedback ) {
2022-02-12 02:14:29 +08:00
tEnableLEDFeedback = LED_FEEDBACK_ENABLED_FOR_RECEIVE ;
}
setLEDFeedback ( aFeedbackLEDPin , tEnableLEDFeedback ) ;
2021-03-09 04:38:06 +08:00
# else
( void ) aEnableLEDFeedback ;
( void ) aFeedbackLEDPin ;
# endif
2021-03-06 08:21:46 +08:00
2022-06-27 07:18:44 +08:00
# if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)
2022-07-19 20:56:20 +08:00
pinModeFast ( _IR_TIMING_TEST_PIN , OUTPUT ) ;
2022-06-27 07:18:44 +08:00
# endif
2022-05-21 00:54:51 +08:00
start ( ) ;
2021-01-17 02:50:36 +08:00
}
2021-03-18 04:52:41 +08:00
/**
* Sets / changes the receiver pin number
*/
2022-05-19 15:51:34 +08:00
void IRrecv : : setReceivePin ( uint_fast8_t aReceivePinNumber ) {
2021-03-09 04:38:06 +08:00
irparams . IRReceivePin = aReceivePinNumber ;
# if defined(__AVR__)
irparams . IRReceivePinMask = digitalPinToBitMask ( aReceivePinNumber ) ;
irparams . IRReceivePinPortInputRegister = portInputRegister ( digitalPinToPort ( aReceivePinNumber ) ) ;
# endif
2022-12-23 06:12:04 +08:00
// Set pin mode once. pinModeFast makes no difference here :-(
pinMode ( aReceivePinNumber , INPUT ) ; // Seems to be at least required by ESP32
2021-03-09 04:38:06 +08:00
}
2022-11-10 07:58:54 +08:00
/**
* Sets the function to call if a protocol message has arrived
*/
void IRrecv : : registerReceiveCompleteCallback ( void ( * aReceiveCompleteCallbackFunction ) ( void ) ) {
irparams . ReceiveCompleteCallbackFunction = aReceiveCompleteCallbackFunction ;
}
2021-03-18 04:52:41 +08:00
/**
2022-12-30 01:46:09 +08:00
* Start the receiving process .
* This configures the timer and the state machine for IR reception
* and enables the receive sample timer interrupt which consumes a small amount of CPU every 50 us .
2021-03-18 04:52:41 +08:00
*/
2021-01-17 02:50:36 +08:00
void IRrecv : : start ( ) {
2022-05-21 00:54:51 +08:00
// Setup for cyclic 50 us interrupt
timerConfigForReceive ( ) ; // no interrupts enabled here!
// Initialize state machine state
resume ( ) ;
// Timer interrupt is enabled after state machine reset
2022-12-30 01:46:09 +08:00
timerEnableReceiveInterrupt ( ) ; // Enables the receive sample timer interrupt which consumes a small amount of CPU every 50 us.
2022-12-15 08:34:02 +08:00
# ifdef _IR_MEASURE_TIMING
pinModeFast ( _IR_TIMING_TEST_PIN , OUTPUT ) ;
# endif
2022-05-21 00:54:51 +08:00
}
2022-08-06 20:39:28 +08:00
/**
* Alias for start ( ) .
*/
2022-05-21 00:54:51 +08:00
void IRrecv : : enableIRIn ( ) {
start ( ) ;
2021-01-17 02:50:36 +08:00
}
2021-03-18 04:52:41 +08:00
/**
* Configures the timer and the state machine for IR reception .
2022-12-15 08:34:02 +08:00
* The tick counter value is already at 100 when decode ( ) gets true , because of the 5000 us minimal gap defined in RECORD_GAP_MICROS .
2022-08-06 20:39:28 +08:00
* @ param aMicrosecondsToAddToGapCounter To compensate for the amount of microseconds the timer was stopped / disabled .
2021-03-18 04:52:41 +08:00
*/
2021-09-28 05:46:13 +08:00
void IRrecv : : start ( uint32_t aMicrosecondsToAddToGapCounter ) {
2021-03-06 08:21:46 +08:00
irparams . TickCounterForISR + = aMicrosecondsToAddToGapCounter / MICROS_PER_TICK ;
2022-12-15 08:34:02 +08:00
start ( ) ;
}
void IRrecv : : startWithTicksToAdd ( uint16_t aTicksToAddToGapCounter ) {
irparams . TickCounterForISR + = aTicksToAddToGapCounter ;
start ( ) ;
2021-02-21 07:17:28 +08:00
}
2021-03-18 04:52:41 +08:00
/**
2023-02-24 09:40:21 +08:00
* Restarts receiver after send . Is a NOP if sending does not require a timer .
2021-03-18 04:52:41 +08:00
*/
2022-05-21 00:54:51 +08:00
void IRrecv : : restartAfterSend ( ) {
# if defined(SEND_PWM_BY_TIMER) && !defined(SEND_PWM_DOES_NOT_USE_RECEIVE_TIMER)
start ( ) ;
# endif
2021-01-17 02:50:36 +08:00
}
2021-03-18 04:52:41 +08:00
/**
* Disables the timer for IR reception .
*/
2022-05-21 00:54:51 +08:00
void IRrecv : : stop ( ) {
2022-12-23 22:24:10 +08:00
timerDisableReceiveInterrupt ( ) ;
2021-01-17 02:50:36 +08:00
}
2022-08-06 20:39:28 +08:00
/**
* Alias for stop ( ) .
*/
2021-01-17 02:50:36 +08:00
void IRrecv : : disableIRIn ( ) {
2022-05-21 00:54:51 +08:00
stop ( ) ;
}
2022-08-06 20:39:28 +08:00
/**
* Alias for stop ( ) .
*/
2022-05-21 00:54:51 +08:00
void IRrecv : : end ( ) {
stop ( ) ;
2021-01-17 02:50:36 +08:00
}
/**
* Returns status of reception
* @ return true if no reception is on - going .
*/
bool IRrecv : : isIdle ( ) {
2021-03-06 08:21:46 +08:00
return ( irparams . StateForISR = = IR_REC_STATE_IDLE | | irparams . StateForISR = = IR_REC_STATE_STOP ) ? true : false ;
2021-01-17 02:50:36 +08:00
}
/**
2022-12-30 01:46:09 +08:00
* Restart the ISR ( Interrupt Service Routine ) state machine , to enable receiving of the next IR frame
2021-01-17 02:50:36 +08:00
*/
void IRrecv : : resume ( ) {
2021-01-24 08:13:48 +08:00
// check allows to call resume at arbitrary places or more than once
2021-03-06 08:21:46 +08:00
if ( irparams . StateForISR = = IR_REC_STATE_STOP ) {
irparams . StateForISR = IR_REC_STATE_IDLE ;
2021-01-24 08:13:48 +08:00
}
2021-01-17 02:50:36 +08:00
}
2021-03-07 04:18:43 +08:00
/**
2021-01-16 01:45:35 +08:00
* Is internally called by decode before calling decoders .
* Must be used to setup data , if you call decoders manually .
*/
2020-12-31 11:51:54 +08:00
void IRrecv : : initDecodedIRData ( ) {
2021-03-06 08:21:46 +08:00
if ( irparams . OverflowFlag ) {
2020-12-31 11:51:54 +08:00
decodedIRData . flags = IRDATA_FLAGS_WAS_OVERFLOW ;
2022-11-08 07:36:44 +08:00
# if defined(LOCAL_DEBUG)
Serial . print ( F ( " Overflow happened, try to increase the \" RAW_BUFFER_LENGTH \" value of " ) ) ;
Serial . print ( RAW_BUFFER_LENGTH ) ;
Serial . println ( F ( " with #define RAW_BUFFER_LENGTH=<biggerValue> " ) ) ;
# endif
2021-01-17 02:50:36 +08:00
2020-12-31 11:51:54 +08:00
} else {
decodedIRData . flags = IRDATA_FLAGS_EMPTY ;
2023-01-02 22:19:42 +08:00
// save last protocol, command and address for repeat handling (where they are compared or copied back :-))
2021-04-29 23:33:05 +08:00
lastDecodedProtocol = decodedIRData . protocol ; // repeat patterns can be equal between protocols (e.g. NEC and LG), so we must keep the original one
2021-01-17 02:50:36 +08:00
lastDecodedCommand = decodedIRData . command ;
lastDecodedAddress = decodedIRData . address ;
}
2021-04-29 23:33:05 +08:00
decodedIRData . protocol = UNKNOWN ;
2021-01-17 02:50:36 +08:00
decodedIRData . command = 0 ;
decodedIRData . address = 0 ;
decodedIRData . decodedRawData = 0 ;
decodedIRData . numberOfBits = 0 ;
}
/**
2021-03-18 04:52:41 +08:00
* Returns true if IR receiver data is available .
2021-01-17 02:50:36 +08:00
*/
bool IRrecv : : available ( ) {
2021-03-06 08:21:46 +08:00
return ( irparams . StateForISR = = IR_REC_STATE_STOP ) ;
2021-01-17 02:50:36 +08:00
}
/**
2021-03-18 04:52:41 +08:00
* If IR receiver data is available , returns pointer to IrReceiver . decodedIRData , else NULL .
2021-01-17 02:50:36 +08:00
*/
IRData * IRrecv : : read ( ) {
2021-03-06 08:21:46 +08:00
if ( irparams . StateForISR ! = IR_REC_STATE_STOP ) {
2021-01-17 02:50:36 +08:00
return NULL ;
}
if ( decode ( ) ) {
return & decodedIRData ;
} else {
return NULL ;
2020-12-31 11:51:54 +08:00
}
}
2021-03-18 04:52:41 +08:00
/**
* The main decode function , attempts to decode the recently receive IR signal .
* The set of decoders used is determined by active definitions of the DECODE_ < PROTOCOL > macros .
2022-12-30 01:46:09 +08:00
* Results of decoding are stored in IrReceiver . decodedIRData . * like e . g . IrReceiver . decodedIRData . command .
* @ return false if no IR receiver data available , true if data available .
2021-03-18 04:52:41 +08:00
*/
2020-08-19 17:03:07 +08:00
bool IRrecv : : decode ( ) {
2021-03-06 08:21:46 +08:00
if ( irparams . StateForISR ! = IR_REC_STATE_STOP ) {
2020-08-19 17:03:07 +08:00
return false ;
}
2021-01-17 02:50:36 +08:00
initDecodedIRData ( ) ; // sets IRDATA_FLAGS_WAS_OVERFLOW
if ( decodedIRData . flags & IRDATA_FLAGS_WAS_OVERFLOW ) {
/*
2021-03-06 08:21:46 +08:00
* Set OverflowFlag flag and return true here , to let the loop call resume or print raw data .
2021-01-17 02:50:36 +08:00
*/
decodedIRData . protocol = UNKNOWN ;
return true ;
}
2020-09-16 16:29:57 +08:00
2021-03-02 22:25:39 +08:00
# if defined(DECODE_NEC)
2022-05-19 15:51:34 +08:00
IR_TRACE_PRINTLN ( F ( " Attempting NEC decode " ) ) ;
2020-12-31 11:51:54 +08:00
if ( decodeNEC ( ) ) {
2020-08-20 04:39:41 +08:00
return true ;
}
# endif
2021-04-08 13:59:45 +08:00
# if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO)
2022-05-19 15:51:34 +08:00
IR_TRACE_PRINTLN ( F ( " Attempting Panasonic/Kaseikyo decode " ) ) ;
2020-12-31 11:51:54 +08:00
if ( decodeKaseikyo ( ) ) {
2020-08-19 17:03:07 +08:00
return true ;
}
# endif
2021-03-02 22:25:39 +08:00
# if defined(DECODE_DENON)
2022-05-19 15:51:34 +08:00
IR_TRACE_PRINTLN ( F ( " Attempting Denon/Sharp decode " ) ) ;
2020-12-31 11:51:54 +08:00
if ( decodeDenon ( ) ) {
2020-08-19 17:03:07 +08:00
return true ;
}
# endif
2021-03-02 22:25:39 +08:00
# if defined(DECODE_SONY)
2022-05-19 15:51:34 +08:00
IR_TRACE_PRINTLN ( F ( " Attempting Sony decode " ) ) ;
2020-08-19 17:03:07 +08:00
if ( decodeSony ( ) ) {
return true ;
}
# endif
2021-03-02 22:25:39 +08:00
# if defined(DECODE_RC5)
2022-05-19 15:51:34 +08:00
IR_TRACE_PRINTLN ( F ( " Attempting RC5 decode " ) ) ;
2020-08-19 17:03:07 +08:00
if ( decodeRC5 ( ) ) {
return true ;
}
# endif
2021-03-02 22:25:39 +08:00
# if defined(DECODE_RC6)
2022-05-19 15:51:34 +08:00
IR_TRACE_PRINTLN ( F ( " Attempting RC6 decode " ) ) ;
2020-08-19 17:03:07 +08:00
if ( decodeRC6 ( ) ) {
return true ;
}
# endif
2021-03-02 22:25:39 +08:00
# if defined(DECODE_LG)
2022-05-19 15:51:34 +08:00
IR_TRACE_PRINTLN ( F ( " Attempting LG decode " ) ) ;
2020-08-19 17:03:07 +08:00
if ( decodeLG ( ) ) {
return true ;
}
# endif
2021-03-02 22:25:39 +08:00
# if defined(DECODE_JVC)
2022-05-19 15:51:34 +08:00
IR_TRACE_PRINTLN ( F ( " Attempting JVC decode " ) ) ;
2020-08-19 17:03:07 +08:00
if ( decodeJVC ( ) ) {
return true ;
}
# endif
2021-03-02 22:25:39 +08:00
# if defined(DECODE_SAMSUNG)
2022-05-19 15:51:34 +08:00
IR_TRACE_PRINTLN ( F ( " Attempting Samsung decode " ) ) ;
2021-01-04 09:54:10 +08:00
if ( decodeSamsung ( ) ) {
return true ;
}
# endif
/*
* Start of the exotic protocols
*/
2022-10-02 16:00:58 +08:00
# if defined(DECODE_BEO)
IR_TRACE_PRINTLN ( F ( " Attempting Bang & Olufsen decode " ) ) ;
if ( decodeBangOlufsen ( ) ) {
return true ;
}
# endif
2023-02-24 09:40:21 +08:00
# if defined(DECODE_FAST)
IR_TRACE_PRINTLN ( F ( " Attempting FAST decode " ) ) ;
if ( decodeFAST ( ) ) {
return true ;
}
# endif
2021-03-02 22:25:39 +08:00
# if defined(DECODE_WHYNTER)
2022-05-19 15:51:34 +08:00
IR_TRACE_PRINTLN ( F ( " Attempting Whynter decode " ) ) ;
2020-08-19 17:03:07 +08:00
if ( decodeWhynter ( ) ) {
return true ;
}
# endif
2021-03-02 22:25:39 +08:00
# if defined(DECODE_LEGO_PF)
2022-05-19 15:51:34 +08:00
IR_TRACE_PRINTLN ( F ( " Attempting Lego Power Functions " ) ) ;
2020-08-19 17:03:07 +08:00
if ( decodeLegoPowerFunctions ( ) ) {
return true ;
}
# endif
2021-03-02 22:25:39 +08:00
# if defined(DECODE_BOSEWAVE)
2022-05-19 15:51:34 +08:00
IR_TRACE_PRINTLN ( F ( " Attempting Bosewave decode " ) ) ;
2021-01-02 09:05:20 +08:00
if ( decodeBoseWave ( ) ) {
return true ;
}
# endif
2021-03-02 22:25:39 +08:00
# if defined(DECODE_MAGIQUEST)
2022-05-19 15:51:34 +08:00
IR_TRACE_PRINTLN ( F ( " Attempting MagiQuest decode " ) ) ;
2020-08-19 17:03:07 +08:00
if ( decodeMagiQuest ( ) ) {
return true ;
}
# endif
2021-04-28 00:30:41 +08:00
/*
2022-06-27 07:18:44 +08:00
* Try the universal decoder for pulse distance protocols
2021-04-28 00:30:41 +08:00
*/
2022-11-08 07:36:44 +08:00
# if defined(DECODE_DISTANCE_WIDTH)
IR_TRACE_PRINTLN ( F ( " Attempting universal Distance Width decode " ) ) ;
2022-11-09 21:01:52 +08:00
if ( decodeDistanceWidth ( ) ) {
2021-04-28 00:30:41 +08:00
return true ;
}
# endif
2021-01-04 09:54:10 +08:00
/*
* Last resort is the universal hash decode which always return true
*/
2021-03-02 22:25:39 +08:00
# if defined(DECODE_HASH)
2022-05-19 15:51:34 +08:00
IR_TRACE_PRINTLN ( F ( " Hash decode " ) ) ;
2020-08-19 17:03:07 +08:00
// decodeHash returns a hash on any input.
// Thus, it needs to be last in the list.
// If you add any decodes, add them before this.
if ( decodeHash ( ) ) {
return true ;
}
# endif
2021-01-04 09:54:10 +08:00
/*
2021-02-19 06:43:11 +08:00
* Return true here , to let the loop decide to call resume or to print raw data .
2021-01-04 09:54:10 +08:00
*/
2021-02-19 06:43:11 +08:00
return true ;
2020-08-19 17:03:07 +08:00
}
2021-03-07 04:18:43 +08:00
/**********************************************************************************************************************
* Common decode functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2021-03-18 04:52:41 +08:00
/**
2022-11-10 05:49:55 +08:00
* Decode pulse distance width protocols .
*
* We can have the following protocol timings
* Pulse distance : Pulses / marks are constant , pause / spaces have different length , like NEC .
* Pulse width : Pulses / marks have different length , pause / spaces are constant , like Sony .
* Pulse distance width : Pulses / marks and pause / spaces have different length , often the bit length is constant , like MagiQuest .
* Pulse distance width can be decoded like pulse width decoder , if this decoder does not check the length of pause / spaces .
2020-12-31 11:51:54 +08:00
*
2021-03-18 04:52:41 +08:00
* Input is IrReceiver . decodedIRData . rawDataPtr - > rawbuf [ ]
* Output is IrReceiver . decodedIRData . decodedRawData
*
2022-11-22 19:28:10 +08:00
* Assume pulse distance if aOneMarkMicros = = aZeroMarkMicros
2022-11-10 05:49:55 +08:00
*
2022-12-30 01:46:09 +08:00
* @ param aNumberOfBits Number of bits to decode from decodedIRData . rawDataPtr - > rawbuf [ ] array .
* @ param aStartOffset Offset in decodedIRData . rawDataPtr - > rawbuf [ ] to start decoding . Must point to a mark .
2022-11-10 05:49:55 +08:00
* @ param aOneMarkMicros Taken as constant BitMarkMicros for pulse distance .
* @ param aZeroMarkMicros Not required if DECODE_STRICT_CHECKS is not defined .
* @ param aOneSpaceMicros Taken as ( constant ) BitSpaceMicros for pulse width .
* @ param aZeroSpaceMicros Not required if DECODE_STRICT_CHECKS is not defined .
2022-12-30 01:46:09 +08:00
* @ param aMSBfirst If true send Most Significant Bit first , else send Least Significant Bit ( lowest bit ) first .
2022-11-10 05:49:55 +08:00
* @ return true If decoding was successful
2020-12-31 11:51:54 +08:00
*/
2023-02-24 09:40:21 +08:00
bool IRrecv : : decodePulseDistanceWidthData ( uint_fast8_t aNumberOfBits , uint_fast8_t aStartOffset , uint16_t aOneMarkMicros ,
uint16_t aZeroMarkMicros , uint16_t aOneSpaceMicros , uint16_t aZeroSpaceMicros , bool aMSBfirst ) {
2021-01-14 22:28:34 +08:00
2023-02-24 09:40:21 +08:00
auto * tRawBufPointer = & decodedIRData . rawDataPtr - > rawbuf [ aStartOffset ] ;
2020-12-31 11:51:54 +08:00
2022-11-10 05:49:55 +08:00
bool isPulseDistanceProtocol = ( aOneMarkMicros = = aZeroMarkMicros ) ; // If true, we have a constant mark -> pulse distance protocol
2022-11-22 19:28:10 +08:00
IRRawDataType tDecodedData = 0 ; // For MSB first tDecodedData is shifted left each loop
IRRawDataType tMask = 1UL ; // Mask is only used for LSB first
2022-11-09 21:01:52 +08:00
for ( uint_fast8_t i = aNumberOfBits ; i > 0 ; i - - ) {
// get one mark and space pair
2022-11-10 05:49:55 +08:00
unsigned int tMarkTicks ;
unsigned int tSpaceTicks ;
if ( isPulseDistanceProtocol ) {
/*
* Pulse distance here , it is not required to check constant mark duration ( aOneMarkMicros ) and zero space duration .
*/
# if defined DECODE_STRICT_CHECKS
tMarkTicks = * tRawBufPointer + + ;
# else
( void ) aZeroSpaceMicros ;
tRawBufPointer + + ;
# endif
tSpaceTicks = * tRawBufPointer + + ; // maybe buffer overflow for last bit, but we do not evaluate this value :-)
# if defined DECODE_STRICT_CHECKS
// Check for constant length mark
if ( ! matchMark ( tMarkTicks , aOneMarkMicros ) ) {
# if defined(LOCAL_DEBUG)
Serial . print ( F ( " Mark= " ) ) ;
Serial . print ( tMarkTicks * MICROS_PER_TICK ) ;
Serial . print ( F ( " is not " ) ) ;
Serial . print ( aOneMarkMicros ) ;
Serial . print ( F ( " . Index= " ) ) ;
Serial . print ( aNumberOfBits - i ) ;
Serial . print ( ' ' ) ;
# endif
return false ;
}
# endif
} else {
/*
* Pulse width here , it is not required to check ( constant ) space duration and zero mark duration .
*/
tMarkTicks = * tRawBufPointer + + ;
2022-11-09 21:01:52 +08:00
# if defined DECODE_STRICT_CHECKS
2022-11-10 05:49:55 +08:00
tSpaceTicks = * tRawBufPointer + + ; // maybe buffer overflow for last bit, but we do not evaluate this value :-)
2022-11-09 21:01:52 +08:00
# else
( void ) aZeroMarkMicros ;
2022-11-10 05:49:55 +08:00
( void ) aZeroSpaceMicros ;
2022-11-09 21:01:52 +08:00
tRawBufPointer + + ;
2022-11-08 07:36:44 +08:00
# endif
2022-11-10 05:49:55 +08:00
}
2020-12-31 11:51:54 +08:00
2022-11-09 21:01:52 +08:00
if ( aMSBfirst ) {
tDecodedData < < = 1 ;
2020-12-31 11:51:54 +08:00
}
2023-02-24 09:40:21 +08:00
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
2022-11-10 05:49:55 +08:00
bool tBitValue ;
if ( isPulseDistanceProtocol ) {
// Check for variable length space indicating a 1 or 0
2023-02-24 09:40:21 +08:00
tBitValue = matchSpace ( tSpaceTicks , aOneSpaceMicros ) ; // tSpaceTicks is initialized here, even if some compiler are complaining!
2022-11-10 05:49:55 +08:00
} else {
// Check for variable length mark indicating a 1 or 0
2023-02-24 09:40:21 +08:00
tBitValue = matchMark ( tMarkTicks , aOneMarkMicros ) ; // tMarkTicks is initialized here, even if some compiler are complaining!
2022-11-10 05:49:55 +08:00
}
2023-02-24 09:40:21 +08:00
# pragma GCC diagnostic pop
2022-11-10 05:49:55 +08:00
if ( tBitValue ) {
2022-11-09 21:01:52 +08:00
// It's a 1 -> set the bit
if ( aMSBfirst ) {
tDecodedData | = 1 ;
2020-12-31 11:51:54 +08:00
} else {
2022-11-09 21:01:52 +08:00
tDecodedData | = tMask ;
}
IR_TRACE_PRINTLN ( ' 1 ' ) ;
} else {
2022-11-10 05:49:55 +08:00
# if defined DECODE_STRICT_CHECKS
/*
* Additionally check length of length parameter which determine a zero
*/
if ( isPulseDistanceProtocol ) {
if ( ! matchSpace ( tSpaceTicks , aZeroSpaceMicros ) ) {
2022-11-09 21:01:52 +08:00
# if defined(LOCAL_DEBUG)
2022-11-10 05:49:55 +08:00
Serial . print ( F ( " Space= " ) ) ;
Serial . print ( tSpaceTicks * MICROS_PER_TICK ) ;
Serial . print ( F ( " is not " ) ) ;
Serial . print ( aOneSpaceMicros ) ;
Serial . print ( F ( " or " ) ) ;
Serial . print ( aZeroSpaceMicros ) ;
Serial . print ( F ( " . Index= " ) ) ;
Serial . print ( aNumberOfBits - i ) ;
Serial . print ( ' ' ) ;
2022-11-09 21:01:52 +08:00
# endif
2022-11-10 05:49:55 +08:00
return false ;
}
} else {
if ( ! matchMark ( tMarkTicks , aZeroMarkMicros ) ) {
# if defined(LOCAL_DEBUG)
Serial . print ( F ( " Mark= " ) ) ;
Serial . print ( tMarkTicks * MICROS_PER_TICK ) ;
Serial . print ( F ( " is not " ) ) ;
Serial . print ( aOneMarkMicros ) ;
Serial . print ( F ( " or " ) ) ;
Serial . print ( aZeroMarkMicros ) ;
Serial . print ( F ( " . Index= " ) ) ;
Serial . print ( aNumberOfBits - i ) ;
Serial . print ( ' ' ) ;
# endif
return false ;
}
}
2022-11-09 21:01:52 +08:00
# endif
2022-11-10 05:49:55 +08:00
// do not set the bit
IR_TRACE_PRINTLN ( ' 0 ' ) ;
2022-11-09 21:01:52 +08:00
}
# if defined DECODE_STRICT_CHECKS
// If we have no stop bit, assume that last space, which is not recorded, is correct, since we can not check it
2022-11-10 05:49:55 +08:00
if ( aZeroSpaceMicros = = aOneSpaceMicros
& & tRawBufPointer < & decodedIRData . rawDataPtr - > rawbuf [ decodedIRData . rawDataPtr - > rawlen ] ) {
// Check for constant length space (of pulse width protocol) here
if ( ! matchSpace ( tSpaceTicks , aOneSpaceMicros ) ) {
2022-11-09 21:01:52 +08:00
# if defined(LOCAL_DEBUG)
Serial . print ( F ( " Space= " ) ) ;
Serial . print ( tSpaceTicks * MICROS_PER_TICK ) ;
2022-11-08 07:36:44 +08:00
Serial . print ( F ( " is not " ) ) ;
2022-11-10 05:49:55 +08:00
Serial . print ( aOneSpaceMicros ) ;
2022-11-08 07:36:44 +08:00
Serial . print ( F ( " . Index= " ) ) ;
Serial . print ( aNumberOfBits - i ) ;
Serial . print ( ' ' ) ;
2022-11-09 21:01:52 +08:00
# endif
2020-12-31 11:51:54 +08:00
return false ;
}
}
2022-11-09 21:01:52 +08:00
# endif
tMask < < = 1 ;
2020-12-31 11:51:54 +08:00
}
2021-01-17 02:50:36 +08:00
decodedIRData . decodedRawData = tDecodedData ;
2020-12-31 11:51:54 +08:00
return true ;
}
2022-08-31 19:25:29 +08:00
/**
2022-11-10 05:49:55 +08:00
* Decode pulse distance protocols for PulseDistanceWidthProtocolConstants .
2022-08-31 19:25:29 +08:00
* @ return true if decoding was successful
*/
2022-11-10 05:49:55 +08:00
bool IRrecv : : decodePulseDistanceWidthData ( PulseDistanceWidthProtocolConstants * aProtocolConstants , uint_fast8_t aNumberOfBits ,
2022-08-31 19:25:29 +08:00
uint_fast8_t aStartOffset ) {
2023-02-24 09:40:21 +08:00
return decodePulseDistanceWidthData ( aNumberOfBits , aStartOffset , aProtocolConstants - > DistanceWidthTimingInfo . OneMarkMicros ,
aProtocolConstants - > DistanceWidthTimingInfo . ZeroMarkMicros , aProtocolConstants - > DistanceWidthTimingInfo . OneSpaceMicros ,
aProtocolConstants - > DistanceWidthTimingInfo . ZeroSpaceMicros , aProtocolConstants - > Flags ) ;
2022-08-31 19:25:29 +08:00
}
2021-03-19 05:01:39 +08:00
/*
* Static variables for the getBiphaselevel function
*/
2022-05-19 15:51:34 +08:00
uint_fast8_t sBiphaseDecodeRawbuffOffset ; // Index into raw timing array
2023-02-24 09:40:21 +08:00
uint16_t sBiphaseCurrentTimingIntervals ; // 1, 2 or 3. Number of aBiphaseTimeUnit intervals of the current rawbuf[sBiphaseDecodeRawbuffOffset] timing.
2022-08-31 20:07:41 +08:00
uint_fast8_t sBiphaseUsedTimingIntervals ; // Number of already used intervals of sCurrentTimingIntervals.
2023-02-24 09:40:21 +08:00
uint16_t sBiphaseTimeUnit ;
2021-03-19 05:01:39 +08:00
2023-02-24 09:40:21 +08:00
void IRrecv : : initBiphaselevel ( uint_fast8_t aRCDecodeRawbuffOffset , uint16_t aBiphaseTimeUnit ) {
2021-03-19 05:01:39 +08:00
sBiphaseDecodeRawbuffOffset = aRCDecodeRawbuffOffset ;
sBiphaseTimeUnit = aBiphaseTimeUnit ;
2022-08-31 20:07:41 +08:00
sBiphaseUsedTimingIntervals = 0 ;
2021-03-19 05:01:39 +08:00
}
2021-03-18 04:52:41 +08:00
/**
2021-03-19 05:01:39 +08:00
* Gets the level of one time interval ( aBiphaseTimeUnit ) at a time from the raw buffer .
* The RC5 / 6 decoding is easier if the data is broken into time intervals .
* E . g . if the buffer has mark for 2 time intervals and space for 1 ,
* successive calls to getBiphaselevel will return 1 , 1 , 0.
2021-03-18 04:52:41 +08:00
*
2021-03-19 05:01:39 +08:00
* _ _ _ _ _ _ _ _ _ _ _ _ _
* _____ | | _ | | _ | | _ | | _ | | _ | | _ | | _ | | _ | | _ | | _ | | _ | | _ | |
* ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ Significant clock edge
* _ _ _ ___ _ ___ ___ _ - Mark
* Data _____ | | ___ | | _ | | _ | | _ | | ___ | | ___ | | _ | | - Data starts with a mark - > space bit
* 1 0 0 0 1 1 0 1 0 1 1 - Space
* A mark to space at a significant clock edge results in a 1
* A space to mark at a significant clock edge results in a 0 ( for RC6 )
* Returns current level [ MARK or SPACE ] or - 1 for error ( measured time interval is not a multiple of sBiphaseTimeUnit ) .
2021-01-14 10:12:57 +08:00
*/
2022-05-19 15:51:34 +08:00
uint_fast8_t IRrecv : : getBiphaselevel ( ) {
uint_fast8_t tLevelOfCurrentInterval ; // 0 (SPACE) or 1 (MARK)
2021-01-14 10:12:57 +08:00
2021-03-19 05:01:39 +08:00
if ( sBiphaseDecodeRawbuffOffset > = decodedIRData . rawDataPtr - > rawlen ) {
return SPACE ; // After end of recorded buffer, assume space.
}
2021-01-14 10:12:57 +08:00
2021-03-19 05:01:39 +08:00
tLevelOfCurrentInterval = ( sBiphaseDecodeRawbuffOffset ) & 1 ; // on odd rawbuf offsets we have mark timings
2021-01-14 10:12:57 +08:00
2021-03-19 05:01:39 +08:00
/*
* Setup data if sUsedTimingIntervals is 0
*/
2022-08-31 20:07:41 +08:00
if ( sBiphaseUsedTimingIntervals = = 0 ) {
2023-02-24 09:40:21 +08:00
uint16_t tCurrentTimingWith = decodedIRData . rawDataPtr - > rawbuf [ sBiphaseDecodeRawbuffOffset ] ;
uint16_t tMarkExcessCorrection = ( tLevelOfCurrentInterval = = MARK ) ? MARK_EXCESS_MICROS : - MARK_EXCESS_MICROS ;
2021-03-19 05:01:39 +08:00
2023-02-24 09:40:21 +08:00
if ( matchTicks ( tCurrentTimingWith , sBiphaseTimeUnit + tMarkExcessCorrection ) ) {
2022-08-31 20:07:41 +08:00
sBiphaseCurrentTimingIntervals = 1 ;
2021-03-19 05:01:39 +08:00
} else if ( matchTicks ( tCurrentTimingWith , ( 2 * sBiphaseTimeUnit ) + tMarkExcessCorrection ) ) {
2022-08-31 20:07:41 +08:00
sBiphaseCurrentTimingIntervals = 2 ;
2021-03-19 05:01:39 +08:00
} else if ( matchTicks ( tCurrentTimingWith , ( 3 * sBiphaseTimeUnit ) + tMarkExcessCorrection ) ) {
2022-08-31 20:07:41 +08:00
sBiphaseCurrentTimingIntervals = 3 ;
2021-01-14 10:12:57 +08:00
} else {
2021-03-19 05:01:39 +08:00
return - 1 ;
2021-01-14 10:12:57 +08:00
}
2021-03-19 05:01:39 +08:00
}
2021-01-14 10:12:57 +08:00
2022-08-31 19:25:29 +08:00
// We use another interval from tCurrentTimingIntervals
2022-08-31 20:07:41 +08:00
sBiphaseUsedTimingIntervals + + ;
2021-03-19 05:01:39 +08:00
2022-08-31 19:25:29 +08:00
// keep track of current timing offset
2022-08-31 20:07:41 +08:00
if ( sBiphaseUsedTimingIntervals > = sBiphaseCurrentTimingIntervals ) {
2021-03-19 05:01:39 +08:00
// we have used all intervals of current timing, switch to next timing value
2022-08-31 20:07:41 +08:00
sBiphaseUsedTimingIntervals = 0 ;
2021-03-19 05:01:39 +08:00
sBiphaseDecodeRawbuffOffset + + ;
2021-01-14 10:12:57 +08:00
}
2021-03-19 05:01:39 +08:00
2021-11-29 20:41:03 +08:00
IR_TRACE_PRINTLN ( tLevelOfCurrentInterval ) ;
2021-03-19 05:01:39 +08:00
return tLevelOfCurrentInterval ;
2021-01-14 10:12:57 +08:00
}
2021-01-18 01:07:49 +08:00
2021-03-02 22:25:39 +08:00
# if defined(DECODE_HASH)
2021-03-07 04:18:43 +08:00
/**********************************************************************************************************************
* Internal Hash decode function
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2021-03-18 04:52:41 +08:00
/**
2022-03-24 16:06:00 +08:00
* Compare two ( tick ) values for Hash decoder
2021-03-07 04:18:43 +08:00
* Use a tolerance of 20 % to enable e . g . 500 and 600 ( NEC timing ) to be equal
2021-03-18 04:52:41 +08:00
* @ return 0 if newval is shorter , 1 if newval is equal , and 2 if newval is longer
2021-03-07 04:18:43 +08:00
*/
2023-02-24 09:40:21 +08:00
uint_fast8_t IRrecv : : compare ( uint16_t oldval , uint16_t newval ) {
2021-03-07 04:18:43 +08:00
if ( newval * 10 < oldval * 8 ) {
return 0 ;
}
if ( oldval * 10 < newval * 8 ) {
return 2 ;
}
return 1 ;
}
2021-03-18 04:52:41 +08:00
# define FNV_PRIME_32 16777619 ///< used for decodeHash()
# define FNV_BASIS_32 2166136261 ///< used for decodeHash()
2021-03-09 04:38:06 +08:00
/**
2021-03-18 04:52:41 +08:00
* decodeHash - decode an arbitrary IR code .
2021-03-09 04:38:06 +08:00
* Instead of decoding using a standard encoding scheme
* ( e . g . Sony , NEC , RC5 ) , the code is hashed to a 32 - bit value .
*
* The algorithm : look at the sequence of MARK signals , and see if each one
* is shorter ( 0 ) , the same length ( 1 ) , or longer ( 2 ) than the previous .
* Do the same with the SPACE signals . Hash the resulting sequence of 0 ' s ,
* 1 ' s , and 2 ' s to a 32 - bit value . This will give a unique value for each
* different code ( probably ) , for most code systems .
*
* Use FNV hash algorithm : http : //isthe.com/chongo/tech/comp/fnv/#FNV-param
* Converts the raw code values into a 32 - bit hash code .
* Hopefully this code is unique for each button .
* This isn ' t a " real " decoding , just an arbitrary value .
*
2021-11-03 13:57:27 +08:00
* see : http : //www.righto.com/2010/01/using-arbitrary-remotes-with-arduino.html
2021-03-18 04:52:41 +08:00
*/
2020-08-19 17:03:07 +08:00
bool IRrecv : : decodeHash ( ) {
2021-12-08 21:14:04 +08:00
unsigned long hash = FNV_BASIS_32 ; // the result is the same no matter if we use a long or unsigned long variable
2020-08-19 17:03:07 +08:00
2020-09-16 16:29:57 +08:00
// Require at least 6 samples to prevent triggering on noise
2021-01-17 02:50:36 +08:00
if ( decodedIRData . rawDataPtr - > rawlen < 6 ) {
2020-08-19 17:03:07 +08:00
return false ;
}
2022-03-30 17:55:04 +08:00
# if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR
2022-05-19 15:51:34 +08:00
uint_fast8_t i ;
2021-09-28 05:46:13 +08:00
# else
2022-05-19 15:51:34 +08:00
unsigned int i ;
2021-09-28 05:46:13 +08:00
# endif
for ( i = 1 ; ( i + 2 ) < decodedIRData . rawDataPtr - > rawlen ; i + + ) {
2022-05-19 15:51:34 +08:00
uint_fast8_t value = compare ( decodedIRData . rawDataPtr - > rawbuf [ i ] , decodedIRData . rawDataPtr - > rawbuf [ i + 2 ] ) ;
2021-01-14 22:28:34 +08:00
// Add value into the hash
hash = ( hash * FNV_PRIME_32 ) ^ value ;
}
2021-01-17 02:50:36 +08:00
decodedIRData . decodedRawData = hash ;
2021-01-14 22:28:34 +08:00
decodedIRData . numberOfBits = 32 ;
decodedIRData . protocol = UNKNOWN ;
return true ;
}
2021-04-08 13:59:45 +08:00
bool IRrecv : : decodeHashOld ( decode_results * aResults ) {
2021-12-08 21:14:04 +08:00
unsigned long hash = FNV_BASIS_32 ;
2021-01-14 22:28:34 +08:00
// Require at least 6 samples to prevent triggering on noise
2021-04-08 13:59:45 +08:00
if ( aResults - > rawlen < 6 ) {
2021-01-14 22:28:34 +08:00
return false ;
}
2022-07-12 17:46:04 +08:00
for ( uint8_t i = 3 ; i < aResults - > rawlen ; i + + ) {
uint_fast8_t value = compare ( aResults - > rawbuf [ i - 2 ] , aResults - > rawbuf [ i ] ) ;
2020-08-19 17:03:07 +08:00
// Add value into the hash
hash = ( hash * FNV_PRIME_32 ) ^ value ;
}
2021-04-08 13:59:45 +08:00
aResults - > value = hash ;
aResults - > bits = 32 ;
aResults - > decode_type = UNKNOWN ;
2020-12-31 11:51:54 +08:00
decodedIRData . protocol = UNKNOWN ;
2020-08-19 17:03:07 +08:00
return true ;
}
2021-01-18 01:07:49 +08:00
# endif // DECODE_HASH
2020-09-16 16:29:57 +08:00
2021-03-07 04:18:43 +08:00
/**********************************************************************************************************************
* Match functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2022-08-31 19:25:29 +08:00
/*
* returns true if values do match
*/
2022-11-10 05:49:55 +08:00
bool IRrecv : : checkHeader ( PulseDistanceWidthProtocolConstants * aProtocolConstants ) {
2022-08-31 19:25:29 +08:00
// Check header "mark" and "space"
2023-02-24 09:40:21 +08:00
if ( ! matchMark ( decodedIRData . rawDataPtr - > rawbuf [ 1 ] , aProtocolConstants - > DistanceWidthTimingInfo . HeaderMarkMicros ) ) {
2022-11-09 21:01:52 +08:00
# if defined(LOCAL_TRACE)
2022-11-08 07:36:44 +08:00
Serial . print ( : : getProtocolString ( aProtocolConstants - > ProtocolIndex ) ) ;
Serial . println ( F ( " : Header mark length is wrong " ) ) ;
# endif
2022-08-31 19:25:29 +08:00
return false ;
}
2023-02-24 09:40:21 +08:00
if ( ! matchSpace ( decodedIRData . rawDataPtr - > rawbuf [ 2 ] , aProtocolConstants - > DistanceWidthTimingInfo . HeaderSpaceMicros ) ) {
2022-11-09 21:01:52 +08:00
# if defined(LOCAL_TRACE)
2022-11-08 07:36:44 +08:00
Serial . print ( : : getProtocolString ( aProtocolConstants - > ProtocolIndex ) ) ;
Serial . println ( F ( " : Header space length is wrong " ) ) ;
# endif
2022-08-31 19:25:29 +08:00
return false ;
}
return true ;
}
2023-01-02 22:19:42 +08:00
/*
* Do not check for same address and command , because it is almost not possible to press 2 different buttons on the remote within around 100 ms .
* And if really required , it can be enabled here , or done manually in user program .
* And we have still no RC6 toggle bit check for detecting a second press on the same button .
*/
2023-02-24 09:40:21 +08:00
void IRrecv : : checkForRepeatSpaceTicksAndSetFlag ( uint16_t aMaximumRepeatSpaceTicks ) {
2023-01-02 22:19:42 +08:00
if ( decodedIRData . rawDataPtr - > rawbuf [ 0 ] < aMaximumRepeatSpaceTicks
# if defined(ENABLE_FULL_REPEAT_CHECK)
& & decodedIRData . address = = lastDecodedAddress & & decodedIRData . command = = lastDecodedCommand /* requires around 85 bytes program space */
# endif
) {
2022-08-31 20:07:41 +08:00
decodedIRData . flags | = IRDATA_FLAGS_IS_REPEAT ;
}
}
2021-03-18 04:52:41 +08:00
/**
2021-03-07 04:18:43 +08:00
* Match function without compensating for marks exceeded or spaces shortened by demodulator hardware
* Currently not used
*/
2023-02-24 09:40:21 +08:00
bool matchTicks ( uint16_t aMeasuredTicks , uint16_t aMatchValueMicros ) {
2022-11-09 21:01:52 +08:00
# if defined(LOCAL_TRACE)
2021-03-07 04:18:43 +08:00
Serial . print ( F ( " Testing: " ) ) ;
Serial . print ( TICKS_LOW ( aMatchValueMicros ) , DEC ) ;
Serial . print ( F ( " <= " ) ) ;
Serial . print ( aMeasuredTicks , DEC ) ;
Serial . print ( F ( " <= " ) ) ;
Serial . print ( TICKS_HIGH ( aMatchValueMicros ) , DEC ) ;
# endif
bool passed = ( ( aMeasuredTicks > = TICKS_LOW ( aMatchValueMicros ) ) & & ( aMeasuredTicks < = TICKS_HIGH ( aMatchValueMicros ) ) ) ;
2022-11-09 21:01:52 +08:00
# if defined(LOCAL_TRACE)
2021-03-07 04:18:43 +08:00
if ( passed ) {
2022-11-08 07:36:44 +08:00
Serial . println ( F ( " => passed " ) ) ;
2021-03-07 04:18:43 +08:00
} else {
2022-11-08 07:36:44 +08:00
Serial . println ( F ( " => FAILED " ) ) ;
2021-03-07 04:18:43 +08:00
}
# endif
return passed ;
}
2023-02-24 09:40:21 +08:00
bool MATCH ( uint16_t measured_ticks , uint16_t desired_us ) {
2021-03-07 04:18:43 +08:00
return matchTicks ( measured_ticks , desired_us ) ;
}
2021-03-18 04:52:41 +08:00
/**
2021-03-07 04:18:43 +08:00
* Compensate for marks exceeded by demodulator hardware
*/
2023-02-24 09:40:21 +08:00
bool matchMark ( uint16_t aMeasuredTicks , uint16_t aMatchValueMicros ) {
2022-11-09 21:01:52 +08:00
# if defined(LOCAL_TRACE)
2021-03-07 04:18:43 +08:00
Serial . print ( F ( " Testing mark (actual vs desired): " ) ) ;
Serial . print ( aMeasuredTicks * MICROS_PER_TICK , DEC ) ;
Serial . print ( F ( " us vs " ) ) ;
Serial . print ( aMatchValueMicros , DEC ) ;
Serial . print ( F ( " us: " ) ) ;
Serial . print ( TICKS_LOW ( aMatchValueMicros + MARK_EXCESS_MICROS ) * MICROS_PER_TICK , DEC ) ;
Serial . print ( F ( " <= " ) ) ;
Serial . print ( aMeasuredTicks * MICROS_PER_TICK , DEC ) ;
Serial . print ( F ( " <= " ) ) ;
Serial . print ( TICKS_HIGH ( aMatchValueMicros + MARK_EXCESS_MICROS ) * MICROS_PER_TICK , DEC ) ;
# endif
2022-11-08 07:36:44 +08:00
// compensate for marks exceeded by demodulator hardware
2021-03-07 04:18:43 +08:00
bool passed = ( ( aMeasuredTicks > = TICKS_LOW ( aMatchValueMicros + MARK_EXCESS_MICROS ) )
& & ( aMeasuredTicks < = TICKS_HIGH ( aMatchValueMicros + MARK_EXCESS_MICROS ) ) ) ;
2022-11-09 21:01:52 +08:00
# if defined(LOCAL_TRACE)
2021-03-07 04:18:43 +08:00
if ( passed ) {
2022-11-08 07:36:44 +08:00
Serial . println ( F ( " => passed " ) ) ;
2021-03-07 04:18:43 +08:00
} else {
2022-11-08 07:36:44 +08:00
Serial . println ( F ( " => FAILED " ) ) ;
2021-03-07 04:18:43 +08:00
}
# endif
return passed ;
}
2023-02-24 09:40:21 +08:00
bool MATCH_MARK ( uint16_t measured_ticks , uint16_t desired_us ) {
2021-03-07 04:18:43 +08:00
return matchMark ( measured_ticks , desired_us ) ;
}
2021-03-18 04:52:41 +08:00
/**
2021-03-07 04:18:43 +08:00
* Compensate for spaces shortened by demodulator hardware
*/
2023-02-24 09:40:21 +08:00
bool matchSpace ( uint16_t aMeasuredTicks , uint16_t aMatchValueMicros ) {
2022-11-09 21:01:52 +08:00
# if defined(LOCAL_TRACE)
2021-03-07 04:18:43 +08:00
Serial . print ( F ( " Testing space (actual vs desired): " ) ) ;
Serial . print ( aMeasuredTicks * MICROS_PER_TICK , DEC ) ;
Serial . print ( F ( " us vs " ) ) ;
Serial . print ( aMatchValueMicros , DEC ) ;
Serial . print ( F ( " us: " ) ) ;
Serial . print ( TICKS_LOW ( aMatchValueMicros - MARK_EXCESS_MICROS ) * MICROS_PER_TICK , DEC ) ;
Serial . print ( F ( " <= " ) ) ;
Serial . print ( aMeasuredTicks * MICROS_PER_TICK , DEC ) ;
Serial . print ( F ( " <= " ) ) ;
Serial . print ( TICKS_HIGH ( aMatchValueMicros - MARK_EXCESS_MICROS ) * MICROS_PER_TICK , DEC ) ;
# endif
2022-11-08 07:36:44 +08:00
// compensate for spaces shortened by demodulator hardware
2021-03-07 04:18:43 +08:00
bool passed = ( ( aMeasuredTicks > = TICKS_LOW ( aMatchValueMicros - MARK_EXCESS_MICROS ) )
& & ( aMeasuredTicks < = TICKS_HIGH ( aMatchValueMicros - MARK_EXCESS_MICROS ) ) ) ;
2022-11-09 21:01:52 +08:00
# if defined(LOCAL_TRACE)
2021-03-07 04:18:43 +08:00
if ( passed ) {
2022-11-08 07:36:44 +08:00
Serial . println ( F ( " => passed " ) ) ;
2021-03-07 04:18:43 +08:00
} else {
2022-11-08 07:36:44 +08:00
Serial . println ( F ( " => FAILED " ) ) ;
2021-03-07 04:18:43 +08:00
}
# endif
return passed ;
}
2023-02-24 09:40:21 +08:00
bool MATCH_SPACE ( uint16_t measured_ticks , uint16_t desired_us ) {
2021-03-07 04:18:43 +08:00
return matchSpace ( measured_ticks , desired_us ) ;
}
2021-03-18 04:52:41 +08:00
/**
* Getter function for MARK_EXCESS_MICROS
*/
2021-03-07 04:18:43 +08:00
int getMarkExcessMicros ( ) {
return MARK_EXCESS_MICROS ;
}
2021-04-29 23:33:05 +08:00
/*
* Check if protocol is not detected and detected space between two transmissions
* is smaller than known value for protocols ( Sony with around 24 ms )
2022-12-15 08:34:02 +08:00
* @ return true , if CheckForRecordGapsMicros ( ) has printed a message , i . e . gap < 15 ms ( RECORD_GAP_MICROS_WARNING_THRESHOLD )
2021-04-29 23:33:05 +08:00
*/
2022-11-14 08:27:45 +08:00
bool IRrecv : : checkForRecordGapsMicros ( Print * aSerial ) {
2021-04-29 23:33:05 +08:00
/*
* Check if protocol is not detected and detected space between two transmissions
* is smaller than known value for protocols ( Sony with around 24 ms )
*/
2022-11-14 08:27:45 +08:00
if ( decodedIRData . protocol < = PULSE_DISTANCE
& & decodedIRData . rawDataPtr - > rawbuf [ 0 ] < ( RECORD_GAP_MICROS_WARNING_THRESHOLD / MICROS_PER_TICK ) ) {
2021-04-29 23:33:05 +08:00
aSerial - > println ( ) ;
2022-06-27 07:18:44 +08:00
aSerial - > print ( F ( " Space of " ) ) ;
2022-11-14 08:27:45 +08:00
aSerial - > print ( decodedIRData . rawDataPtr - > rawbuf [ 0 ] * MICROS_PER_TICK ) ;
2022-06-27 07:18:44 +08:00
aSerial - > print ( F ( " us between two detected transmission is smaller than the minimal gap of " ) ) ;
2021-04-29 23:33:05 +08:00
aSerial - > print ( RECORD_GAP_MICROS_WARNING_THRESHOLD ) ;
2022-11-14 08:27:45 +08:00
aSerial - > println ( F ( " us known for implemented protocols like NEC, Sony, RC% etc.. " ) ) ;
aSerial - > println ( F ( " But it can be OK for some yet unsupported protocols, and especially for repeats. " ) ) ;
2021-08-08 03:25:44 +08:00
aSerial - > println ( F ( " If you get unexpected results, try to increase the RECORD_GAP_MICROS in IRremote.h. " ) ) ;
2021-04-29 23:33:05 +08:00
aSerial - > println ( ) ;
2022-11-14 08:27:45 +08:00
return true ;
2021-04-29 23:33:05 +08:00
}
2022-11-14 08:27:45 +08:00
return false ;
2021-04-29 23:33:05 +08:00
}
2021-03-07 04:18:43 +08:00
/**********************************************************************************************************************
* Print functions
* Since a library should not allocate the " Serial " object , all functions require a pointer to a Print object .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2022-07-25 21:09:53 +08:00
void IRrecv : : printActiveIRProtocols ( Print * aSerial ) {
2022-08-31 19:25:29 +08:00
// call no class function with same name
2022-07-25 21:09:53 +08:00
: : printActiveIRProtocols ( aSerial ) ;
}
2021-10-31 01:10:27 +08:00
void printActiveIRProtocols ( Print * aSerial ) {
# if defined(DECODE_NEC)
2022-08-28 02:22:58 +08:00
aSerial - > print ( F ( " NEC/NEC2/Onkyo/Apple, " ) ) ;
2021-10-31 01:10:27 +08:00
# endif
# if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO)
aSerial - > print ( F ( " Panasonic/Kaseikyo, " ) ) ;
# endif
# if defined(DECODE_DENON)
aSerial - > print ( F ( " Denon/Sharp, " ) ) ;
# endif
# if defined(DECODE_SONY)
aSerial - > print ( F ( " Sony, " ) ) ;
# endif
# if defined(DECODE_RC5)
aSerial - > print ( F ( " RC5, " ) ) ;
# endif
# if defined(DECODE_RC6)
aSerial - > print ( F ( " RC6, " ) ) ;
# endif
# if defined(DECODE_LG)
aSerial - > print ( F ( " LG, " ) ) ;
# endif
# if defined(DECODE_JVC)
aSerial - > print ( F ( " JVC, " ) ) ;
# endif
# if defined(DECODE_SAMSUNG)
aSerial - > print ( F ( " Samsung, " ) ) ;
# endif
/*
* Start of the exotic protocols
*/
2022-10-02 16:00:58 +08:00
# if defined(DECODE_BEO)
aSerial - > print ( F ( " Bang & Olufsen, " ) ) ;
# endif
2023-02-24 09:40:21 +08:00
# if defined(DECODE_FAST)
aSerial - > print ( F ( " FAST, " ) ) ;
# endif
2021-10-31 01:10:27 +08:00
# if defined(DECODE_WHYNTER)
aSerial - > print ( F ( " Whynter, " ) ) ;
# endif
# if defined(DECODE_LEGO_PF)
aSerial - > print ( F ( " Lego Power Functions, " ) ) ;
# endif
# if defined(DECODE_BOSEWAVE)
aSerial - > print ( F ( " Bosewave , " ) ) ;
# endif
# if defined(DECODE_MAGIQUEST)
aSerial - > print ( F ( " MagiQuest, " ) ) ;
# endif
2022-11-08 07:36:44 +08:00
# if defined(DECODE_DISTANCE_WIDTH)
aSerial - > print ( F ( " Universal Pulse Distance Width, " ) ) ;
2021-10-31 01:10:27 +08:00
# endif
# if defined(DECODE_HASH)
aSerial - > print ( F ( " Hash " ) ) ;
# endif
2021-11-08 03:44:07 +08:00
# if defined(NO_DECODER) // for sending raw only
( void ) aSerial ; // to avoid compiler warnings
# endif
2022-07-12 17:46:04 +08:00
}
2021-11-08 03:44:07 +08:00
2022-07-12 17:46:04 +08:00
/**
* Function to print values and flags of IrReceiver . decodedIRData in one line .
* Ends with println ( ) .
*
2022-12-30 01:46:09 +08:00
* @ param aSerial The Print object on which to write , for Arduino you can use & Serial .
* @ param aPrintRepeatGap If true also print the gap before repeats .
* @ param aCheckForRecordGapsMicros If true , call CheckForRecordGapsMicros ( ) which may do a long printout ,
* which in turn may block the proper detection of repeats . *
* @ return true , if CheckForRecordGapsMicros ( ) has printed a message , i . e . gap < 15 ms ( RECORD_GAP_MICROS_WARNING_THRESHOLD ) .
2022-07-12 17:46:04 +08:00
*/
2022-11-14 08:27:45 +08:00
bool IRrecv : : printIRResultShort ( Print * aSerial , bool aPrintRepeatGap , bool aCheckForRecordGapsMicros ) {
2022-08-31 19:25:29 +08:00
// call no class function with same name
2022-11-14 08:27:45 +08:00
: : printIRResultShort ( aSerial , & decodedIRData , aPrintRepeatGap ) ;
2022-11-22 19:28:10 +08:00
if ( aCheckForRecordGapsMicros & & decodedIRData . protocol ! = UNKNOWN ) {
return checkForRecordGapsMicros ( aSerial ) ;
2022-11-14 08:27:45 +08:00
}
return false ;
2022-01-27 01:36:50 +08:00
}
2022-07-12 17:46:04 +08:00
2023-02-24 09:40:21 +08:00
void IRrecv : : printDistanceWidthTimingInfo ( Print * aSerial , DistanceWidthTimingInfoStruct * aDistanceWidthTimingInfo ) {
aSerial - > print ( aDistanceWidthTimingInfo - > HeaderMarkMicros ) ;
aSerial - > print ( F ( " , " ) ) ;
aSerial - > print ( aDistanceWidthTimingInfo - > HeaderSpaceMicros ) ;
aSerial - > print ( F ( " , " ) ) ;
aSerial - > print ( aDistanceWidthTimingInfo - > OneMarkMicros ) ;
aSerial - > print ( F ( " , " ) ) ;
aSerial - > print ( aDistanceWidthTimingInfo - > OneSpaceMicros ) ;
aSerial - > print ( F ( " , " ) ) ;
aSerial - > print ( aDistanceWidthTimingInfo - > ZeroMarkMicros ) ;
aSerial - > print ( F ( " , " ) ) ;
aSerial - > print ( aDistanceWidthTimingInfo - > ZeroSpaceMicros ) ;
}
uint32_t IRrecv : : getTotalDurationOfRawData ( ) {
uint16_t tSumOfDurationTicks = 0 ;
for ( uint_fast8_t i = 1 ; i < decodedIRData . rawDataPtr - > rawlen ; i + + ) {
tSumOfDurationTicks + = decodedIRData . rawDataPtr - > rawbuf [ i ] ;
}
return tSumOfDurationTicks * ( uint32_t ) MICROS_PER_TICK ;
}
2021-03-18 04:52:41 +08:00
/**
* Function to print values and flags of IrReceiver . decodedIRData in one line .
2021-05-02 04:24:04 +08:00
* Ends with println ( ) .
*
2021-03-18 04:52:41 +08:00
* @ param aSerial The Print object on which to write , for Arduino you can use & Serial .
*/
2022-07-12 17:46:04 +08:00
void IRrecv : : printIRSendUsage ( Print * aSerial ) {
2022-11-22 19:28:10 +08:00
if ( decodedIRData . protocol ! = UNKNOWN
& & ( decodedIRData . flags & ( IRDATA_FLAGS_IS_AUTO_REPEAT | IRDATA_FLAGS_IS_REPEAT ) ) = = 0x00 ) {
2022-11-08 07:36:44 +08:00
# if defined(DECODE_DISTANCE_WIDTH)
2022-08-28 02:22:58 +08:00
aSerial - > print ( F ( " Send with: " ) ) ;
2022-11-22 19:28:10 +08:00
uint_fast8_t tNumberOfArrayData = 0 ;
2022-11-14 08:27:45 +08:00
if ( decodedIRData . protocol = = PULSE_DISTANCE | | decodedIRData . protocol = = PULSE_WIDTH ) {
2022-12-02 07:28:03 +08:00
# if __INT_WIDTH__ < 32
2022-11-22 19:28:10 +08:00
tNumberOfArrayData = ( ( decodedIRData . numberOfBits - 1 ) / 32 ) + 1 ;
if ( tNumberOfArrayData > 1 ) {
aSerial - > println ( ) ;
aSerial - > print ( F ( " uint32_t tRawData[]={0x " ) ) ;
2022-12-02 07:28:03 +08:00
# else
2022-11-22 19:28:10 +08:00
tNumberOfArrayData = ( ( decodedIRData . numberOfBits - 1 ) / 64 ) + 1 ;
if ( tNumberOfArrayData > 1 ) {
aSerial - > println ( ) ;
aSerial - > print ( F ( " uint64_t tRawData[]={0x " ) ) ;
2022-12-02 07:28:03 +08:00
# endif
2022-11-22 19:28:10 +08:00
for ( uint_fast8_t i = 0 ; i < tNumberOfArrayData ; + + i ) {
2022-12-02 07:28:03 +08:00
# if (__INT_WIDTH__ < 32)
2022-11-22 19:28:10 +08:00
aSerial - > print ( decodedIRData . decodedRawDataArray [ i ] , HEX ) ;
2022-12-02 07:28:03 +08:00
# else
PrintULL : : print ( aSerial , decodedIRData . decodedRawDataArray [ i ] , HEX ) ;
# endif
2022-11-22 19:28:10 +08:00
if ( i ! = tNumberOfArrayData - 1 ) {
aSerial - > print ( F ( " , 0x " ) ) ;
}
2022-07-12 17:46:04 +08:00
}
2022-11-22 19:28:10 +08:00
aSerial - > println ( F ( " }; " ) ) ;
aSerial - > print ( F ( " " ) ) ;
2022-07-12 17:46:04 +08:00
}
}
2022-08-28 02:22:58 +08:00
aSerial - > print ( F ( " IrSender.send " ) ) ;
2022-07-12 17:46:04 +08:00
# else
aSerial - > print ( F ( " Send with: IrSender.send " ) ) ;
# endif
2022-08-28 02:22:58 +08:00
2022-11-08 07:36:44 +08:00
# if defined(DECODE_DISTANCE_WIDTH)
2022-11-14 08:27:45 +08:00
if ( decodedIRData . protocol ! = PULSE_DISTANCE & & decodedIRData . protocol ! = PULSE_WIDTH ) {
2022-07-12 17:46:04 +08:00
# endif
2022-11-14 08:27:45 +08:00
aSerial - > print ( getProtocolString ( ) ) ;
2022-11-08 07:36:44 +08:00
aSerial - > print ( F ( " (0x " ) ) ;
2022-09-15 08:53:46 +08:00
# if defined(DECODE_MAGIQUEST)
2022-11-22 19:28:10 +08:00
if ( decodedIRData . protocol = = MAGIQUEST ) {
2022-12-02 07:28:03 +08:00
# if (__INT_WIDTH__ < 32)
2022-11-22 19:28:10 +08:00
aSerial - > print ( decodedIRData . decodedRawData , HEX ) ;
2022-12-02 07:28:03 +08:00
# else
PrintULL : : print ( aSerial , decodedIRData . decodedRawData , HEX ) ;
# endif
2022-11-22 19:28:10 +08:00
} else {
aSerial - > print ( decodedIRData . address , HEX ) ;
}
2022-11-08 07:36:44 +08:00
# else
/*
* New decoders have address and command
*/
2022-11-14 08:27:45 +08:00
aSerial - > print ( decodedIRData . address , HEX ) ;
2022-09-15 08:53:46 +08:00
# endif
2022-08-28 02:22:58 +08:00
2022-11-08 07:36:44 +08:00
aSerial - > print ( F ( " , 0x " ) ) ;
2022-11-14 08:27:45 +08:00
aSerial - > print ( decodedIRData . command , HEX ) ;
2022-12-15 08:34:02 +08:00
if ( decodedIRData . protocol = = SONY ) {
aSerial - > print ( F ( " , 2, " ) ) ;
aSerial - > print ( decodedIRData . numberOfBits ) ;
} else {
aSerial - > print ( F ( " , <numberOfRepeats> " ) ) ;
}
2022-09-15 08:53:46 +08:00
2022-11-08 07:36:44 +08:00
# if defined(DECODE_DISTANCE_WIDTH)
2022-07-12 17:46:04 +08:00
} else {
2023-02-20 10:22:15 +08:00
/*
* Pulse distance or pulse width here
*/
2023-02-24 09:40:21 +08:00
aSerial - > print ( " PulseDistanceWidth " ) ;
2022-11-22 19:28:10 +08:00
if ( tNumberOfArrayData > 1 ) {
2023-02-24 09:40:21 +08:00
aSerial - > print ( " FromArray(38, " ) ;
2022-11-08 07:36:44 +08:00
} else {
2023-02-24 09:40:21 +08:00
aSerial - > print ( " (38, " ) ;
2022-11-08 07:36:44 +08:00
}
2023-02-24 09:40:21 +08:00
printDistanceWidthTimingInfo ( aSerial , & decodedIRData . DistanceWidthTimingInfo ) ;
2022-11-22 19:28:10 +08:00
if ( tNumberOfArrayData > 1 ) {
aSerial - > print ( F ( " , &tRawData[0], " ) ) ;
} else {
aSerial - > print ( F ( " , 0x " ) ) ;
2022-12-02 07:28:03 +08:00
# if (__INT_WIDTH__ < 32)
2022-11-22 19:28:10 +08:00
aSerial - > print ( decodedIRData . decodedRawData , HEX ) ;
2022-12-02 07:28:03 +08:00
# else
PrintULL : : print ( aSerial , decodedIRData . decodedRawData , HEX ) ;
# endif
2022-11-22 19:28:10 +08:00
aSerial - > print ( F ( " , " ) ) ;
}
2022-11-14 08:27:45 +08:00
aSerial - > print ( decodedIRData . numberOfBits ) ; // aNumberOfBits
2023-02-24 09:40:21 +08:00
aSerial - > print ( F ( " , PROTOCOL_IS_ " ) ) ;
2022-11-14 08:27:45 +08:00
if ( decodedIRData . flags & IRDATA_FLAGS_IS_MSB_FIRST ) {
2023-02-24 09:40:21 +08:00
aSerial - > print ( ' M ' ) ;
2022-11-08 07:36:44 +08:00
} else {
2023-02-24 09:40:21 +08:00
aSerial - > print ( ' L ' ) ;
2022-11-08 07:36:44 +08:00
}
2023-02-24 09:40:21 +08:00
aSerial - > print ( F ( " SB_FIRST, <RepeatPeriodMillis>, <numberOfRepeats> " ) ) ;
2022-07-12 17:46:04 +08:00
}
# endif
2023-02-24 09:40:21 +08:00
# if defined(DECODE_PANASONIC) || defined(DECODE_KASEIKYO)
if ( ( decodedIRData . flags & IRDATA_FLAGS_EXTRA_INFO ) & & decodedIRData . protocol = = KASEIKYO ) {
aSerial - > print ( F ( " , 0x " ) ) ;
2022-11-30 05:06:08 +08:00
aSerial - > print ( decodedIRData . extra , HEX ) ;
}
2023-02-24 09:40:21 +08:00
# endif
aSerial - > print ( F ( " ); " ) ) ;
2022-11-30 05:06:08 +08:00
aSerial - > println ( ) ;
2022-07-12 17:46:04 +08:00
}
2020-09-16 16:29:57 +08:00
}
2021-03-18 04:52:41 +08:00
/**
2021-03-19 05:01:39 +08:00
* Function to print protocol number , address , command , raw data and repeat flag of IrReceiver . decodedIRData in one short line .
2021-05-02 04:24:04 +08:00
* Does not print a Newline / does not end with println ( ) .
*
2021-03-18 04:52:41 +08:00
* @ param aSerial The Print object on which to write , for Arduino you can use & Serial .
*/
2021-02-19 06:43:11 +08:00
void IRrecv : : printIRResultMinimal ( Print * aSerial ) {
aSerial - > print ( F ( " P= " ) ) ;
2021-03-19 05:01:39 +08:00
aSerial - > print ( decodedIRData . protocol ) ;
2021-02-19 06:43:11 +08:00
if ( decodedIRData . protocol = = UNKNOWN ) {
2021-03-02 22:25:39 +08:00
# if defined(DECODE_HASH)
2021-02-19 06:43:11 +08:00
aSerial - > print ( F ( " #=0x " ) ) ;
2022-12-02 07:28:03 +08:00
# if (__INT_WIDTH__ < 32)
2021-02-19 06:43:11 +08:00
aSerial - > print ( decodedIRData . decodedRawData , HEX ) ;
2022-12-02 07:28:03 +08:00
# else
PrintULL : : print ( aSerial , decodedIRData . decodedRawData , HEX ) ;
# endif
2021-02-19 06:43:11 +08:00
# endif
aSerial - > print ( ' ' ) ;
aSerial - > print ( ( decodedIRData . rawDataPtr - > rawlen + 1 ) / 2 , DEC ) ;
aSerial - > println ( F ( " bits received " ) ) ;
} else {
/*
* New decoders have address and command
*/
aSerial - > print ( F ( " A=0x " ) ) ;
aSerial - > print ( decodedIRData . address , HEX ) ;
aSerial - > print ( F ( " C=0x " ) ) ;
aSerial - > print ( decodedIRData . command , HEX ) ;
2021-03-18 04:52:41 +08:00
2021-02-19 06:43:11 +08:00
aSerial - > print ( F ( " Raw=0x " ) ) ;
2022-12-02 07:28:03 +08:00
# if (__INT_WIDTH__ < 32)
2021-02-19 06:43:11 +08:00
aSerial - > print ( decodedIRData . decodedRawData , HEX ) ;
2022-12-02 07:28:03 +08:00
# else
PrintULL : : print ( aSerial , decodedIRData . decodedRawData , HEX ) ;
# endif
2021-03-18 04:52:41 +08:00
2021-02-19 06:43:11 +08:00
if ( decodedIRData . flags & ( IRDATA_FLAGS_IS_AUTO_REPEAT | IRDATA_FLAGS_IS_REPEAT ) ) {
aSerial - > print ( F ( " R " ) ) ;
}
}
}
2021-03-09 04:38:06 +08:00
/**
2021-03-18 04:52:41 +08:00
* Dump out the timings in IrReceiver . decodedIRData . rawDataPtr - > rawbuf [ ] array 8 values per line .
2021-05-02 04:24:04 +08:00
*
2021-03-18 04:52:41 +08:00
* @ param aSerial The Print object on which to write , for Arduino you can use & Serial .
2022-08-06 20:39:28 +08:00
* @ param aOutputMicrosecondsInsteadOfTicks Output the ( rawbuf_values * MICROS_PER_TICK ) for better readability .
2021-03-09 04:38:06 +08:00
*/
2020-11-05 00:10:32 +08:00
void IRrecv : : printIRResultRawFormatted ( Print * aSerial , bool aOutputMicrosecondsInsteadOfTicks ) {
2023-02-24 09:40:21 +08:00
uint8_t tRawlen = decodedIRData . rawDataPtr - > rawlen ; // Get it once here in order to print quite consistent data, even if ISR is running
2022-08-31 19:25:29 +08:00
// Print Raw data
2020-12-31 11:51:54 +08:00
aSerial - > print ( F ( " rawData[ " ) ) ;
2023-02-24 09:40:21 +08:00
aSerial - > print ( tRawlen , DEC ) ;
2020-12-31 11:51:54 +08:00
aSerial - > println ( F ( " ]: " ) ) ;
/*
* Print initial gap
*/
2022-07-12 17:46:04 +08:00
aSerial - > print ( F ( " - " ) ) ;
2020-12-31 11:51:54 +08:00
if ( aOutputMicrosecondsInsteadOfTicks ) {
2022-07-12 17:46:04 +08:00
aSerial - > println ( ( uint32_t ) decodedIRData . rawDataPtr - > rawbuf [ 0 ] * MICROS_PER_TICK , DEC ) ;
2020-12-31 11:51:54 +08:00
} else {
2022-07-12 17:46:04 +08:00
aSerial - > println ( decodedIRData . rawDataPtr - > rawbuf [ 0 ] , DEC ) ;
2020-12-31 11:51:54 +08:00
}
2022-03-30 17:55:04 +08:00
# if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR
2022-05-19 15:51:34 +08:00
uint_fast8_t i ;
2021-09-28 05:46:13 +08:00
# else
2022-11-08 07:36:44 +08:00
unsigned int i ;
2021-09-28 05:46:13 +08:00
# endif
2022-08-28 02:22:58 +08:00
2022-08-31 19:25:29 +08:00
// Newline is printed every 8. value, if tCounterForNewline % 8 == 0
2022-07-12 17:46:04 +08:00
uint_fast8_t tCounterForNewline = 6 ; // first newline is after the 2 values of the start bit
2022-08-31 19:25:29 +08:00
// check if we have a protocol with no or 8 start bits
2022-07-12 17:46:04 +08:00
# if defined(DECODE_DENON) || defined(DECODE_MAGIQUEST)
if (
2022-12-02 07:28:03 +08:00
# if defined(DECODE_DENON)
2022-07-12 17:46:04 +08:00
decodedIRData . protocol = = DENON | | decodedIRData . protocol = = SHARP | |
2022-12-02 07:28:03 +08:00
# endif
# if defined(DECODE_MAGIQUEST)
2022-07-12 17:46:04 +08:00
decodedIRData . protocol = = MAGIQUEST | |
2022-12-02 07:28:03 +08:00
# endif
2022-11-08 07:36:44 +08:00
false ) {
2022-07-12 17:46:04 +08:00
tCounterForNewline = 0 ; // no or 8 start bits
}
# endif
2022-08-28 02:22:58 +08:00
uint32_t tDuration ;
uint16_t tSumOfDurationTicks = 0 ;
2023-02-24 09:40:21 +08:00
for ( i = 1 ; i < tRawlen ; i + + ) {
2022-08-28 02:22:58 +08:00
auto tCurrentTicks = decodedIRData . rawDataPtr - > rawbuf [ i ] ;
2020-11-05 00:10:32 +08:00
if ( aOutputMicrosecondsInsteadOfTicks ) {
2022-08-28 02:22:58 +08:00
tDuration = tCurrentTicks * MICROS_PER_TICK ;
2020-11-05 00:10:32 +08:00
} else {
2022-08-28 02:22:58 +08:00
tDuration = tCurrentTicks ;
2020-11-05 00:10:32 +08:00
}
2022-08-28 02:22:58 +08:00
tSumOfDurationTicks + = tCurrentTicks ; // compute length of protocol frame
2020-10-26 02:18:57 +08:00
if ( ! ( i & 1 ) ) { // even
2020-12-31 11:51:54 +08:00
aSerial - > print ( ' - ' ) ;
2020-10-26 02:18:57 +08:00
} else { // odd
2022-07-12 17:46:04 +08:00
aSerial - > print ( F ( " + " ) ) ;
2021-02-19 06:43:11 +08:00
}
2022-07-12 17:46:04 +08:00
// padding only for big values
2022-08-28 02:22:58 +08:00
if ( aOutputMicrosecondsInsteadOfTicks & & tDuration < 1000 ) {
2021-02-19 06:43:11 +08:00
aSerial - > print ( ' ' ) ;
}
2022-08-28 02:22:58 +08:00
if ( aOutputMicrosecondsInsteadOfTicks & & tDuration < 100 ) {
2021-02-19 06:43:11 +08:00
aSerial - > print ( ' ' ) ;
2020-10-26 02:18:57 +08:00
}
2022-08-28 02:22:58 +08:00
if ( tDuration < 10 ) {
2021-02-19 06:43:11 +08:00
aSerial - > print ( ' ' ) ;
}
2022-08-28 02:22:58 +08:00
aSerial - > print ( tDuration , DEC ) ;
2021-02-19 06:43:11 +08:00
2023-02-24 09:40:21 +08:00
if ( ( i & 1 ) & & ( i + 1 ) < tRawlen ) {
2021-02-19 06:43:11 +08:00
aSerial - > print ( ' , ' ) ; //',' not required for last one
}
2022-07-12 17:46:04 +08:00
tCounterForNewline + + ;
if ( ( tCounterForNewline % 8 ) = = 0 ) {
aSerial - > println ( ) ;
2020-10-26 02:18:57 +08:00
}
}
2022-08-28 02:22:58 +08:00
aSerial - > println ( ) ;
aSerial - > print ( " Sum: " ) ;
if ( aOutputMicrosecondsInsteadOfTicks ) {
aSerial - > println ( ( uint32_t ) tSumOfDurationTicks * MICROS_PER_TICK , DEC ) ;
} else {
aSerial - > println ( tSumOfDurationTicks , DEC ) ;
}
2020-10-26 02:18:57 +08:00
}
2020-11-05 00:10:32 +08:00
2021-03-09 04:38:06 +08:00
/**
2021-03-18 04:52:41 +08:00
* Dump out the IrReceiver . decodedIRData . rawDataPtr - > rawbuf [ ] to be used as C definition for sendRaw ( ) .
2021-01-14 22:28:34 +08:00
*
2021-03-18 04:52:41 +08:00
* Compensate received values by MARK_EXCESS_MICROS , like it is done for decoding !
2021-01-14 22:28:34 +08:00
* Print ticks in 8 bit format to save space .
* Maximum is 255 * 50 microseconds = 12750 microseconds = 12.75 ms , which hardly ever occurs inside an IR sequence .
* Recording of IRremote anyway stops at a gap of RECORD_GAP_MICROS ( 5 ms ) .
2021-03-18 04:52:41 +08:00
*
* @ param aSerial The Print object on which to write , for Arduino you can use & Serial .
* @ param aOutputMicrosecondsInsteadOfTicks Output the ( rawbuf_values * MICROS_PER_TICK ) for better readability .
2020-11-05 00:10:32 +08:00
*/
2021-01-15 22:57:40 +08:00
void IRrecv : : compensateAndPrintIRResultAsCArray ( Print * aSerial , bool aOutputMicrosecondsInsteadOfTicks ) {
2021-02-19 06:43:11 +08:00
// Start declaration
2020-11-05 00:10:32 +08:00
if ( aOutputMicrosecondsInsteadOfTicks ) {
2022-03-05 00:06:44 +08:00
aSerial - > print ( F ( " uint16_t rawData[ " ) ) ; // variable type, array name
2020-11-05 00:10:32 +08:00
} else {
2022-03-05 00:06:44 +08:00
aSerial - > print ( F ( " uint8_t rawTicks[ " ) ) ; // variable type, array name
2020-11-05 00:10:32 +08:00
}
2021-01-17 02:50:36 +08:00
aSerial - > print ( decodedIRData . rawDataPtr - > rawlen - 1 , DEC ) ; // array size
aSerial - > print ( F ( " ] = { " ) ) ; // Start declaration
2020-10-26 02:18:57 +08:00
2020-11-05 00:10:32 +08:00
// Dump data
2022-03-30 17:55:04 +08:00
# if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR
2022-05-19 15:51:34 +08:00
uint_fast8_t i ;
2021-09-28 05:46:13 +08:00
# else
2022-11-08 07:36:44 +08:00
unsigned int i ;
2021-09-28 05:46:13 +08:00
# endif
for ( i = 1 ; i < decodedIRData . rawDataPtr - > rawlen ; i + + ) {
2021-01-17 02:50:36 +08:00
uint32_t tDuration = decodedIRData . rawDataPtr - > rawbuf [ i ] * MICROS_PER_TICK ;
2021-01-14 22:28:34 +08:00
if ( i & 1 ) {
// Mark
tDuration - = MARK_EXCESS_MICROS ;
} else {
tDuration + = MARK_EXCESS_MICROS ;
}
2020-11-05 00:10:32 +08:00
if ( aOutputMicrosecondsInsteadOfTicks ) {
2021-01-14 22:28:34 +08:00
aSerial - > print ( tDuration ) ;
2020-11-05 00:10:32 +08:00
} else {
2022-05-21 00:54:51 +08:00
unsigned int tTicks = ( tDuration + ( MICROS_PER_TICK / 2 ) ) / MICROS_PER_TICK ;
2023-02-10 07:08:42 +08:00
/*
* Clip to 8 bit value
*/
tTicks = ( tTicks > UINT8_MAX ) ? UINT8_MAX : tTicks ;
2021-01-14 22:28:34 +08:00
aSerial - > print ( tTicks ) ;
2020-11-05 00:10:32 +08:00
}
2021-01-17 02:50:36 +08:00
if ( i + 1 < decodedIRData . rawDataPtr - > rawlen )
2020-12-31 11:51:54 +08:00
aSerial - > print ( ' , ' ) ; // ',' not required on last one
2020-10-26 02:18:57 +08:00
if ( ! ( i & 1 ) )
2020-12-31 11:51:54 +08:00
aSerial - > print ( ' ' ) ;
2020-10-26 02:18:57 +08:00
}
2020-11-05 00:10:32 +08:00
// End declaration
2021-01-14 10:12:57 +08:00
aSerial - > print ( F ( " }; " ) ) ; //
2020-10-26 02:18:57 +08:00
2020-11-05 00:10:32 +08:00
// Comment
2020-12-31 11:51:54 +08:00
aSerial - > print ( F ( " // " ) ) ;
2021-01-16 01:45:35 +08:00
printIRResultShort ( aSerial ) ;
2020-10-26 02:18:57 +08:00
2020-11-05 00:10:32 +08:00
// Newline
2020-10-26 02:18:57 +08:00
aSerial - > println ( " " ) ;
}
2021-03-09 04:38:06 +08:00
/**
2021-04-08 13:59:45 +08:00
* Store the decodedIRData to be used for sendRaw ( ) .
*
2021-03-18 04:52:41 +08:00
* Compensate received values by MARK_EXCESS_MICROS , like it is done for decoding and store it in an array provided .
2021-01-15 22:57:40 +08:00
*
2021-03-07 04:18:43 +08:00
* Maximum for uint8_t is 255 * 50 microseconds = 12750 microseconds = 12.75 ms , which hardly ever occurs inside an IR sequence .
* Recording of IRremote anyway stops at a gap of RECORD_GAP_MICROS ( 5 ms ) .
2021-03-18 04:52:41 +08:00
* @ param aArrayPtr Address of an array provided by the caller .
2021-01-15 22:57:40 +08:00
*/
void IRrecv : : compensateAndStoreIRResultInArray ( uint8_t * aArrayPtr ) {
2021-09-28 05:46:13 +08:00
// Store data, skip leading space#
2022-03-30 17:55:04 +08:00
# if RAW_BUFFER_LENGTH <= 254 // saves around 75 bytes program memory and speeds up ISR
2022-05-19 15:51:34 +08:00
uint_fast8_t i ;
2021-09-28 05:46:13 +08:00
# else
2022-11-08 07:36:44 +08:00
unsigned int i ;
2021-09-28 05:46:13 +08:00
# endif
for ( i = 1 ; i < decodedIRData . rawDataPtr - > rawlen ; i + + ) {
2021-01-17 02:50:36 +08:00
uint32_t tDuration = decodedIRData . rawDataPtr - > rawbuf [ i ] * MICROS_PER_TICK ;
2021-01-15 22:57:40 +08:00
if ( i & 1 ) {
// Mark
tDuration - = MARK_EXCESS_MICROS ;
} else {
tDuration + = MARK_EXCESS_MICROS ;
}
2022-05-21 00:54:51 +08:00
unsigned int tTicks = ( tDuration + ( MICROS_PER_TICK / 2 ) ) / MICROS_PER_TICK ;
2022-03-05 00:06:44 +08:00
* aArrayPtr = ( tTicks > UINT8_MAX ) ? UINT8_MAX : tTicks ; // we store it in an 8 bit array
2021-01-15 22:57:40 +08:00
aArrayPtr + + ;
}
}
2021-03-18 04:52:41 +08:00
/**
2021-04-08 13:59:45 +08:00
* Print results as C variables to be used for sendXXX ( )
2021-03-18 04:52:41 +08:00
* @ param aSerial The Print object on which to write , for Arduino you can use & Serial .
*/
2020-10-26 02:18:57 +08:00
void IRrecv : : printIRResultAsCVariables ( Print * aSerial ) {
2020-11-05 00:10:32 +08:00
// Now dump "known" codes
2020-12-31 11:51:54 +08:00
if ( decodedIRData . protocol ! = UNKNOWN ) {
2021-01-17 02:50:36 +08:00
/*
* New decoders have address and command
*/
2021-02-03 23:07:01 +08:00
aSerial - > print ( F ( " uint16_t " ) ) ;
2021-01-17 02:50:36 +08:00
aSerial - > print ( F ( " address = 0x " ) ) ;
aSerial - > print ( decodedIRData . address , HEX ) ;
aSerial - > println ( ' ; ' ) ;
2020-10-26 02:18:57 +08:00
2021-02-03 23:07:01 +08:00
aSerial - > print ( F ( " uint16_t " ) ) ;
2021-01-17 02:50:36 +08:00
aSerial - > print ( F ( " command = 0x " ) ) ;
aSerial - > print ( decodedIRData . command , HEX ) ;
aSerial - > println ( ' ; ' ) ;
2020-10-26 02:18:57 +08:00
2022-11-22 19:28:10 +08:00
// All protocols have raw data
# if __INT_WIDTH__ < 32
aSerial - > print ( F ( " uint32_t rawData = 0x " ) ) ;
# else
aSerial - > print ( F ( " uint64_t rawData = 0x " ) ) ;
# endif
2022-12-02 07:28:03 +08:00
# if (__INT_WIDTH__ < 32)
2021-01-17 02:50:36 +08:00
aSerial - > print ( decodedIRData . decodedRawData , HEX ) ;
2022-12-02 07:28:03 +08:00
# else
PrintULL : : print ( aSerial , decodedIRData . decodedRawData , HEX ) ;
# endif
2020-12-31 11:51:54 +08:00
aSerial - > println ( ' ; ' ) ;
2020-10-26 02:18:57 +08:00
aSerial - > println ( ) ;
}
}
2022-08-31 20:07:41 +08:00
# if defined(__AVR__)
2022-07-25 21:09:53 +08:00
const __FlashStringHelper * IRrecv : : getProtocolString ( ) {
2022-08-31 19:25:29 +08:00
// call no class function with same name
2022-07-25 21:09:53 +08:00
return : : getProtocolString ( decodedIRData . protocol ) ;
}
2022-08-31 20:07:41 +08:00
# else
const char * IRrecv : : getProtocolString ( ) {
2022-11-08 07:36:44 +08:00
// call no class function with same name
2022-08-31 20:07:41 +08:00
return : : getProtocolString ( decodedIRData . protocol ) ;
}
# endif
2021-03-07 04:18:43 +08:00
2022-08-31 19:25:29 +08:00
/**********************************************************************************************************************
* The OLD and DEPRECATED decode function with parameter aResults , kept for backward compatibility to old 2.0 tutorials
2021-04-10 22:49:28 +08:00
* This function calls the old MSB first decoders and fills only the 3 variables :
* aResults - > value
* aResults - > bits
* aResults - > decode_type
2021-03-07 04:18:43 +08:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool IRrecv : : decode ( decode_results * aResults ) {
2021-04-08 13:59:45 +08:00
static bool sDeprecationMessageSent = false ;
if ( irparams . StateForISR ! = IR_REC_STATE_STOP ) {
return false ;
}
if ( ! sDeprecationMessageSent ) {
2021-10-18 06:53:51 +08:00
# if !(defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__))
2023-02-12 20:02:01 +08:00
// Serial.println(
// "The function decode(&results)) is deprecated and may not work as expected! Just use decode() without a parameter and IrReceiver.decodedIRData.<fieldname> .");
2021-10-18 06:53:51 +08:00
# endif
2021-04-08 13:59:45 +08:00
sDeprecationMessageSent = true ;
}
2022-08-31 19:25:29 +08:00
// copy for usage by legacy programs
2021-04-08 13:59:45 +08:00
aResults - > rawbuf = irparams . rawbuf ;
aResults - > rawlen = irparams . rawlen ;
if ( irparams . OverflowFlag ) {
// Copy overflow flag to decodedIRData.flags
irparams . OverflowFlag = false ;
irparams . rawlen = 0 ; // otherwise we have OverflowFlag again at next ISR call
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINTLN ( F ( " Overflow happened " ) ) ;
2021-04-08 13:59:45 +08:00
}
aResults - > overflow = irparams . OverflowFlag ;
aResults - > value = 0 ;
decodedIRData . flags = IRDATA_FLAGS_IS_MSB_FIRST ; // for print
# if defined(DECODE_NEC)
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINTLN ( F ( " Attempting old NEC decode " ) ) ;
2021-04-08 13:59:45 +08:00
if ( decodeNECMSB ( aResults ) ) {
2022-11-08 07:36:44 +08:00
return true ;
2021-04-08 13:59:45 +08:00
}
# endif
# if defined(DECODE_SONY)
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINTLN ( F ( " Attempting old Sony decode " ) ) ;
2022-11-08 07:36:44 +08:00
if ( decodeSonyMSB ( aResults ) ) {
return true ;
2021-04-08 13:59:45 +08:00
}
# endif
# if defined(DECODE_RC5)
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINTLN ( F ( " Attempting RC5 decode " ) ) ;
2021-04-08 13:59:45 +08:00
if ( decodeRC5 ( ) ) {
aResults - > bits = decodedIRData . numberOfBits ;
aResults - > value = decodedIRData . decodedRawData ;
aResults - > decode_type = RC5 ;
2022-11-08 07:36:44 +08:00
return true ;
2021-04-08 13:59:45 +08:00
}
# endif
# if defined(DECODE_RC6)
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINTLN ( F ( " Attempting RC6 decode " ) ) ;
2022-11-08 07:36:44 +08:00
if ( decodeRC6 ( ) ) {
2021-04-08 13:59:45 +08:00
aResults - > bits = decodedIRData . numberOfBits ;
aResults - > value = decodedIRData . decodedRawData ;
aResults - > decode_type = RC6 ;
2022-11-08 07:36:44 +08:00
return true ;
2021-04-08 13:59:45 +08:00
}
# endif
2022-08-31 19:25:29 +08:00
// Removed bool IRrecv::decodePanasonicMSB(decode_results *aResults) since implementations was wrong (wrong length), and nobody recognized it
2021-04-08 13:59:45 +08:00
# if defined(DECODE_LG)
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINTLN ( F ( " Attempting old LG decode " ) ) ;
2022-11-08 07:36:44 +08:00
if ( decodeLGMSB ( aResults ) ) { return true ; }
2021-04-08 13:59:45 +08:00
# endif
# if defined(DECODE_JVC)
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINTLN ( F ( " Attempting old JVC decode " ) ) ;
2021-04-08 13:59:45 +08:00
if ( decodeJVCMSB ( aResults ) ) {
2022-11-08 07:36:44 +08:00
return true ;
2021-04-08 13:59:45 +08:00
}
# endif
# if defined(DECODE_SAMSUNG)
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINTLN ( F ( " Attempting old SAMSUNG decode " ) ) ;
2021-04-08 13:59:45 +08:00
if ( decodeSAMSUNG ( aResults ) ) {
2022-11-08 07:36:44 +08:00
return true ;
2021-04-08 13:59:45 +08:00
}
# endif
# if defined(DECODE_DENON)
2022-05-19 15:51:34 +08:00
IR_DEBUG_PRINTLN ( F ( " Attempting old Denon decode " ) ) ;
2021-04-08 13:59:45 +08:00
if ( decodeDenonOld ( aResults ) ) {
2022-11-08 07:36:44 +08:00
return true ;
2021-04-08 13:59:45 +08:00
}
# endif
2022-08-31 19:25:29 +08:00
// decodeHash returns a hash on any input.
// Thus, it needs to be last in the list.
// If you add any decodes, add them before this.
2021-04-08 13:59:45 +08:00
if ( decodeHashOld ( aResults ) ) {
return true ;
}
2022-08-31 19:25:29 +08:00
// Throw away and start over
2021-04-08 13:59:45 +08:00
resume ( ) ;
return false ;
2021-03-07 04:18:43 +08:00
}
2021-03-18 04:52:41 +08:00
/** @}*/
2023-02-24 09:40:21 +08:00
# if defined(_IR_MEASURE_TIMING)
# undef _IR_MEASURE_TIMING
# endif
2022-11-09 21:01:52 +08:00
# if defined(LOCAL_TRACE)
# undef LOCAL_TRACE
# endif
2022-11-08 07:36:44 +08:00
# if defined(LOCAL_DEBUG)
# undef LOCAL_DEBUG
# endif
2022-03-30 17:55:04 +08:00
# endif // _IR_RECEIVE_HPP