Infrared remote library for Arduino: send and receive infrared signals with multiple protocols Port from Arduino-IRremote https://github.com/z3t0/Arduino-IRremote
irSend.cpp@8:0650578366fd, 2019-06-16 (annotated)
- Committer:
- eunmango
- Date:
- Sun Jun 16 04:36:58 2019 +0000
- Revision:
- 8:0650578366fd
- Parent:
- 6:ee990cddff48
dd
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
yuhki50 | 0:70c8e56bac45 | 1 | #include "IRremote.h" |
yuhki50 | 0:70c8e56bac45 | 2 | #include "IRremoteInt.h" |
yuhki50 | 6:ee990cddff48 | 3 | #include "cmath" |
yuhki50 | 0:70c8e56bac45 | 4 | |
yuhki50 | 0:70c8e56bac45 | 5 | //+============================================================================= |
yuhki50 | 0:70c8e56bac45 | 6 | void IRsend::sendRaw (unsigned int buf[], unsigned int len, unsigned int hz) |
yuhki50 | 0:70c8e56bac45 | 7 | { |
yuhki50 | 0:70c8e56bac45 | 8 | // Set IR carrier frequency |
yuhki50 | 0:70c8e56bac45 | 9 | enableIROut(hz); |
yuhki50 | 0:70c8e56bac45 | 10 | |
yuhki50 | 0:70c8e56bac45 | 11 | for (unsigned int i = 0; i < len; i++) { |
yuhki50 | 0:70c8e56bac45 | 12 | if (i & 1) space(buf[i]) ; |
yuhki50 | 0:70c8e56bac45 | 13 | else mark (buf[i]) ; |
yuhki50 | 0:70c8e56bac45 | 14 | } |
yuhki50 | 0:70c8e56bac45 | 15 | |
yuhki50 | 0:70c8e56bac45 | 16 | space(0); // Always end with the LED off |
yuhki50 | 0:70c8e56bac45 | 17 | } |
yuhki50 | 0:70c8e56bac45 | 18 | |
yuhki50 | 0:70c8e56bac45 | 19 | //+============================================================================= |
yuhki50 | 0:70c8e56bac45 | 20 | // Sends an IR mark for the specified number of microseconds. |
yuhki50 | 0:70c8e56bac45 | 21 | // The mark output is modulated at the PWM frequency. |
yuhki50 | 0:70c8e56bac45 | 22 | // |
yuhki50 | 0:70c8e56bac45 | 23 | void IRsend::mark (unsigned int time) |
yuhki50 | 0:70c8e56bac45 | 24 | { |
yuhki50 | 3:17440cf7ab90 | 25 | _pwm.write(0.5); // Enable PWM output |
yuhki50 | 0:70c8e56bac45 | 26 | if (time > 0) custom_delay_usec(time); |
yuhki50 | 0:70c8e56bac45 | 27 | } |
yuhki50 | 0:70c8e56bac45 | 28 | |
yuhki50 | 0:70c8e56bac45 | 29 | //+============================================================================= |
yuhki50 | 0:70c8e56bac45 | 30 | // Leave pin off for time (given in microseconds) |
yuhki50 | 0:70c8e56bac45 | 31 | // Sends an IR space for the specified number of microseconds. |
yuhki50 | 0:70c8e56bac45 | 32 | // A space is no output, so the PWM output is disabled. |
yuhki50 | 0:70c8e56bac45 | 33 | // |
yuhki50 | 0:70c8e56bac45 | 34 | void IRsend::space (unsigned int time) |
yuhki50 | 0:70c8e56bac45 | 35 | { |
yuhki50 | 3:17440cf7ab90 | 36 | _pwm.write(0.0); // Disable PWM output |
yuhki50 | 0:70c8e56bac45 | 37 | if (time > 0) IRsend::custom_delay_usec(time); |
yuhki50 | 0:70c8e56bac45 | 38 | } |
yuhki50 | 0:70c8e56bac45 | 39 | |
yuhki50 | 0:70c8e56bac45 | 40 | //+============================================================================= |
yuhki50 | 0:70c8e56bac45 | 41 | // Enables IR output. The khz value controls the modulation frequency in kilohertz. |
yuhki50 | 0:70c8e56bac45 | 42 | // The IR output will be on pin 3 (OC2B). |
yuhki50 | 0:70c8e56bac45 | 43 | // This routine is designed for 36-40KHz; if you use it for other values, it's up to you |
yuhki50 | 0:70c8e56bac45 | 44 | // to make sure it gives reasonable results. (Watch out for overflow / underflow / rounding.) |
yuhki50 | 0:70c8e56bac45 | 45 | // TIMER2 is used in phase-correct PWM mode, with OCR2A controlling the frequency and OCR2B |
yuhki50 | 0:70c8e56bac45 | 46 | // controlling the duty cycle. |
yuhki50 | 0:70c8e56bac45 | 47 | // There is no prescaling, so the output frequency is 16MHz / (2 * OCR2A) |
yuhki50 | 0:70c8e56bac45 | 48 | // To turn the output on and off, we leave the PWM running, but connect and disconnect the output pin. |
yuhki50 | 0:70c8e56bac45 | 49 | // A few hours staring at the ATmega documentation and this will all make sense. |
yuhki50 | 0:70c8e56bac45 | 50 | // See my Secrets of Arduino PWM at http://arcfn.com/2009/07/secrets-of-arduino-pwm.html for details. |
yuhki50 | 0:70c8e56bac45 | 51 | // |
yuhki50 | 0:70c8e56bac45 | 52 | void IRsend::enableIROut (int khz) |
yuhki50 | 0:70c8e56bac45 | 53 | { |
yuhki50 | 3:17440cf7ab90 | 54 | _pwm.write(0.0); |
yuhki50 | 6:ee990cddff48 | 55 | _pwm.period_us(std::floor((1.0 / khz * 1000) + 0.5)); // round |
yuhki50 | 0:70c8e56bac45 | 56 | } |
yuhki50 | 0:70c8e56bac45 | 57 | |
yuhki50 | 0:70c8e56bac45 | 58 | //+============================================================================= |
yuhki50 | 0:70c8e56bac45 | 59 | // Custom delay function that circumvents Arduino's delayMicroseconds limit |
yuhki50 | 0:70c8e56bac45 | 60 | |
yuhki50 | 0:70c8e56bac45 | 61 | void IRsend::custom_delay_usec(unsigned long uSecs) { |
yuhki50 | 0:70c8e56bac45 | 62 | if (uSecs > 4) { |
yuhki50 | 3:17440cf7ab90 | 63 | unsigned long start = us_ticker_read(); |
yuhki50 | 0:70c8e56bac45 | 64 | unsigned long endMicros = start + uSecs - 4; |
yuhki50 | 0:70c8e56bac45 | 65 | if (endMicros < start) { // Check if overflow |
yuhki50 | 3:17440cf7ab90 | 66 | while ( us_ticker_read() > start ) {} // wait until overflow |
yuhki50 | 0:70c8e56bac45 | 67 | } |
yuhki50 | 3:17440cf7ab90 | 68 | while ( us_ticker_read() < endMicros ) {} // normal wait |
yuhki50 | 0:70c8e56bac45 | 69 | } |
yuhki50 | 0:70c8e56bac45 | 70 | //else { |
yuhki50 | 0:70c8e56bac45 | 71 | // __asm__("nop\n\t"); // must have or compiler optimizes out |
yuhki50 | 0:70c8e56bac45 | 72 | //} |
yuhki50 | 0:70c8e56bac45 | 73 | } |