#include "application.h" #include "Remote.h" const int Remote::dutyCycle = 50; const int Remote::carrierFrequency = 38000; const int Remote::period = (1000000 + carrierFrequency / 2) / carrierFrequency; const int Remote::highTime = period * dutyCycle / 100; const int Remote::lowTime = period - highTime; Remote::Remote(unsigned int irOutputPin, unsigned int ledPin) { this->irOutputPin = irOutputPin; this->ledPin = ledPin; pinMode(this->ledPin, OUTPUT); pinMode(this->irOutputPin, OUTPUT); this->signalTime = 0; } void Remote::mark(unsigned int length) { this->signalTime += length; // Mark ends at new signal time. unsigned long now = micros(); unsigned long dur = this->signalTime - now; // Allows for rolling time adjustment due to code execution delays. if (dur == 0) return; while ((micros() - now) < dur) { // Just wait here until time is up. digitalWriteFast(this->irOutputPin, HIGH); delayMicroseconds(this->highTime - 3); digitalWriteFast(this->irOutputPin, LOW); delayMicroseconds(this->lowTime - 4); } } void Remote::space(unsigned int length) { this->signalTime += length; // Space ends at new signal time. unsigned long now = micros(); unsigned long dur = this->signalTime - now; // Allows for rolling time adjustment due to code execution delays. if (dur == 0) return; while ((micros() - now) < dur); // Just wait here until time is up. } void Remote::transmit(unsigned int *data, size_t length) { // Indicate we are sending the signal digitalWriteFast(this->ledPin, HIGH); this->signalTime = micros(); // Keeps rolling track of signal time to avoid impact of loop & code execution delays. for (int i = 0; i < length; i++) { this->mark(data[i++]); // Also move pointer to next position. if (i < length) { this->space(data[i]); // Pointer will be moved by for loop. } } // Indicate we are finished sending the signal. digitalWriteFast(this->ledPin, LOW); // Wait 40 miliseconds seconds between each signal. // Here was cannot simply use delay when in an ISR // as it relies on interrupts iteslef casuing the // applicatio to crash. Since delayMicroseconds // instead relies on ASM NOP commands this is not // an issue. delayMicroseconds(40000); }