#include <TM1637.h>
#include <RTClib.h>
#include <Keypad.h>
// Піни для реле та дисплею
const int relayPin = 4;
const int CLK = 2;
const int DIO = 3;
// Піни для клавіатури
const byte ROWS = 4; // Кількість рядків у клавіатурі
const byte COLS = 3; // Кількість стовпців у клавіатурі
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[ROWS] = {12, 11, 10, 9}; // Піни для рядків
byte colPins[COLS] = {8, 7, 6}; // Піни для стовпців
TM1637 tm1637(CLK, DIO); // Ініціалізація дисплею
RTC_DS1307 rtc; // Ініціалізація модулю реального часу
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
int minutes = 0; // Змінна для збереження кількості хвилин
unsigned long previousMillis = 0; // Змінна для збереження часу останнього виміру
void setup() {
pinMode(relayPin, OUTPUT);
tm1637.init();
tm1637.set(BRIGHT_TYPICAL);
rtc.begin();
}
void loop() {
char key = keypad.getKey(); // Отримання натисканої кнопки з клавіатури
if (key != NO_KEY) {
if (key == '#') {
activateRelay(minutes); // Активація реле на вказану кількість хвилин
minutes = 0; // Скидання лічильника хвилин
tm1637.display(0, 0); // Скидання дисплею
tm1637.display(1, 0);
} else if (key == 'C') {
minutes = 0; // Скидання лічильника хвилин
tm1637.display(0, 0); // Скидання дисплею
tm1637.display(1, 0);
} else if (key >= '0' && key <= '9') {
minutes = minutes * 10 + (key - '0'); // Додавання числа до кількості хвилин
tm1637.display(0, minutes / 10); // Відображення десятків хвилин
tm1637.display(1, minutes % 10); // Відображення одиниць хвилин
}
}
// Обрахування та відображення часу, що залишився
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= 1000) { // Оновлення кожну секунду
if (minutes > 0) {
unsigned long elapsedSeconds = (currentMillis - previousMillis) / 1000;
if (elapsedSeconds >= 60) {
minutes--;
elapsedSeconds -= 60;
}
tm1637.display(2, minutes / 10); // Відображення десятків хвилин, що залишилися
tm1637.display(3, minutes % 10); // Відображення одиниць хвилин, що залишилися
previousMillis = currentMillis - (elapsedSeconds * 1000);
} else {
tm1637.display(2, 0); // Якщо час вичерпано, відображаємо 0
tm1637.display(3, 0);
}
}
// Додаткові дії, які можна виконати під час очікування на клавішу
// Наприклад, відображення поточного часу на дисплеї
}
void activateRelay(int minutes) {
// Вмикаємо реле на вказану кількість хвилин
digitalWrite(relayPin, HIGH);
// delay(minutes * 60 * 1000); // Очікування вказаної кількості хвилин (не використовується)
// Вмість delay використовується логіка з мілісекундами для точного вимірювання часу
}