daily_automated
This commit is contained in:
206
trunk/Arduino/libraries/IRremote/src/irSend.cpp
Normal file
206
trunk/Arduino/libraries/IRremote/src/irSend.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
#include "IRremote.h"
|
||||
|
||||
#ifdef SENDING_SUPPORTED // from IRremoteBoardDefs.h
|
||||
//+=============================================================================
|
||||
void IRsend::sendRaw(const unsigned int buf[], unsigned int len, unsigned int hz) {
|
||||
// Set IR carrier frequency
|
||||
enableIROut(hz);
|
||||
|
||||
for (unsigned int i = 0; i < len; i++) {
|
||||
if (i & 1) {
|
||||
space(buf[i]);
|
||||
} else {
|
||||
mark(buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
space(0); // Always end with the LED off
|
||||
}
|
||||
|
||||
void IRsend::sendRaw_P(const unsigned int buf[], unsigned int len, unsigned int hz) {
|
||||
#if !defined(__AVR__)
|
||||
sendRaw(buf,len,hz); // Let the function work for non AVR platforms
|
||||
#else
|
||||
// Set IR carrier frequency
|
||||
enableIROut(hz);
|
||||
|
||||
for (unsigned int i = 0; i < len; i++) {
|
||||
uint16_t duration = pgm_read_word_near(buf + sizeof(uint16_t) * i);
|
||||
if (i & 1) {
|
||||
space(duration);
|
||||
} else {
|
||||
mark(duration);
|
||||
}
|
||||
}
|
||||
space(0); // Always end with the LED off
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef USE_SOFT_SEND_PWM
|
||||
void inline IRsend::sleepMicros(unsigned long us) {
|
||||
#ifdef USE_SPIN_WAIT
|
||||
sleepUntilMicros(micros() + us);
|
||||
#else
|
||||
if (us > 0U) { // Is this necessary? (Official docu https://www.arduino.cc/en/Reference/DelayMicroseconds does not tell.)
|
||||
delayMicroseconds((unsigned int) us);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void inline IRsend::sleepUntilMicros(unsigned long targetTime) {
|
||||
#ifdef USE_SPIN_WAIT
|
||||
while (micros() < targetTime)
|
||||
;
|
||||
#else
|
||||
unsigned long now = micros();
|
||||
if (now < targetTime) {
|
||||
sleepMicros(targetTime - now);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif // USE_SOFT_SEND_PWM
|
||||
|
||||
//+=============================================================================
|
||||
// Sends PulseDistance data from MSB to LSB
|
||||
//
|
||||
void IRsend::sendPulseDistanceWidthData(unsigned int aOneMarkMicros, unsigned int aOneSpaceMicros, unsigned int aZeroMarkMicros,
|
||||
unsigned int aZeroSpaceMicros, unsigned long aData, uint8_t aNumberOfBits, bool aMSBfirst) {
|
||||
|
||||
if (aMSBfirst) { // Send the MSB first.
|
||||
// send data from MSB to LSB until mask bit is shifted out
|
||||
for (unsigned long mask = 1UL << (aNumberOfBits - 1); mask; mask >>= 1) {
|
||||
if (aData & mask) {
|
||||
DBG_PRINT("1");
|
||||
mark(aOneMarkMicros);
|
||||
space(aOneSpaceMicros);
|
||||
} else {
|
||||
DBG_PRINT("0");
|
||||
mark(aZeroMarkMicros);
|
||||
space(aZeroSpaceMicros);
|
||||
}
|
||||
}
|
||||
DBG_PRINTLN("");
|
||||
}
|
||||
#if defined(LSB_FIRST_REQUIRED)
|
||||
else { // Send the Least Significant Bit (LSB) first / MSB last.
|
||||
for (uint16_t bit = 0; bit < aNumberOfBits; bit++, aData >>= 1)
|
||||
if (aData & 1) { // Send a 1
|
||||
DBG_PRINT("1");
|
||||
mark(aOneMarkMicros);
|
||||
space(aOneSpaceMicros);
|
||||
} else { // Send a 0
|
||||
DBG_PRINT("0");
|
||||
mark(aZeroMarkMicros);
|
||||
space(aZeroSpaceMicros);
|
||||
}
|
||||
DBG_PRINTLN("");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//+=============================================================================
|
||||
// Sends an IR mark for the specified number of microseconds.
|
||||
// The mark output is modulated at the PWM frequency.
|
||||
//
|
||||
|
||||
void IRsend::mark(unsigned int time) {
|
||||
#ifdef USE_SOFT_SEND_PWM
|
||||
unsigned long start = micros();
|
||||
unsigned long stop = start + time;
|
||||
if (stop + periodTimeMicros < start) {
|
||||
// Counter wrap-around, happens very seldomly, but CAN happen.
|
||||
// Just give up instead of possibly damaging the hardware.
|
||||
return;
|
||||
}
|
||||
unsigned long nextPeriodEnding = start;
|
||||
unsigned long now = micros();
|
||||
while (now < stop) {
|
||||
SENDPIN_ON(sendPin);
|
||||
sleepMicros (periodOnTimeMicros);
|
||||
SENDPIN_OFF(sendPin);
|
||||
nextPeriodEnding += periodTimeMicros;
|
||||
sleepUntilMicros(nextPeriodEnding);
|
||||
now = micros();
|
||||
}
|
||||
#elif defined(USE_NO_SEND_PWM)
|
||||
digitalWrite(sendPin, LOW); // Set output to active low.
|
||||
#else
|
||||
TIMER_ENABLE_SEND_PWM; // Enable pin 3 PWM output
|
||||
#endif
|
||||
if (time > 0) {
|
||||
custom_delay_usec(time);
|
||||
}
|
||||
}
|
||||
|
||||
//+=============================================================================
|
||||
// Leave pin off for time (given in microseconds)
|
||||
// Sends an IR space for the specified number of microseconds.
|
||||
// A space is no output, so the PWM output is disabled.
|
||||
//
|
||||
void IRsend::space(unsigned int time) {
|
||||
#if defined(USE_NO_SEND_PWM)
|
||||
digitalWrite(sendPin, HIGH); // Set output to inactive high.
|
||||
#else
|
||||
TIMER_DISABLE_SEND_PWM; // Disable pin 3 PWM output
|
||||
#endif
|
||||
if (time > 0) {
|
||||
IRsend::custom_delay_usec(time);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_DEFAULT_ENABLE_IR_OUT
|
||||
//+=============================================================================
|
||||
// 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.
|
||||
//
|
||||
void IRsend::enableIROut(int khz) {
|
||||
#ifdef USE_SOFT_SEND_PWM
|
||||
periodTimeMicros = (1000U + khz / 2) / khz; // = 1000/khz + 1/2 = round(1000.0/khz)
|
||||
periodOnTimeMicros = periodTimeMicros * IR_SEND_DUTY_CYCLE / 100U - PULSE_CORRECTION_MICROS;
|
||||
#endif
|
||||
|
||||
#if defined(USE_NO_SEND_PWM)
|
||||
pinMode(sendPin, OUTPUT);
|
||||
digitalWrite(sendPin, HIGH); // Set output to inactive high.
|
||||
#else
|
||||
// Disable the Timer2 Interrupt (which is used for receiving IR)
|
||||
TIMER_DISABLE_RECEIVE_INTR; //Timer2 Overflow Interrupt
|
||||
|
||||
pinMode(sendPin, OUTPUT);
|
||||
|
||||
SENDPIN_OFF(sendPin); // When not sending, we want it low
|
||||
|
||||
timerConfigForSend(khz);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
//+=============================================================================
|
||||
// Custom delay function that circumvents Arduino's delayMicroseconds limit
|
||||
|
||||
void IRsend::custom_delay_usec(unsigned long uSecs) {
|
||||
if (uSecs > 4) {
|
||||
unsigned long start = micros();
|
||||
unsigned long endMicros = start + uSecs - 4;
|
||||
if (endMicros < start) { // Check if overflow
|
||||
while (micros() > start) {
|
||||
} // wait until overflow
|
||||
}
|
||||
while (micros() < endMicros) {
|
||||
} // normal wait
|
||||
}
|
||||
//else {
|
||||
// __asm__("nop\n\t"); // must have or compiler optimizes out
|
||||
//}
|
||||
}
|
||||
|
||||
#endif // SENDING_SUPPORTED
|
||||
Reference in New Issue
Block a user