Infrared remote library for Arduino: send and receive infrared signals with multiple protocols Port from Arduino-IRremote https://github.com/z3t0/Arduino-IRremote

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers irSend.cpp Source File

irSend.cpp

00001 #include "IRremote.h"
00002 #include "IRremoteInt.h"
00003 #include "cmath"
00004 
00005 //+=============================================================================
00006 void  IRsend::sendRaw (unsigned int buf[],  unsigned int len,  unsigned int hz)
00007 {
00008     // Set IR carrier frequency
00009     enableIROut(hz);
00010 
00011     for (unsigned int i = 0;  i < len;  i++) {
00012         if (i & 1)  space(buf[i]) ;
00013         else        mark (buf[i]) ;
00014     }
00015 
00016     space(0);  // Always end with the LED off
00017 }
00018 
00019 //+=============================================================================
00020 // Sends an IR mark for the specified number of microseconds.
00021 // The mark output is modulated at the PWM frequency.
00022 //
00023 void  IRsend::mark (unsigned int time)
00024 {
00025     _pwm.write(0.5); // Enable PWM output
00026     if (time > 0) custom_delay_usec(time);
00027 }
00028 
00029 //+=============================================================================
00030 // Leave pin off for time (given in microseconds)
00031 // Sends an IR space for the specified number of microseconds.
00032 // A space is no output, so the PWM output is disabled.
00033 //
00034 void  IRsend::space (unsigned int time)
00035 {
00036     _pwm.write(0.0); // Disable PWM output
00037     if (time > 0) IRsend::custom_delay_usec(time);
00038 }
00039 
00040 //+=============================================================================
00041 // Enables IR output.  The khz value controls the modulation frequency in kilohertz.
00042 // The IR output will be on pin 3 (OC2B).
00043 // This routine is designed for 36-40KHz; if you use it for other values, it's up to you
00044 // to make sure it gives reasonable results.  (Watch out for overflow / underflow / rounding.)
00045 // TIMER2 is used in phase-correct PWM mode, with OCR2A controlling the frequency and OCR2B
00046 // controlling the duty cycle.
00047 // There is no prescaling, so the output frequency is 16MHz / (2 * OCR2A)
00048 // To turn the output on and off, we leave the PWM running, but connect and disconnect the output pin.
00049 // A few hours staring at the ATmega documentation and this will all make sense.
00050 // See my Secrets of Arduino PWM at http://arcfn.com/2009/07/secrets-of-arduino-pwm.html for details.
00051 //
00052 void  IRsend::enableIROut (int khz)
00053 {
00054     _pwm.write(0.0);
00055     _pwm.period_us(std::floor((1.0 / khz * 1000) + 0.5));  // round
00056 }
00057 
00058 //+=============================================================================
00059 // Custom delay function that circumvents Arduino's delayMicroseconds limit
00060 
00061 void IRsend::custom_delay_usec(unsigned long uSecs) {
00062   if (uSecs > 4) {
00063     unsigned long start = us_ticker_read();
00064     unsigned long endMicros = start + uSecs - 4;
00065     if (endMicros < start) { // Check if overflow
00066       while ( us_ticker_read() > start ) {} // wait until overflow
00067     }
00068     while ( us_ticker_read() < endMicros ) {} // normal wait
00069   } 
00070   //else {
00071   //  __asm__("nop\n\t"); // must have or compiler optimizes out
00072   //}
00073 }