/* * This file contains all of the building-block routines for doing IR (infrared) * transmitting and receiving, currently using just a 38kHz center-frequency and * a standard bit-length-encoded over-the-air protocol. * * It provides three levels of abstraction, depending on the amount of control desired * by the application. * * At the highest level for applications that only need to send numeric data, * IRSendDigit() and IRReceiveDigit() may be used to send/receive byte-at-a-time data. * * At the next lower-level, applications can use IRSend() and IRReceive() to send/recieve * arbitrary length bit patterns (up to the length of bits in an "unsigned long"). * * At the lowest-level, applications can assemble their own over-the-air protocol by * generating individual pulses with lengths of their own choosing. * * Finally, a few utility routines are provided that may be used to return the lower-level * data that was collected when receiving an IR burst. For instance, the sense and length of * the individual pulses in the burst can be retrieved to assist in decoding other bit-length- * encoded keys or protocols. * * Written by Eric B. Wertz * Last modified 2010/04/07 */ #ifndef IR_H_INCLUDED #define IR_H_INCLUDED /* * Send a single digit over IR using a simple, robust interface and encoding protocol. * This routine is intended to be used to send data to an application using IRReceiveDigit() * on the other side. * * The over-the-air protocol is that same as that used by Sony 12-bit TV remotes. For * robustness, it sends three copies of the requested digit, which IRReceiveDigit() * handles transparently and turns into a single received digit on its end. Internally, * it uses IRSend() to do the heavy-lifting. * * Parameters: * [IN] pin Arduino pin number for the IR transmitter * [IN] digit the digit to send, must be 0..9 */ #ifdef PROTOTYPES void IRSendDigit(byte pin, byte digit); #endif /* * Receive a single digit over IR. The received may be sent by IRSendDigit(), or by a * remote control that is using the Sony 12-bit TV protocol. * * This routine handles receiving transmissions that are duplicated in close proximity * to each other (which is to say that it filters-out auto key-repeat). Internally, * it uses IRReceive() to do the heavy-lifting. * * Parameters: * [IN] pin Arduino pin number for the IR transmitter * [IN] timeoutUsecs the number of microseconds to wait for a burst of input * * Returns: * 0..9 if successful * IRRECV_TVDIGIT_TIMEOUT if no burst received in "timeout" microseconds * IRRECV_TVDIGIT_FAILURE if burst is unrecognized/corrupt */ #define IRRECV_TVDIGIT_TIMEOUT 254 #define IRRECV_TVDIGIT_FAILURE 255 #ifdef PROTOTYPES byte IRReceiveDigit(byte pin, unsigned long timeoutUsecs); #endif /* * Send a burst (a single keycode) of IR data, right-justified in the data parameter. * The burst preamble is sent first, followed by the numBits data bits, most significant * bit first). * * Parameters: * [IN] pin Arduino pin number for the IR transmitter * [IN] data the binary code for the burst is returned * [IN] numBits the number of bits in "data" */ #ifdef PROTOTYPES void IRSend(byte pin, unsigned long data, byte numBits); #endif /* * Receive a burst (a single keycode) of IR data. * * Parameters: * [IN] pin Arduino pin number for the IR transmitter * [IN] timeoutUsecs the number of microseconds to wait for a burst of input * [OUT] pData location in which the binary code for the burst is returned * [OUT] pNumBits the number of bits that were received and placed in pData * * Returns: * IRRECV_SUCCESS if successful * IRRECV_TIMEOUT if no burst received in "timeout" microseconds * IRRECV_OVERFLOW if the burst is too many bits to fit in an unsigned long * IRRECV_FAILURE if burst is unrecognized/corrupt */ #define IRRECV_SUCCESS 0 #define IRRECV_TIMEOUT 1 #define IRRECV_OVERFLOW 2 #define IRRECV_FAILURE 3 #ifdef PROTOTYPES byte IRReceive(byte pin, unsigned long timeoutUsecs, unsigned long *pData, byte *pNumBits); #endif /* * Generate a single, high pulse. The generated pulse immediately goes high * goes high and then falls after the specified length of time. * It is the responsibility of the caller to time the low segment of the pulse. * * * Parameters: * [IN] pin Arduino pin number for the IR transmitter * [IN] usecs the number of microseconds hold the pulse high before pulling it down * Returns: * 0..9 data digit * BURSTINTVDIGIT_TIMEOUT if no burst received in "timeout" microseconds * BURSTINTVDIGIT_FAILURE if burst is unrecognized/corrupt */ #ifdef PROTOTYPES void IRSendPulse(byte pin, unsigned int usecs); #endif /* * Get the pulse length data from the last incoming pulse. * * The tricky thing to remember here is that the array return value contains one more * pulse length entry because of the presence of the preamble pulse. So, when numPulses * is reported to be 9 (as in the example below), only the rightmost eight bits returned * pData are valid. * * For example, if the following is returned from IRGetLastPulseData(): * *pNumPulses = 9 * *pData = 00000000 00000000 00000000 10010100 * return value[] = {2400,1300.700,770,1290,666,1250,777,1000} * * this means that the array contains 9 entries, but only the rightmost bits in *pData * are useful. But also note that because the length of the last pulse does not * correspond to either a valid 0 or 1 pulse, you cannot trust the final bit in *pData. * * Parameters: * [OUT] pNumBits location in which the number of received pulses is returned * [OUT] pData location in which binary value of the entire burst is returned * Returns: * A pointer to the array of pulse-length data, in microseconds */ #ifdef PROTOTYPES unsigned int *IRGetLastPulseData(byte *pNumPulses, unsigned long *pData) #endif /* * Using Serial, print out all the data that is returned by IRGetLastPulseData (which * is called internal to this function). * * Note that because this uses Serial, it probably takes tens of microseconds to run. */ #ifdef PROTOTYPES void printPulseData(); #endif #endif /* !IR_H_INCLUDED */