Спойлер
/*
Абзавём входные данные, а именно пины для КНОПКИ и ТРЁХ РЕЛЕ
*/
#define BUTTON_PIN 12 // Кнопка
#define RELE1_PIN 2 // Реле 1
#define RELE2_PIN 3 // Реле 2
#define RELE3_PIN 4 // Реле 3
#define TIME_BOUNCE 70 // 70мс время "фильтрации" дребезга контактов
#define LONG_PRESS_TIME 2000 // 2 секунды время удержания кнопки
#define SHORT_TIME 3000
enum BUTTON_RESULT : uint8_t {
NOT_PRESS,
PRESS,
LONG_PRESS
};
BUTTON_RESULT current_button_res = NOT_PRESS;
const uint8_t RELE_PINS[] = {RELE1_PIN, RELE2_PIN, RELE3_PIN}, r_count = sizeof(RELE_PINS) / sizeof(RELE_PINS[0]);
uint8_t cur_rele = 0;
void releOff () {
for (uint8_t i = 0; i < r_count; i++) {
digitalWrite(RELE_PINS[i], LOW);
}
}
void setup() {
// Теперь настроим пины
pinMode(BUTTON_PIN, INPUT_PULLUP); // На вход и подтянуть к +питания (экономим на резисторах для "подтяжки")
for (uint8_t i = 0; i < r_count; i++) {
pinMode(RELE_PINS[i], OUTPUT); // А пины реле на выход
}
// И выключим их все
releOff();
}
void loop() {
uint8_t button_state = digitalRead(BUTTON_PIN); // Ну во, вот тут мы её и "уконтропупили".
uint32_t _millis = millis(); // Запомним текущее значение миллисекунд
static uint32_t timeHoldBegin; // Время начала удержания кнопки
static uint32_t timeHold; // Длительность удержания кнопки
// А дальше нам нужно узнать - нажимал кто на кнопку? А если нажимал - то как долго удерживал?
if (!button_state) { // Если кнопка нажата
timeHold = _millis - timeHoldBegin; // Считаем длительность удержания
} else { // Еслди кнопку отпустили
timeHoldBegin = _millis; // Сбрасываем
timeHold = 0;
current_button_res = NOT_PRESS;
}
if (timeHold > TIME_BOUNCE && timeHold < LONG_PRESS_TIME) { // Если время удержание в интервале между временем подавления дребезга и удержанием
current_button_res = PRESS; // То нужно как-то "зарегистрировать нажатие"
}
if (timeHold > LONG_PRESS_TIME) { // Если время удержание больше времени удержаниея (2 сек)
current_button_res = LONG_PRESS; // То нужно как-то "зарегистрировать долгое удержание"
}
// Состояние кнопки узнали.
// А дальше пошла "жара" (то есть обработка нажатий)
switch (current_button_res) {
case PRESS: // Если кликнули один раз
releOff();
if (cur_rele < (r_count - 1)) {
digitalWrite(RELE_PINS[cur_rele], HIGH);
}
cur_rele = (cur_rele++) % r_count;
break;
case LONG_PRESS: // Если кномпу долго удерживали
releOff();
digitalWrite(RELE_PINS[r_count - 1], HIGH);
delay(SHORT_TIME);
digitalWrite(RELE_PINS[r_count - 1], LOW);
cur_rele = 0;
break;
case NOT_PRESS: // Если кнопку не нажимали
// Ничего не делаем. Это просто для наглядности
break;
default:
break;
}
}
Скетч использует 1396 байт (4%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 23 байт (1%) динамической памяти, оставляя 2025 байт для локальных переменных. Максимум: 2048 байт.