#define BUTTON_TIMER_PIN 2 // Кнопка запуска таймера (D2)
#define BUTTON_PWM_PIN 3 // Кнопка управления ШИМ (D3)
#define OUTPUT_TIMER_PIN 13 // Управляемый выход (D13)
#define OUTPUT_PWM_PIN 9 // ШИМ на D9
#define POTENTIOMETER_PIN A0 // Потенциометр (A0)
volatile uint16_t ticksRemaining = 0;
volatile bool timerRunning = false;
volatile bool pwmRunning = false;
volatile unsigned long lastPressTime = 0;
const uint16_t DEBOUNCE_TIME = 200; // Антидребезг (мс)
volatile uint8_t pwmDutyCycle = 10; // Заполняемость ШИМ (%) - по умолчанию 10%
volatile uint16_t pwmFrequency = 1; // Частота ШИМ в Гц - по умолчанию 1 Гц
void setup() {
Serial.begin(115200);
pinMode(BUTTON_TIMER_PIN, INPUT_PULLUP);
pinMode(BUTTON_PWM_PIN, INPUT_PULLUP);
pinMode(OUTPUT_TIMER_PIN, OUTPUT);
pinMode(OUTPUT_PWM_PIN, OUTPUT);
digitalWrite(OUTPUT_TIMER_PIN, LOW);
digitalWrite(OUTPUT_PWM_PIN, LOW);
attachInterrupt(digitalPinToInterrupt(BUTTON_TIMER_PIN), startTimer, RISING);
attachInterrupt(digitalPinToInterrupt(BUTTON_PWM_PIN), handlePWM, CHANGE);
}
void loop() {
int potValue = analogRead(POTENTIOMETER_PIN);
uint16_t timerDuration = map(potValue, 0, 1023, 0, 6000);
//Serial.print("Установленное время: ");
//Serial.print(timerDuration);
//Serial.println(" мс");
delay(1000);
}
void startTimer() {
unsigned long now = millis();
if (now - lastPressTime < DEBOUNCE_TIME) return;
lastPressTime = now;
if (pwmRunning) {
Serial.println("Таймер не запускается - ШИМ активен!");
return;
}
int potValue = analogRead(POTENTIOMETER_PIN);
uint16_t timerDuration = map(potValue, 0, 1023, 0, 6000);
Serial.print("Запуск таймера на ");
Serial.print(timerDuration);
Serial.println(" мс!");
if (!timerRunning && timerDuration > 0) {
digitalWrite(OUTPUT_TIMER_PIN, HIGH);
timerRunning = true;
ticksRemaining = timerDuration / 100;
TCCR1A = 0;
TCCR1B = (1 << WGM12) | (1 << CS12); // CTC, делитель 256
OCR1A = 6249; // 100 мс на шаг
TIMSK1 |= (1 << OCIE1A);
}
}
ISR(TIMER1_COMPA_vect) {
if (ticksRemaining > 0) {
ticksRemaining--;
} else {
Serial.println("Таймер истёк, выключаю...");
digitalWrite(OUTPUT_TIMER_PIN, LOW);
timerRunning = false;
TIMSK1 &= ~(1 << OCIE1A);
}
}
void handlePWM() {
if (digitalRead(BUTTON_PWM_PIN) == HIGH) {
startPWM();
} else {
stopPWM();
}
}
void startPWM() {
if (timerRunning) {
Serial.println("ШИМ не запускается - таймер активен!");
return;
}
Serial.println("Старт ШИМ!");
pwmRunning = true;
TCCR1A = (1 << WGM11) | (1 << COM1A1); // Fast PWM, non-inverting mode
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS12); // Делитель 256
ICR1 = (16000000 / (256 * pwmFrequency)) - 1; // Расчёт TOP для заданной частоты
OCR1A = (ICR1 * pwmDutyCycle) / 100; // Заполняемость
}
void stopPWM() {
Serial.println("Остановка ШИМ!");
pwmRunning = false;
TCCR1A = 0; // Отключаем ШИМ
digitalWrite(OUTPUT_PWM_PIN, LOW);
}