// Пины
const int pinD2 = 2;
const int pinD3 = 3;
const int ledPin = 13;
const int pwmPin = 9;
const int potPin = A0;
volatile bool startPWM = false;
volatile bool startTimer = false;
volatile bool debounceFlag = false;
volatile unsigned long debounceTime = 0;
unsigned long lastPwmToggle;
bool pwmState = false;
unsigned long kofemolka_vremja;
const unsigned long debounceDelay = 50; // Задержка для фильтрации дребезга (50 мс)
void setup() {
Serial.begin(9600); // Инициализация последовательного порта
Serial.println("Начало работы");
// Настраиваем пины с подтяжкой к плюсу
pinMode(pinD2, INPUT_PULLUP);
pinMode(pinD3, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
pinMode(pwmPin, OUTPUT);
// Настраиваем прерывания на пинах D2 и D3
attachInterrupt(digitalPinToInterrupt(pinD2), onD2Fall, FALLING);
attachInterrupt(digitalPinToInterrupt(pinD3), onD3Change, CHANGE);
// Настраиваем Timer1 для прерываний
TCCR1A = 0; // установить регистры в 0
TCCR1B = 0;
TCCR1B |= (1 << WGM12); // включение в CTC режим
TCCR1B |= (1 << CS10) | (1 << CS12); // Установка битов CS10 и CS12 на коэффициент деления 1024
TIMSK1 |= (1 << OCIE1A); // Разрешаем прерывание по совпадению
// Настраиваем Timer2 для фильтрации дребезга
TCCR2A = 0; // установить регистры в 0
TCCR2B = 0;
TCCR2B |= (1 << WGM21); // включение в CTC режим
OCR2A = 249; // Установка периода таймера (1 мс при делении на 64)
TCCR2B |= (1 << CS22); // Установка битов CS22 на коэффициент деления 64
TIMSK2 |= (1 << OCIE2A); // Разрешаем прерывание по совпадению
}
void loop() {
// Считываем значение потенциометра и определяем время
kofemolka_vremja = map(analogRead(potPin), 0, 1023, 1000, 10000); // Например, от 1 до 10 секунд
OCR1A = (kofemolka_vremja * 16) - 1; // Установка периода таймера
// Обработка ШИМ
if (startPWM) {
if (millis() - lastPwmToggle >= 500) { // 500 мс для 2 Гц
pwmState = !pwmState;
analogWrite(pwmPin, pwmState ? 127 : 0); // Устанавливаем ШИМ на 50%
lastPwmToggle = millis();
Serial.println("ШИМ состояние изменено");
}
} else {
analogWrite(pwmPin, 0); // Выключаем ШИМ, если startPWM равен false
}
}
void onD2Fall() {
debounceFlag = true;
debounceTime = millis();
TCCR2B |= (1 << CS22); // Запуск таймера для фильтрации дребезга
}
void onD3Change() {
if (digitalRead(pinD3) == HIGH) {
startPWM = true;
Serial.println("D3 высокий, запуск ШИМ");
} else {
startPWM = false;
Serial.println("D3 низкий, отключение ШИМ");
}
}
ISR(TIMER1_COMPA_vect) {
if (startTimer) {
digitalWrite(ledPin, LOW);
startTimer = false;
TCCR1B &= ~((1 << CS10) | (1 << CS12)); // Остановить таймер
Serial.println("Таймер завершился, отключение светодиода");
}
}
ISR(TIMER2_COMPA_vect) {
if (debounceFlag && (millis() - debounceTime) > debounceDelay) {
if (digitalRead(pinD2) == LOW) {
digitalWrite(ledPin, HIGH);
startTimer = true;
TCNT1 = 0; // Сбросить счетчик таймера
TCCR1B |= (1 << CS10) | (1 << CS12); // Запуск таймера с делением 1024
Serial.println("D2 спад, запуск таймера");
}
debounceFlag = false;
TCCR2B &= ~(1 << CS22); // Остановить таймер для фильтрации дребезга
}
}