// Скетч для проверки приёмника TSOP
#define GENPIN 3 // пин, на который нужно подключить ИК передатчик
// поддерживается D0-D7
#define TARGET_FREQUENCY 38000 // несущая частота, Гц
#define BURST_TIME 600 // длительность цикла burst, мкс
#define GAP_TIME 600 // длительность интервала между burst, мкс
#define SIGNAL_LENGTH_TIME 80 // длительность сигнала, мс
#define SIGNAL_GAP_TIME 20 // интервал между посылками данных, мс
unsigned long timer_target; // таймер несущей
unsigned long timer_burst; // таймер burst
unsigned long timer_gap; // таймер интервала между посылками
#define BIT_TARGET 1<<0
#define BIT_BURST 1<<1
#define BIT_GAP 1<<2
byte flags; // бит 0: 0 - сигнал 0; 1 - сигнал 1;
// бит 1: 0 - находимся в gap (бит 0 должен быть равен 0);
// 1 - находимся в burst
// бит 2: 0 - находимся в signal gap (бит 1 и бит 0 должны быть равны 0);
// 1 - находимся в signal send
void setup() {
// настройка порта на вывод
pinMode(GENPIN, OUTPUT);
// включаем таймеры
timer_target = micros();
timer_burst = micros();
timer_gap = millis();
flags = 0;
}
void loop() {
// обеспечение логики работы:
// 1. В течение SIGNAL_LENGTH_TIME выполняем:
// 1.1. Генерацию несущей с TARGET_FREQUENCY в течение BURST_TIME.
// 1.2. Пауза в течение GAP_TIME.
// 1.3. Повторить с 1.1.
// 2. В течение SIGNAL_GAP_TIME - пауза.
// 3. Повторить с 1.
if (flags & BIT_BURST) {
// вход в эту ветку предполагает, что выполняется пункт 1.1 логики работы
if (micros()-timer_target >= ((unsigned long)1000000/(TARGET_FREQUENCY*2))) {
// вход в эту ветку означает, что закончился полупериод несущей частоты
flags ^= BIT_TARGET; // заменяем состояние выхода
bitWrite(PORTD, GENPIN, flags & BIT_TARGET); // выводим в соответствующий пин новое состояние
timer_target = micros(); // взводим таймер полупериода
}
if (micros()-timer_burst >= BURST_TIME) {
// вход в эту ветку означает, что п.1.1. завершился
bitWrite(PORTD, GENPIN, 0); // сбрасываем выход в 0
flags &= ~(BIT_BURST | BIT_TARGET); // обнуляем активный режим (переходим к 1.2) и состояние выхода
timer_burst = micros(); // взводим таймер на GAP_TIME
}
} else {
// вход в эту ветку предполагает, что выполняются п. 1.2 или 2 логики работы
if(flags & BIT_GAP) {
// вход в эту ветку предполагает, что выполняются п. 1.2 логики работы
if (millis()-timer_gap >= SIGNAL_LENGTH_TIME) {
// вход в эту ветку предполагает, что п. 1.2 завершился и нужно перейти к п. 2
bitWrite(PORTD, GENPIN, 0); // сбрасываем выход в 0
flags &= ~(BIT_GAP | BIT_TARGET); // обнуляем режим передачи сигнала (переходим к п. 2) и состояние выхода
timer_gap = millis(); // взводим таймер на SIGNAL_GAP_TIME
} else {
// вход в эту ветку означает продолжение выполнения п. 1.2
if (micros()-timer_burst >= GAP_TIME) {
// вход в эту ветку означает, что п. 1.2 завершился и нужно перейти к п 1.1.
bitWrite(PORTD, GENPIN, 1); // устанавливаем выход в 1
flags |= BIT_BURST | BIT_TARGET; // устанавливаем активный режим, состояние выхода 1
timer_target = timer_burst = micros(); // взводим таймеры полупериода и BURST_TIME
}
}
} else {
// вход в эту ветку предполагает, что выполняется п. 2 длгики работы
if (millis()-timer_gap >= SIGNAL_GAP_TIME) {
// вход в эту ветку предполагает, что п. 2 завершён и нужно перейти к п. 1.1.
bitWrite(PORTD, GENPIN, 1); // устанавливаем выход в 1
flags |= BIT_GAP | BIT_BURST | BIT_TARGET; // устанавливаем режим передачи сигнала, активный режим, состояние выхода 1
timer_target = timer_burst = micros(); // взводим таймеры полупериода и BURST_TIME
timer_gap = millis(); // взводим таймер SIGNAL_LENGTH_TIME
}
}
}
}