Есть следующий код: Спойлер: rus_clock_weather_station.ino Код (C++): #include <Wire.h> //подключаем библиотеку для работы по I²C #include <LiquidCrystal.h> //подключаем библиотеку для ЖКИ #include <RTClib.h> //подключаем библиотеку для DS3231/DS1307 #include <Adafruit_Sensor.h> //для нормальной работы библиотеки, что ниже #include <Adafruit_BMP280.h> //библиотека для BMP280 #include <DHT.h> //подключаем библиотеку для DHT11 #define SENSOR_UPDATE_TIME 5100 //время на обновление датчиков (опрашивать DHT11 не чаще 1 раза в 5 секунд) #define DEBOUNCE_TIME 200 //время на подавление дребезга кнопки #define DHT_PIN 8 //сигнальный провод DHT на 8 ноге дуины #define BUTTON_PIN 9 //кнопка подключена через подягивающий резистор к 9 пину #define BUZZER_PIN 10 //пищалка подключена к 10 пину LiquidCrystal lcd(7, 6, 5, 4, 3, 2); //подключаем ЖКИ 16x2 RTC_DS1307 rtc; //DS1307 и DS3231 одинаковы в работе, так что можно подключать и то и то DHT dht(DHT_PIN, DHT11); //сигнальный пин DHT11 подключаем к 8 пину Arduino Adafruit_BMP280 bmp; //BMP280 подключен через аппаратный SPI и CS к 10 пину Arduino int temperature; //сюда пишем температуру int humidity; //сюда - влажность int pressure; //сюда - давление byte whatToDisplay = 0; //если 0 - то отображаем темп., если 1 - влажн., если 2 - то давл. unsigned long buttonReadCounter; //счетчик времени, нужен для подавления дребезга кнопки unsigned long sensorReadCounter = 5101; //счетчик времени, нужен для опроса сенсоров раз в 5.1 секунды (значение 5101 - костыль для обновления сразу после подачи питания) int currentButtonState; //сюда считываем состояние кнопки int previousButtonState; //а сюда будем записывать состояние кнопки в конце loop boolean needUpdateDisplay = true; //флаг для обновления дисплея char timeString[17]; //сюда форматируем строку в формате "ЧЧ:ММ" (16 символов + 1) char dateString[17]; //сюда форматируем строку в формате "дд.мм.гг" (16 символов + 1) char daysOfTheWeek[7][12] = {"\xB3oc\xBApec", "\xBEo\xBD""e\xE3""e\xBB", "\xB3\xBFop\xBD\xB8\xBA", " cpe\xE3""a", "\xC0""e\xBF\xB3""ep\xB4", "\xBE\xC7\xBF\xBD\xB8\xE5""a", "cy\xB2\xB2o\xBF""a"}; void setup() { lcd.begin(16, 2); //инициализируем ЖКИ rtc.begin(); //инициализируем часы dht.begin(); //инициализируем DHT11 bmp.begin(); //инициализируем BMP280 pinMode(BUTTON_PIN, INPUT); //кнопка на вход pinMode(BUZZER_PIN, OUTPUT); //пищалка на выход (хотя нужна ли эта строчка?) } void loop() { if (millis() - sensorReadCounter > SENSOR_UPDATE_TIME) { temperature = bmp.readTemperature(); //читаем из BMP280 температуру humidity = dht.readHumidity(); //читаем из DHT11 влажность pressure = bmp.readPressure() / 133.3224; //рассчитываем давление (переводим из Па в мм рт.ст.) needUpdateDisplay = true; //обновляем дисплей sensorReadCounter = millis(); } currentButtonState = digitalRead(BUTTON_PIN); //читаем кнопку if (currentButtonState == HIGH && previousButtonState == LOW && millis() - buttonReadCounter > DEBOUNCE_TIME) { whatToDisplay++; //меняем то, что будем изображать if (whatToDisplay > 2) whatToDisplay = 0; //если досичтали до 3 - сбрасываем на 0 needUpdateDisplay = true; //обновляем дисплей buttonReadCounter = millis(); tone(BUZZER_PIN, 4200, 70); //пищим с частотой 4200Гц на протяжении 70мс } if (needUpdateDisplay) { lcd.clear(); //очищаем ЖКИ displayDateTime(); //отображаем время и дату if (whatToDisplay == 0) displayTemp(); //отображаем температуру и влажность else if (whatToDisplay == 1) displayHum(); else if (whatToDisplay == 2) displayPressure(); //отображаем давление needUpdateDisplay = false; //обнуляем флаг } previousButtonState = currentButtonState; //записываем текущее состояние кнопки для последующего цикла } void displayDateTime() { //функция отображения даты и времени DateTime now = rtc.now(); //читаем из часов дату и время sprintf(timeString, "%02d:%02d", now.hour(), now.minute()); //форматируем строку "ЧЧ:ММ" sprintf(dateString, "%02d.%02d.%02d", now.day(), now.month(), now.year() - 2000);//форматируем строку "дд.мм.гг" lcd.setCursor(11, 0); //устанавливаем курсор в верхний правый угол lcd.print(timeString); //записываем строку времени lcd.setCursor(0, 1); //устанавливаем курсор в нижний левый угол lcd.print(dateString); //записываем строку даты lcd.setCursor(9, 1); //устанавливаем курсор в нижний правый угол lcd.print(daysOfTheWeek[now.dayOfTheWeek()]); //записываем строку дня недели } void displayTemp() { //функция вывода температуры и влажности lcd.home(); lcd.print("Te\xBC\xBE="); //пишем "Темп=" lcd.print(temperature); //отображаем температуру lcd.print("\x99""C"); //знак градуса и букву "С" } void displayHum() { lcd.home(); lcd.print("B\xBB""a\xB6\xBD="); //пишем "Влажн=" lcd.print(humidity); //отображаем влажность lcd.print("%"); //рисуем знак процента } void displayPressure() { //функция вывода давления lcd.home(); lcd.print("\xE0""a\xB3\xBB="); //пишем "Давл=" lcd.print(pressure); //отображаем давление lcd.print("p\xBF"); //пишем "рт" } Как победить неправильную работу скетча после ~40 суток аптайма? Проблема же с millis()? P.S. Если есть еще какие-нибудь замечания по коду - буду рад услышать что я делаю не так
Используйте вместо millis() переменную с типом DateTime Если новая дата минус период больше старой даты
Этот нестандартный тип требует дополнительных библиотек. И главное - он абсолютно не нужен для скетчей, где не используется реальное время
нет, не видел. Хотите показать мне что-то интересноЕ? - я не против. Заодно подробнее остановитесь на том, какие преимущества дает использование DateTime вместо миллис()