/* Leave pin off for time (given in microseconds) */void IRsend::space(int time) { // Sends an IR space for the specified number of microseconds. // A space is no output, so the PWM output is disabled. TIMER_DISABLE_PWM; // Disable pin 3 PWM output delayMicroseconds(time);}

void IRsend::enableIROut(int khz) { // Enables IR output. The khz value controls the modulation frequency in kilohertz. // The IR output will be on pin 3 (OC2B). // This routine is designed for 36-40KHz; if you use it for other values, it's up to you // to make sure it gives reasonable results. (Watch out for overflow / underflow / rounding.) // TIMER2 is used in phase-correct PWM mode, with OCR2A controlling the frequency and OCR2B // controlling the duty cycle. // There is no prescaling, so the output frequency is 16MHz / (2 * OCR2A) // To turn the output on and off, we leave the PWM running, but connect and disconnect the output pin. // A few hours staring at the ATmega documentation and this will all make sense. // See my Secrets of Arduino PWM at http://arcfn.com/2009/07/secrets-of-arduino-pwm.html for details.

// TIMER2 interrupt code to collect raw data.// Widths of alternating SPACE, MARK are recorded in rawbuf.// Recorded in ticks of 50 microseconds.// rawlen counts the number of entries recorded so far.// First entry is the SPACE between transmissions.// As soon as a SPACE gets long, ready is set, state switches to IDLE, timing of SPACE continues.// As soon as first MARK arrives, gap width is recorded, ready is cleared, and new logging startsISR(TIMER_INTR_NAME){ TIMER_RESET;

// Gets one undecoded level 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 getRClevel will return MARK, MARK, SPACE.// offset and used are updated to keep track of the current position.// t1 is the time interval for a single bit in microseconds.// Returns -1 for error (measured time interval is not a multiple of t1).int IRrecv::getRClevel(decode_results *results, int *offset, int *used, int t1) { if (*offset >= results->rawlen) { // After end of recorded buffer, assume SPACE. return SPACE; } int width = results->rawbuf[*offset]; int val = ((*offset) % 2) ? MARK : SPACE; int correction = (val == MARK) ? MARK_EXCESS : - MARK_EXCESS;

/* ----------------------------------------------------------------------- * hashdecode - decode an arbitrary IR code. * 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. Hszh 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. * * http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html */