#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <ArduinoOTA.h>
#include <ESP8266WebServer.h>
#include <ThingerESP8266.h>

// Настройки дисплея
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Настройки Wi-Fi
const char* ssid = "Beeline_2G_A7F18A";  // Ваш SSID
const char* password = "iD2tAXJN3e";     // Ваш пароль

// OTA пароль
const char* otaPassword = "35539900";

// Настройки NTP
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 10800, 60000); // UTC+3

// Аппаратные пины
#define BUZZER_PIN 14  // GPIO14
#define BUTTON_PIN 12  // GPIO12
#define LED_PIN 13     // GPIO13 поддерживает ШИМ (PWM)

// Настройки Thinger.io
#define THINGER_USERNAME "PavelMy"
#define THINGER_DEVICE_ID "ESPPROGECT1"
#define THINGER_DEVICE_CREDENTIAL "Asus35539900"

ThingerESP8266 thing(THINGER_USERNAME, THINGER_DEVICE_ID, THINGER_DEVICE_CREDENTIAL);

// Обработчик веб-сервера
ESP8266WebServer server(80);

// Переменные
String scrollMessage = "";         // Сообщение для дисплея
int textXPosition = SCREEN_WIDTH;  // Стартовая позиция текста (с правой границы дисплея)
bool newMessageReceived = false;   // Флаг нового сообщения
unsigned long lastButtonPress = 0; // Время последнего нажатия кнопки

// Переменные для мигания светодиода
bool ledState = false;                
unsigned long lastLedToggle = 0;     
const unsigned long ledBlinkInterval = 2000; // Интервал мигания светодиода (2 секунды)

void setup() {
    Serial.begin(115200);
    Serial.println("\nStarting...");

    // Настройка пинов
    pinMode(BUZZER_PIN, OUTPUT);
    digitalWrite(BUZZER_PIN, LOW);
    pinMode(BUTTON_PIN, INPUT_PULLUP);
    pinMode(LED_PIN, OUTPUT);
    digitalWrite(LED_PIN, LOW);

    // Инициализация дисплея
    if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
        Serial.println(F("SSD1306 initialization failed"));
        while (true);
    }
    display.clearDisplay();
    display.display();

    // Подключение к Wi-Fi
    Serial.println("Connecting to Wi-Fi...");
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("\nWi-Fi connected!");
    Serial.print("IP Address: ");
    Serial.println(WiFi.localIP());

    timeClient.begin(); // Запуск времени через NTP

    // Thinger.io настройки
    thing.add_wifi(ssid, password);

    thing["display_message"] << [](pson& input) {
        if (input.is_string()) {
            scrollMessage = (const char*)input;
            textXPosition = SCREEN_WIDTH;  // Начинаем текст с правой границы дисплея
            newMessageReceived = true;    // Флаг наличия нового сообщения
            Serial.print("New message: ");
            Serial.println(scrollMessage);
            Beep(); // Подаем сигнал
        }
    };

    thing["clear_message"] = []() {
        scrollMessage = "";             // Удаляем сообщение
        newMessageReceived = false;     // Убираем флаг
        Serial.println("Message cleared");
    };

    ArduinoOTA.setPassword(otaPassword);
    ArduinoOTA.begin(); // Настройка OTA обновлений

    WebServerInit();
    Serial.println("Setup complete.");
}

void loop() {
    ArduinoOTA.handle();
    timeClient.update();
    server.handleClient();
    thing.handle();

    HandleButton();    // Обработка кнопки
    UpdateDisplay();   // Обновление дисплея
    UpdateLed();       // Обновление светодиода
}

// Веб-сервер
void WebServerInit() {
    server.on("/", HTTP_GET, []() {
        String html = "<html>"
                      "<h1>ESP8266 Message</h1>"
                      "<form action='/sendMessage' method='POST'>"
                      "Message: <input name='message' type='text'/><br>"
                      "<input type='submit' value='Send'/>"
                      "</form></html>";
        server.send(200, "text/html", html);
    });

    server.on("/sendMessage", HTTP_POST, []() {
        if (server.hasArg("message")) {
            scrollMessage = server.arg("message");
            textXPosition = SCREEN_WIDTH;  // Возврат к начальному положению
            newMessageReceived = true;
            Serial.println("Message received: " + scrollMessage);
            Beep();
            server.send(200, "text/html", "<h1>Message Sent!</h1><br><a href='/'>Back</a>");
        } else {
            server.send(400, "text/plain", "Message not provided");
        }
    });

    server.begin();
    Serial.println("Web server initialized.");
}

// Кнопка сброса сообщения
void HandleButton() {
    unsigned long currentMillis = millis();
    if (digitalRead(BUTTON_PIN) == LOW && currentMillis - lastButtonPress > 300) {
        lastButtonPress = currentMillis; // Антидребезг
        scrollMessage = "";              // Сброс текста
        newMessageReceived = false;
        Serial.println("Message cleared by button!");
    }
}

// Прокрутка текста и отображение времени
void UpdateDisplay() {
    display.clearDisplay();

    // Отображение времени
    display.setTextSize(2);
    display.setCursor(0, 0);
    display.setTextColor(SSD1306_WHITE);
    display.print(timeClient.getFormattedTime());

    // Если есть сообщение, прокручиваем его
    if (!scrollMessage.isEmpty()) {
        display.setTextSize(1);
        display.setCursor(textXPosition, 16);  // Сообщение всегда на второй строке
        display.print(scrollMessage);

        // Прокрутка текста
        textXPosition -= 2; // Сдвиг текста влево
        if (textXPosition < -6 * scrollMessage.length()) {  // Если текст вышел за край дисплея
            textXPosition = SCREEN_WIDTH;  // Возвращаем текст в начальную позицию справа
        }
    }

    display.display(); // Обновляем дисплей
}

// Динамика работы светодиода
void UpdateLed() {
    if (newMessageReceived) {
        unsigned long currentMillis = millis();
        if (currentMillis - lastLedToggle >= ledBlinkInterval) {
            lastLedToggle = currentMillis;
            ledState = !ledState;
            digitalWrite(LED_PIN, ledState ? HIGH : LOW);
        }
    } else {
        digitalWrite(LED_PIN, LOW); // Выключаем светодиод
    }
}

// Звуковой сигнал
void Beep() {
    digitalWrite(BUZZER_PIN, HIGH);
    delay(100);
    digitalWrite(BUZZER_PIN, LOW);
} почему дисплей ничего не отображает