#include "GyverTimers.h"
#include "Bounce2.h"
#define BEEPERPIN A1 // номер порта к которому подключен потенциометр
#define TIMERFREQUENCY 4 // Частота срабатывания основного таймера, Гц
#define PINCHANNEL_1_2 12 // Пин для канала 1.2 ГГц
#define PINCHANNEL_1_5 9 // Пин для канала 1.5 ГГц
#define PINCHANNEL_2_4 8 // Пин для канала 2.4 ГГц - АНАЛОГОВЫЙ ОТ FPV
#define PINCHANNEL_5_8 11 // Пин для канала 5.8 ГГц
#define PINSTARTSTOPBTN 2 // Пин для кнопки Старт/Стоп
#define MAXTICKCOUNT_5_8 12 // Количество тактов таймера для 5.8 ГГц (1 / TIMERFREQUENCY * 12) => 3 секунды
#define MAXTICKCOUNT_FULL 20 // Количество тактов таймера одного цикла переключений для 1.2 - 2.4 ГГц (1 / TIMERFREQUENCY * 20) => 5 секунд
#define MAXTICKCOUNT_DOWN 4 // Количество тактов таймера для 1.2 - 2.4 ГГц (1 / TIMERFREQUENCY * 4) => 1 секунда
int startstopbtnStatus; // Флаг нажата/отжата кнопка старт/стоп
volatile bool bthwasPressed = false; // Признак что в текущем цикле кнопки на 1.2 - 2.4 были нажаты
volatile bool btnStatus = false; // Признак текущего состояния пинов управления 1.2 - 2.4 ГГц
volatile bool autosearchStatus = false; // Статус автопоиска
volatile uint8_t tickCount_5_8 = 0; // Текущее значение счетчика тактов для 5.8
volatile uint8_t tickCountFull = 0; // Текущее значение счетчика тактов для отжатого состояния кнопок 1.2 - 2.4 ГГц
volatile uint8_t tickCountDown = 0; // Текущее значение счетчика тактов для нажатого состояния для кнопок 1.2 - 2.4 ГГц
Bounce statrstopdebouncer = Bounce();
void setoutPin(const uint8_t pin){
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}
void reversePins(){ // Реверс значения пинов для 1.2 - 2.4 ГГц
digitalWrite(13, !digitalRead(13)); // 13 индикатор - для визуального контроля состояния пинов для 1.2 - 2.4
digitalWrite(PINCHANNEL_1_2, !digitalRead(PINCHANNEL_1_2));
digitalWrite(PINCHANNEL_1_5, !digitalRead(PINCHANNEL_1_5));
digitalWrite(PINCHANNEL_2_4, !digitalRead(PINCHANNEL_2_4));
}
void setpinsValue(const int value){ // Установка в value всех пинов кроме управляющего каналом 5.8
digitalWrite(13, value); // 13 индикатор - для визуального контроля состояния пинов для 1.2 - 2.4
digitalWrite(PINCHANNEL_1_2, value);
digitalWrite(PINCHANNEL_1_5, value);
digitalWrite(PINCHANNEL_2_4, value);
}
void setup() {
Serial.begin(115200); // Монитор состояния
setoutPin(13); // 13 индикатор - для визуального контроля состояния пинов для 1.2 - 2.4
setoutPin(PINCHANNEL_1_2);
setoutPin(PINCHANNEL_1_5);
setoutPin(PINCHANNEL_2_4);
setoutPin(PINCHANNEL_5_8);
pinMode(BEEPERPIN, INPUT); // Пин для входа бипера
pinMode(PINSTARTSTOPBTN, INPUT_PULLUP); // Пин для кнопки Старт/Стоп - с подтяжкой
statrstopdebouncer.attach(PINSTARTSTOPBTN);
statrstopdebouncer.interval(30);
statrstopdebouncer.update();
startstopbtnStatus = statrstopdebouncer.read(); // Читаем текущее состояние кнопки Старт/Стоп
Timer1.setFrequency(TIMERFREQUENCY); // Частота срабатывания таймера (4Гц)
Timer1.enableISR(); // Подключаем прерывание канала A таймера 1
if(startstopbtnStatus == LOW){ // Кнопка старт/стоп в положении стоп
Timer1.stop(); // Останавливаем таймер
Serial.println("Кнопка старт/стоп выключена");
}
else{
Timer1.pause();
Serial.println("Кнопка старт/стоп включена\nАвтопоиск выключен");
Timer1.resume();
}
}
void loop() {
//Проверяем изменилось ли состояние кнопки старт/стоп
statrstopdebouncer.update();
int currentbtnStatus = statrstopdebouncer.read();
if(currentbtnStatus != startstopbtnStatus){ // Состояние кнопки изменилось
if(currentbtnStatus == LOW){ // Кнопка старт/стов в положении стоп
Timer1.stop(); // Останавливаем таймер
autosearchStatus = false;
setpinsValue(LOW); // Устанавливаем состояния всех управляющих пинов
digitalWrite(PINCHANNEL_5_8, LOW); // в LOW
Serial.println("Кнопка старт/стоп выключена");
}
else{ // Кнопка старт/стоп в положении старт
Serial.println("Кнопка старт/стоп включена\nАвтопоиск выключен");
tickCount_5_8 = 0;
tickCountFull = 0;
tickCountDown = 0;
bthwasPressed = false;
btnStatus = false;
setpinsValue(LOW); // Устанавливаем состояния всех управляющих пинов
digitalWrite(PINCHANNEL_5_8, LOW); // в LOW
Timer1.restart(); // Запускаем таймер в работу
}
startstopbtnStatus = currentbtnStatus;
}
}
ISR(TIMER1_A) {
int beeperVal = analogRead(BEEPERPIN); // Считываем значение с бипера (длительность операции ~100 микросекунд)
if( beeperVal > 1020){ // Бипер молчит => автопоиск вЫключен
if(autosearchStatus){ // Если в данный момент автопоиск включен, выключаем его
autosearchStatus = false;
bthwasPressed = false;
btnStatus = false;
tickCount_5_8 = 0;
tickCountFull = 0;
tickCountDown = 0;
Serial.println("Автопоиск выключен");
setpinsValue(LOW); // Устанавливаем значения всех управляющих
digitalWrite(PINCHANNEL_5_8, LOW); // пинов в состояние LOW (отжатые кнопки)
}
}
else{ // Бипер пищит => автопоиск включен
if(!autosearchStatus){
autosearchStatus = true;
Serial.println("Автопоиск включен");
}
Serial.println(beeperVal);
if(++tickCountFull == MAXTICKCOUNT_FULL){ // Дошли до максимального количества тактов полного цикла
setpinsValue(LOW); // Устанавливаем пины на 1.2 - 2.4 ГГц в состояние LOW (отжимаем кнопки)
tickCountFull = 0;
tickCountDown = 0;
bthwasPressed = false;
btnStatus = false;
}
else{ // До конца полного цикла не дошли
if(!bthwasPressed){ // В текущем цикле кнопки 1.2 - 2.4 еще не нажимались
if(!btnStatus){ // Кнопки 1.2 - 2.4 в данный момент не нажаты
setpinsValue(HIGH); // Устанавливаем состояние пинов 1.2 - 2.4 в состояние HIGH (нажимаем кнопки)
tickCountDown = 0;
btnStatus = !btnStatus;
}
else{ // Кнопки 1.2 - 2.4 в данный момент нажаты
if(++tickCountDown == MAXTICKCOUNT_DOWN){ // Пора отпускать кнопку
setpinsValue(LOW); // Устанавливаем пины на 1.2 - 2.4 ГГц в состояние LOW (отжимаем кнопки)
bthwasPressed = true;
btnStatus = !btnStatus;
}
}
}
}
if(++tickCount_5_8 == MAXTICKCOUNT_5_8){ // Дошли до окончания цикла для пина, управляющего 5.8
tickCount_5_8 = 0;
digitalWrite(PINCHANNEL_5_8, !digitalRead(PINCHANNEL_5_8)); // Меняем состояние пина
}
}
}