#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#define bt1 16
#define bt2 17
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Переменные для управления
int x = 0, lx = 1;
bool page = 0; // 0 - курсор, 1 - системная информация
// Переменные для антидребезга и автоповтора
unsigned long lastBt1Press = 0;
unsigned long lastBt2Press = 0;
unsigned long lastRepeatTime = 0;
bool bt1Pressed = false;
bool bt2Pressed = false;
int repeatDelay = 500; // Начальная задержка автоповтора (мс)
int repeatSpeed = 100; // Скорость автоповтора после ускорения (мс)
bool repeatAccelerated = false;
// Пользовательский символ (иконка)
byte customChar[8] = {
0b00000,
0b01110,
0b11111,
0b10101,
0b11111,
0b01110,
0b00100,
0b00000
};
// Для системной информации
unsigned long startTime = 0;
void setup() {
pinMode(bt1, INPUT_PULLUP);
pinMode(bt2, INPUT_PULLUP);
lcd.init();
lcd.backlight();
// Создаем пользовательский символ
lcd.createChar(0, customChar);
// Подключаемся к Wi-Fi (замените на свои данные)
WiFi.begin("RTU MIREA", "12345678");
lcd.setCursor(0, 0);
lcd.print("RTU MIREA");
lcd.setCursor(0, 1);
lcd.print("Hello world!");
startTime = millis();
delay(2000);
lcd.clear();
drawCursorPage();
}
void drawCursorPage() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cursor: ");
lcd.print(x);
lcd.print(" ");
drawSlider();
}
void drawSlider() {
// Рисуем шкалу на второй строке
lcd.setCursor(0, 1);
for (int i = 0; i < 16; i++) {
if (i <= x) {
lcd.write(0); // Пользовательский символ
} else {
lcd.print("-");
}
}
}
void drawSystemInfoPage() {
lcd.clear();
lcd.setCursor(0, 0);
// Информация о Wi-Fi
if (WiFi.status() == WL_CONNECTED) {
lcd.print("WiFi: ");
lcd.print(WiFi.RSSI());
lcd.print(" dBm");
} else {
lcd.print("WiFi: disconnected");
}
lcd.setCursor(0, 1);
// Информация о времени работы
unsigned long uptime = (millis() - startTime) / 1000;
int hours = uptime / 3600;
int minutes = (uptime % 3600) / 60;
int seconds = uptime % 60;
lcd.print("Up: ");
if (hours < 10) lcd.print("0");
lcd.print(hours);
lcd.print(":");
if (minutes < 10) lcd.print("0");
lcd.print(minutes);
lcd.print(":");
if (seconds < 10) lcd.print("0");
lcd.print(seconds);
}
bool checkButton(int pin, unsigned long &lastPressTime, bool &buttonPressed) {
bool currentState = digitalRead(pin) == LOW;
unsigned long currentTime = millis();
// Антидребезг (25 мс)
if (currentState != buttonPressed) {
if (currentTime - lastPressTime > 25) {
buttonPressed = currentState;
lastPressTime = currentTime;
return currentState;
}
}
// Автоповтор при удержании
if (buttonPressed && currentTime - lastPressTime > repeatDelay) {
if (currentTime - lastRepeatTime > (repeatAccelerated ? repeatSpeed : repeatDelay)) {
lastRepeatTime = currentTime;
// Ускоряем автоповтор после первого повторения
if (!repeatAccelerated) {
repeatAccelerated = true;
}
return true;
}
}
return false;
}
void loop() {
// Обработка кнопки 1 (влево)
if (checkButton(bt1, lastBt1Press, bt1Pressed)) {
if (page == 0) { // Только на странице курсора
x--;
// Замкнутый курсор - переход через границы
if (x < 0) {
x = 15;
}
drawCursorPage();
}
} else if (!bt1Pressed) {
repeatAccelerated = false; // Сбрасываем ускорение при отпускании
}
// Обработка кнопки 2 (вправо + переключение страниц)
if (checkButton(bt2, lastBt2Press, bt2Pressed)) {
if (page == 0) { // На странице курсора
x++;
// Замкнутый курсор - переход через границы
if (x > 15) {
x = 0;
}
drawCursorPage();
}
// Проверка длинного нажатия для переключения страниц
if (millis() - lastBt2Press > 1000 && bt2Pressed) {
page = !page;
if (page == 0) {
drawCursorPage();
} else {
drawSystemInfoPage();
}
delay(300); // Задержка для предотвращения множественного переключения
lastBt2Press = millis(); // Сбрасываем время нажатия
}
} else if (!bt2Pressed) {
repeatAccelerated = false; // Сбрасываем ускорение при отпускании
}
// Автообновление системной информации каждую секунду
if (page == 1 && millis() % 1000 < 50) {
drawSystemInfoPage();
}
delay(10); // Небольшая задержка для стабильности
}