/** * @file IRremote.h * @brief Public API to the library. */ //****************************************************************************** // IRremote // Version 2.0.1 June, 2015 // Copyright 2009 Ken Shirriff // For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html // Edited by Mitra to add new controller SANYO // // Interrupt code based on NECIRrcv by Joe Knapp // http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 // Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ // // JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) // LG added by Darryl Smith (based on the JVC protocol) // Whynter A/C ARC-110WD added by Francesco Meschia // MagiQuest added by E. Stuart Hicks (based on code by mpflaga - https://github.com/mpflaga/Arduino-IRremote/) //****************************************************************************** #ifndef IRremote_h #define IRremote_h //------------------------------------------------------------------------------ #include "private/IRremoteInt.h" /**************************************************** * PROTOCOLS ****************************************************/ //------------------------------------------------------------------------------ // Supported IR protocols // Each protocol you include costs memory and, during decode, costs time // Disable (set to 0) all the protocols you do not need/want! // #define DECODE_AIWA_RC_T501 1 #define SEND_AIWA_RC_T501 1 #define DECODE_BOSEWAVE 1 #define SEND_BOSEWAVE 1 #define DECODE_DENON 1 #define SEND_DENON 1 #define DECODE_DISH 0 // NOT WRITTEN #define SEND_DISH 1 #define DECODE_JVC 1 #define SEND_JVC 1 #define DECODE_LEGO_PF 0 // NOT WRITTEN #define SEND_LEGO_PF 1 #define DECODE_LG 1 #define SEND_LG 1 #define DECODE_MAGIQUEST 1 #define SEND_MAGIQUEST 1 #define DECODE_MITSUBISHI 1 #define SEND_MITSUBISHI 0 // NOT WRITTEN //#define USE_NEC_STANDARD // remove comment to have the standard NEC decoding (LSB first) available. #if defined(USE_NEC_STANDARD) #define DECODE_NEC_STANDARD 1 #define DECODE_NEC 0 #define LSB_FIRST_REQUIRED #else #define DECODE_NEC_STANDARD 0 #define DECODE_NEC 1 #endif #define SEND_NEC 1 #define SEND_NEC_STANDARD 1 #define DECODE_PANASONIC 1 #define SEND_PANASONIC 1 #define DECODE_RC5 1 #define SEND_RC5 1 #define DECODE_RC6 1 #define SEND_RC6 1 #define DECODE_SAMSUNG 1 #define SEND_SAMSUNG 1 #define DECODE_SANYO 1 #define SEND_SANYO 0 // NOT WRITTEN #define DECODE_SHARP 1 #define SEND_SHARP 1 #define DECODE_SHARP_ALT 1 #define SEND_SHARP_ALT 1 #if SEND_SHARP_ALT #define LSB_FIRST_REQUIRED #endif #define DECODE_SONY 1 #define SEND_SONY 1 #define DECODE_WHYNTER 1 #define SEND_WHYNTER 1 #define DECODE_HASH 1 // special decoder for all protocols /** * An enum consisting of all supported formats. * You do NOT need to remove entries from this list when disabling protocols! */ typedef enum { UNKNOWN = -1, UNUSED = 0, AIWA_RC_T501, BOSEWAVE, DENON, DISH, JVC, LEGO_PF, LG, MAGIQUEST, MITSUBISHI, NEC_STANDARD, NEC, PANASONIC, RC5, RC6, SAMSUNG, SANYO, SHARP, SHARP_ALT, SONY, WHYNTER, } decode_type_t; /** * Comment this out for lots of lovely debug output. */ //#define DEBUG //------------------------------------------------------------------------------ // Debug directives // #ifdef DEBUG # define DBG_PRINT(...) Serial.print(__VA_ARGS__) # define DBG_PRINTLN(...) Serial.println(__VA_ARGS__) #else /** * If DEBUG, print the arguments, otherwise do nothing. */ # define DBG_PRINT(...) void() /** * If DEBUG, print the arguments as a line, otherwise do nothing. */ # define DBG_PRINTLN(...) void() #endif //------------------------------------------------------------------------------ // Helper macro for getting a macro definition as string // #define STR_HELPER(x) #x #define STR(x) STR_HELPER(x) //------------------------------------------------------------------------------ // Mark & Space matching functions // int MATCH(int measured, int desired); int MATCH_MARK(int measured_ticks, int desired_us); int MATCH_SPACE(int measured_ticks, int desired_us); /**************************************************** * RECEIVING ****************************************************/ /** * Results returned from the decoder */ struct decode_results { decode_type_t decode_type; ///< UNKNOWN, NEC, SONY, RC5, ... unsigned int address; ///< Used by Panasonic & Sharp6 NEC_standard [16-bits] unsigned long value; ///< Decoded value / command [max 32-bits] int bits; ///< Number of bits in decoded value unsigned int magnitude; ///< Used by MagiQuest [16-bits] bool isRepeat; ///< True if repeat of value is detected // next 3 values are copies of irparams values unsigned int *rawbuf; ///< Raw intervals in 50uS ticks unsigned int rawlen; ///< Number of records in rawbuf bool overflow; ///< true if IR raw code too long }; /** * DEPRECATED * Decoded value for NEC and others when a repeat code is received * Use Flag decode_results.isRepeat (see above) instead */ #define REPEAT 0xFFFFFFFF /** * Main class for receiving IR */ class IRrecv { public: /** * Instantiate the IRrecv class. Multiple instantiation is not supported. * @param recvpin Arduino pin to use. No sanity check is made. */ IRrecv(int recvpin); /** * Instantiate the IRrecv class. Multiple instantiation is not supported. * @param recvpin Arduino pin to use, where a demodulating IR receiver is connected. * @param blinkpin pin to blink when receiving IR. Not supported by all hardware. No sanity check is made. */ IRrecv(int recvpin, int blinkpin); /** * TODO: Why is this public??? * @param blinkflag */ void blink13(int blinkflag); /** * Attempt to decode the recently receive IR signal * @param results decode_results instance returning the decode, if any. * @return success of operation. */ bool decode(decode_results *aResults);__attribute__ ((deprecated ("You should use decode() without a parameter."))) ; // deprecated bool decode(); /** * Enable IR reception. */ void enableIRIn(); /** * Disable IR reception. */ void disableIRIn(); /** * Returns status of reception * @return true if no reception is on-going. */ bool isIdle(); /** * Returns status of reception and copies IR-data to decode_results buffer if true. * @return true if data is available. */ bool available(); /** * Called to re-enable IR reception. */ void resume(); const char* getProtocolString(); void printResultShort(Print * aSerial); /** * Print the result (second argument) as Pronto Hex on the Stream supplied as argument. * @param stream The Stream on which to write, often Serial * @param results the decode_results as delivered from irrecv.decode. * @param frequency Modulation frequency in Hz. Often 38000Hz. */ void dumpPronto(Stream& stream, unsigned int frequency = 38000U); unsigned long decodePulseDistanceData(uint8_t aNumberOfBits, uint8_t aStartOffset, unsigned int aBitMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroSpaceMicros, bool aMSBfirst = true); decode_results results; // the instance for decoding private: #if DECODE_HASH bool decodeHash(); bool decodeHash(decode_results *aResults); int compare(unsigned int oldval, unsigned int newval); #endif //...................................................................... #if DECODE_RC5 /** * Try to decode the recently received IR signal as an RC5 signal- * @param results decode_results instance returning the decode, if any. * @return Success of the operation. */ bool decodeRC5(); bool decodeRC5(decode_results *aResults); #endif #if DECODE_RC6 bool decodeRC6(); bool decodeRC6(decode_results *aResults); #endif //...................................................................... #if DECODE_NEC bool decodeNEC(); bool decodeNEC(decode_results *aResults); #endif #if DECODE_NEC_STANDARD bool decodeNECStandard(); #endif //...................................................................... #if DECODE_SONY bool decodeSony(); bool decodeSony(decode_results *aResults); #endif //...................................................................... #if DECODE_PANASONIC bool decodePanasonic(); bool decodePanasonic(decode_results *aResults); #endif //...................................................................... #if DECODE_JVC bool decodeJVC(); bool decodeJVC(decode_results *aResults); #endif //...................................................................... #if DECODE_SAMSUNG bool decodeSAMSUNG(); bool decodeSAMSUNG(decode_results *aResults); #endif //...................................................................... #if DECODE_WHYNTER bool decodeWhynter(); bool decodeWhynter(decode_results *aResults); #endif //...................................................................... #if DECODE_AIWA_RC_T501 bool decodeAiwaRCT501(); bool decodeAiwaRCT501(decode_results *aResults); #endif //...................................................................... #if DECODE_LG bool decodeLG(); bool decodeLG(decode_results *aResults); #endif //...................................................................... #if DECODE_SANYO bool decodeSanyo(); bool decodeSanyo(decode_results *aResults); #endif //...................................................................... #if DECODE_MITSUBISHI bool decodeMitsubishi(); bool decodeMitsubishi(decode_results *aResults); #endif //...................................................................... #if DECODE_DISH bool decodeDish () ; // NOT WRITTEN #endif //...................................................................... #if DECODE_SHARP bool decodeSharp(); bool decodeSharp(decode_results *aResults); #endif #if DECODE_SHARP_ALT bool decodeSharpAlt(); bool decodeSharpAlt(decode_results *aResults); #endif //...................................................................... #if DECODE_DENON bool decodeDenon(); bool decodeDenon(decode_results *aResults); #endif //...................................................................... #if DECODE_LEGO_PF bool decodeLegoPowerFunctions (decode_results *aResults) ; #endif //...................................................................... #if DECODE_BOSEWAVE bool decodeBoseWave(); bool decodeBoseWave(decode_results *aResults); #endif //...................................................................... #if DECODE_MAGIQUEST bool decodeMagiQuest(); bool decodeMagiQuest(decode_results *aResults); #endif }; /**************************************************** * SENDING ****************************************************/ /** * Define to use no carrier PWM, just simulate an active low receiver signal. */ //#define USE_NO_SEND_PWM /** * Define to use carrier PWM generation in software, instead of hardware PWM. */ //#define USE_SOFT_SEND_PWM /** * If USE_SOFT_SEND_PWM, this amount is subtracted from the on-time of the pulses. */ #ifndef PULSE_CORRECTION_MICROS #define PULSE_CORRECTION_MICROS 3 #endif /** * If USE_SOFT_SEND_PWM, use spin wait instead of delayMicros(). */ //#define USE_SPIN_WAIT /** * Main class for sending IR */ class IRsend { public: #if defined(USE_SOFT_SEND_PWM) || defined(USE_NO_SEND_PWM) IRsend(int pin = IR_SEND_PIN) { sendPin = pin; } #else IRsend() { } #endif void custom_delay_usec(unsigned long uSecs); void enableIROut(int khz); void sendPulseDistanceWidthData(unsigned int aOneMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroMarkMicros, unsigned int aZeroSpaceMicros, unsigned long aData, uint8_t aNumberOfBits, bool aMSBfirst = true); void mark(unsigned int usec); void space(unsigned int usec); void sendRaw(const unsigned int buf[], unsigned int len, unsigned int hz); void sendRaw_P(const unsigned int buf[], unsigned int len, unsigned int hz); //...................................................................... #if SEND_RC5 void sendRC5(unsigned long data, int nbits); void sendRC5ext(uint8_t addr, uint8_t cmd, boolean toggle); #endif #if SEND_RC6 void sendRC6(unsigned long data, int nbits); #endif //...................................................................... #if SEND_NEC || SEND_NEC_STANDARD void sendNECRepeat(); #endif #if SEND_NEC void sendNEC(unsigned long data, int nbits, bool repeat = false); #endif #if SEND_NEC_STANDARD void sendNECStandard(uint16_t aAddress, uint8_t aCommand, uint8_t aNumberOfRepeats = 0); #endif //...................................................................... #if SEND_SONY void sendSony(unsigned long data, int nbits); #endif //...................................................................... #if SEND_PANASONIC void sendPanasonic(unsigned int address, unsigned long data); #endif //...................................................................... #if SEND_JVC // JVC does NOT repeat by sending a separate code (like NEC does). // The JVC protocol repeats by skipping the header. // To send a JVC repeat signal, send the original code value // and set 'repeat' to true void sendJVC(unsigned long data, int nbits, bool repeat = false); #endif //...................................................................... #if SEND_SAMSUNG void sendSAMSUNG(unsigned long data, int nbits); #endif //...................................................................... #if SEND_WHYNTER void sendWhynter(unsigned long data, int nbits); #endif //...................................................................... #if SEND_AIWA_RC_T501 void sendAiwaRCT501(int code); #endif //...................................................................... #if SEND_LG void sendLG(unsigned long data, int nbits); #endif //...................................................................... #if SEND_SANYO void sendSanyo ( ) ; // NOT WRITTEN #endif //...................................................................... #if SEND_MISUBISHI void sendMitsubishi ( ) ; // NOT WRITTEN #endif //...................................................................... #if SEND_DISH void sendDISH(unsigned long data, int nbits); #endif //...................................................................... #if SEND_SHARP void sendSharpRaw(unsigned long data, int nbits); void sendSharp(unsigned int address, unsigned int command); #endif #if SEND_SHARP_ALT void sendSharpAltRaw(unsigned int data, int nbits); void sendSharpAlt(uint8_t address, uint8_t command); #endif //...................................................................... #if SEND_DENON void sendDenon(unsigned long data, int nbits); #endif //...................................................................... #if SEND_LEGO_PF void sendLegoPowerFunctions(uint16_t data, bool repeat = true); #endif //...................................................................... #if SEND_BOSEWAVE void sendBoseWave(unsigned char code); #endif //...................................................................... #if SEND_MAGIQUEST void sendMagiQuest(unsigned long wand_id, unsigned int magnitude); #endif /** * Parse the string given as Pronto Hex, and send it a number of times given * as the second argument. Thereby the division of the Pronto Hex into * an intro-sequence and a repeat sequence is taken into account: * First the intro sequence is sent, then the repeat sequence is sent times-1 times. * However, if the intro sequence is empty, the repeat sequence is sent times times. * Reference. * * Note: Using this function is very wasteful for the memory consumption on * a small board. * Normally it is a much better ide to use a tool like e.g. IrScrutinizer * to transform Pronto type signals offline * to a more memory efficient format. * * @param prontoHexString C type string (null terminated) containing a Pronto Hex representation. * @param times Number of times to send the signal. */ void sendPronto(const char* prontoHexString, unsigned int times = 1U); void sendPronto(const uint16_t* data, unsigned int length, unsigned int times = 1U); #if HAS_FLASH_READ || defined(DOXYGEN) void sendPronto_PF(uint_farptr_t str, unsigned int times = 1U); /** * Version of sendPronto that reads from PROGMEM, saving RAM memory. * @param pronto C type string (null terminated) containing a Pronto Hex representation. * @param times Number of times to send the signal. */ void sendPronto_PF(const char *str, unsigned int times = 1U); void sendPronto(const __FlashStringHelper *str, unsigned int times = 1U); #endif private: #if (DECODE_RC5 || DECODE_RC6) /** * This helper function is shared by RC5 and RC6 */ int getRClevel(decode_results *results, unsigned int *offset, int *used, int t1); #endif #if defined(USE_SOFT_SEND_PWM) || defined(USE_NO_SEND_PWM) int sendPin; # if defined(USE_SOFT_SEND_PWM) unsigned int periodTimeMicros; unsigned int periodOnTimeMicros; void sleepMicros(unsigned long us); void sleepUntilMicros(unsigned long targetTime); # endif #else const int sendPin = IR_SEND_PIN; #endif }; #endif // IRremote_h