#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 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, FALLING);
attachInterrupt(digitalPinToInterrupt(BUTTON_PWM_PIN), startStopPWM, CHANGE);
}
void loop() {
// Никакой логики в loop — всё через прерывания
}
void startTimer() {
int potValue = analogRead(POTENTIOMETER_PIN);
uint16_t timerDuration = map(potValue, 0, 1023, 0, 6000);
Serial.print("Запуск расширителя импульса на ");
Serial.print(timerDuration);
Serial.println(" мс!");
digitalWrite(OUTPUT_TIMER_PIN, HIGH);
timerRunning = true;
ticksRemaining = timerDuration / 100;
// Настройка Timer1 под расширитель импульса
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 startStopPWM() {
if (digitalRead(BUTTON_PWM_PIN) == HIGH) {
startPWM();
} else {
stopPWM();
}
}
void startPWM() {
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);
}