#include <TimerOne.h> // Подключение библиотеки TimerOne
const int buttonPin = 13; // Единственная кнопка
const int Leds[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
const int numLeds = 11;
const int snakeLength = 4;
bool isRunning = false;
bool buttonState = LOW;
bool lastButtonState = LOW;
int currentPosition = 0;
unsigned long lastUpdate = 0;
const int delayTime = 100;
int mode = 0; // 0 - delay, 1 - millis, 2 - timer
unsigned long buttonPressTime = 0;
const unsigned long longPressTime = 1000; // Время длинного нажатия
void setup() {
for (int i = 0; i < numLeds; i++) {
pinMode(Leds[i], OUTPUT);
digitalWrite(Leds[i], LOW);
}
pinMode(buttonPin, INPUT);
// Настройка таймера с использованием библиотеки TimerOne
Timer1.initialize(1000000); // Инициализация таймера с периодом 1 секунда (1000000 микросекунд)
Timer1.attachInterrupt(timerISR); // Привязка прерывания к функции timerISR
}
void loop() {
buttonState = digitalRead(buttonPin);
// Обработка нажатия кнопки
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
buttonPressTime = millis(); // Запоминаем время нажатия
} else {
unsigned long pressDuration = millis() - buttonPressTime;
if (pressDuration < longPressTime) {
// Короткое нажатие - запуск/остановка
isRunning = !isRunning;
if (!isRunning) {
// Выключить все светодиоды при остановке
for (int i = 0; i < numLeds; i++) {
digitalWrite(Leds[i], LOW);
}
}
} else {
// Длинное нажатие - смена режима
mode = (mode + 1) % 3; // Переключение между режимами 0, 1, 2
}
}
delay(50); // Дебаунс кнопки
}
lastButtonState = buttonState;
// Управление гирляндой в зависимости от выбранного режима
if (isRunning) {
switch (mode) {
case 0:
runDelayMode();
break;
case 1:
runMillisMode();
break;
case 2:
// В режиме таймера управление происходит в прерывании
break;
}
}
}
// Режим delay
void runDelayMode() {
digitalWrite(Leds[currentPosition % numLeds], HIGH);
int tailPosition = currentPosition - snakeLength;
if (tailPosition >= 0) {
digitalWrite(Leds[tailPosition % numLeds], LOW);
}
currentPosition++;
delay(delayTime); // Задержка для управления скоростью гирлянды
}
// Режим millis
void runMillisMode() {
unsigned long currentMillis = millis();
if (currentMillis - lastUpdate >= delayTime) {
lastUpdate = currentMillis;
digitalWrite(Leds[currentPosition % numLeds], HIGH);
int tailPosition = currentPosition - snakeLength;
if (tailPosition >= 0) {
digitalWrite(Leds[tailPosition % numLeds], LOW);
}
currentPosition++;
}
}
// Прерывание для режима таймера
void timerISR() {
if (isRunning && mode == 2) {
digitalWrite(Leds[currentPosition % numLeds], HIGH);
int tailPosition = currentPosition - snakeLength;
if (tailPosition >= 0) {
digitalWrite(Leds[tailPosition % numLeds], LOW);
}
currentPosition++;
}
}