Files
SyncHome/trunk/Arduino/libraries/IRremote/src/IRremote.h

571 lines
18 KiB
C
Raw Normal View History

2023-03-17 11:59:21 +00:00
/**
* @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.
* <a href="http://www.harctoolbox.org/Glossary.html#ProntoSemantics">Reference</a>.
*
* 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