#define OUT_PIN 9 // Выходной сигнал (D9)
#define In_3 3 // Управление таймером (D3)
#define LED_PIN 13 // Импульсный выход (D13)
#define In_2 2 // Управление импульсом (D2)
#define POT_PIN A0 // Переменный резистор (A0)
volatile bool timerRunning = false; // Флаг работы таймера
volatile bool timer1Enabled = false; // Флаг разрешения работы таймера 1
volatile bool pulseActive = false; // Флаг работы импульса
volatile uint16_t pulseCounter = 0; // Счётчик миллисекунд для D13
volatile int potValue = 0; // Значение с переменного резистора (A0)
volatile bool readPot = false; // Флаг для считывания с A0
volatile bool timer2Stopped = false; // Флаг остановки таймера 2
volatile uint32_t timer2StopTime = 0; // Время остановки таймера 2
volatile bool timer2Completed = false; // Флаг, что таймер 2 отработал
volatile bool timer1Completed = false; // Флаг, что таймер 1 отработал
void setup() {
Serial.begin(9600); // Инициализация Serial для вывода в консоль
pinMode(OUT_PIN, OUTPUT);
pinMode(In_3, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
pinMode(In_2, INPUT_PULLUP);
pinMode(POT_PIN, INPUT); // Настройка A0 как входа
attachInterrupt(digitalPinToInterrupt(In_3), controlTimer, CHANGE); // D3 управляет таймером
attachInterrupt(digitalPinToInterrupt(In_2), startPulse, FALLING); // D2 запускает импульс по спаду
// === Таймер 1 (1 Гц) ===
TCCR1A = 0; // установить регистры в 0
TCCR1B = 0;
OCR1A = 15624; // установка регистра совпадения
TCCR1B |= (1 << WGM12); // включение в CTC режим
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS12);
TIMSK1 |= (1 << OCIE1A); // Разрешаем прерывание по совпадению
// === Таймер 2 (1 мс) ===
TCCR2A = (1 << WGM21); // CTC
TCCR2B = (1 << CS22); // Предделитель 64 (16MHz / 64 / 250 = 1 мс)
OCR2A = 242;
TIMSK2 |= (1 << OCIE2A); // Разрешаем прерывание
digitalWrite(OUT_PIN, LOW);
digitalWrite(LED_PIN, LOW);
}
void controlTimer() {
delay(50); // Задержка для устранения дребезга
uint32_t currentTime = millis();
if (digitalRead(In_3) == HIGH) {
Serial.println("D3 HIGH"); // Вывод в консоль
if (timer2Stopped && (currentTime - timer2StopTime > 2000) && timer2Completed && !timer1Completed) {
timer1Enabled = true; // Разрешение работы таймера 1
Serial.println("Timer1 enabled");
if (timer1Enabled) {
timerRunning = true; // Запуск таймера 1
digitalWrite(OUT_PIN, HIGH); // Включение OUT_PIN
Serial.println("Timer1 started");
}
} else {
Serial.println("Conditions not met for Timer1 start");
}
} else {
Serial.println("D3 LOW"); // Вывод в консоль
if (timerRunning) {
timerRunning = false; // Остановка таймера 1
digitalWrite(OUT_PIN, LOW);
Serial.println("Timer1 stopped");
timer1Completed = true; // Устанавливаем флаг, что таймер 1 отработал
timer1Enabled = false; // Сбрасываем флаг разрешения работы таймера 1
}
}
}
void startPulse() {
if (!pulseActive && !timer2Completed) {
pulseActive = true;
pulseCounter = map(potValue, 0, 1023, 0, 3000); // От 0 до 3000 мс
digitalWrite(LED_PIN, HIGH); // Включаем D13
readPot = true; // Устанавливаем флаг для считывания с A0
Serial.println("Pulse started");
}
}
ISR(TIMER1_COMPA_vect) {
if (timerRunning) {
digitalWrite(OUT_PIN, !digitalRead(OUT_PIN)); // Мигание D9
Serial.println("TIMER1_COMPA_vect");
}
}
ISR(TIMER2_COMPA_vect) {
if (pulseActive) {
if (pulseCounter > 0) {
pulseCounter--;
} else {
digitalWrite(LED_PIN, LOW); // Выключаем D13 через 3 секунды
pulseActive = false;
timer2Completed = true; // Фиксируем, что таймер 2 отработал
timer2Stopped = true; // Фиксируем, что таймер 2 остановился
timer2StopTime = millis(); // Запоминаем время остановки таймера 2
Serial.println("Pulse completed");
}
}
if (readPot) {
potValue = analogRead(POT_PIN); // Считываем значение с A0
readPot = false; // Сбрасываем флаг, чтобы не считывать постоянно
}
}
void loop() {
// Основной код не нужен, всё работает через прерывания
// Опрос переменного резистора
if (!pulseActive && !readPot) {
potValue = analogRead(POT_PIN); // Считываем значение с A0
readPot = true; // Устанавливаем флаг, чтобы не считывать повторно
}
}