Доброго дня. Подключил ардуинку к Oled SSD1306. Загрузил код. Часики работают, но вот проблема. В коде нет команд управления установки времени(кнопок). Время, коректировку и дату можно установить только в самом скетче. Может кто допишет для пары кнопочек. Спойлер#include <OLED_I2C.h>
const int ledPin = 13; // номер выхода, подключенного к светодиоду int ledState = LOW; // этой переменной устанавливаем состояние светодиода
long previousMillis = 0; //переменная для хранения значений таймера // интервал отсчёта, меняя это значение можно корректировать точность хода часов long interval = 1000; // интервал между включение/выключением светодиода
// Установка времени и даты int chas = 23; //значение часов int minut = 5; //значение минут int sek = 0; //значение секунд int den = 1; //день int mesac = 7; //месяц int god = 2015; //год int nedela = 3; // день недели int wgod = 2000; //первый высокосный год int key = 1; //ключ перевода дня
void setup() { // задаем режим выхода для порта, подключенного к светодиоду pinMode(ledPin, OUTPUT); myOLED.begin(); }
void loop() { unsigned long currentMillis = millis(); //проверяем не прошел ли нужный интервал, если прошел то if (currentMillis - previousMillis > interval)
{ // сохраняем время последнего переключения previousMillis = currentMillis; sek++; // Добавляем секунду
if (sek > 59) { //если переменная секунд больше 59 ... sek = 0; //сбрасываем ее на 0 minut++; //пишем +1 в переменную минут }
if (minut > 59) { //если переменная минут больше 59 ... minut = 0; //сбрасываем ее на 0 chas++; //пишем +1 в переменную часов }
if (chas > 23) { //если переменная часов больше 23 ... chas = 0; //сбрасываем ее на 0 nedela++; // переводим день недели if (nedela == { // Если день недели = 8 nedela = 1; // то ставим на 1 (Понедельник) }
// Если сейчас февраль и 29 число if (mesac == 2 && den == 29) { den = 1; // Переводим день на 1 число mesac++; // Переводим месяц key = 0; // Устанавливаем флаг перевода дня } // Если сейчас февраль и 28 число if (mesac == 2 && den == 28) { // Высчитываем ближайший високосный год do { wgod = wgod + 4; // в циклк вычисяем высокосные года } while (wgod < god); // и сравниваем с текущим годом // Если сравниваемый високосный год равен текущему if (wgod == god) { den++; // прибавляем день key = 0; // Устанавливаем флаг перевода дня } else { // Если сравниваемый високосный год НЕ равен текущему den = 1; // Устанавливаем первое число mesac++; // Переводим месяц key = 0; // Устанавливаем флаг перевода дня } wgod = wgod - 4; // Откатываем сравниваемый високосный год на предыдущий високосный год }
// если сечас 30 число if ( den == 30 ) { // и сейчас 4, 6, 9 или 11 месяц if (mesac == 4 || mesac == 6 || mesac == 9 || mesac == 11 ) { den = 1; // Устанавливаем первое число mesac++; // Переводим месяц key = 0; // Устанавливаем флаг перевода дня } } // Если сейчас 31 число if ( den == 31 ) { // И сейчас 1, 3, 5, 7, 8, 10 или 12 месяц if (mesac == 1 || mesac == 3 || mesac == 5 || mesac == 7 || mesac == 8 || mesac == 10 || mesac == 12 ) { den = 1; // Устанавливаем первое число // если текущий месяц - Декабрь if (mesac == 12) { mesac = 1; // Переводим месяц на Январь god++; // Переводим на следующий год } else{ mesac++; // Переводим месяц } key = 0; // Устанавливаем флаг перевода дня } } // если флаг перевода дня равен 1 if (key == 1 ) { den++; // Добавляем день } else { // иначе если был установлен флаг перевода дня, день не добавляется key = 1; // и сбрасывается флаг перевода дня }
}
lcd(); // Вывод информации на дисплей
} // конец опроса
} // конец цикла
void lcd(){ //вывод символов на дисплей//
// Установка большого шрифта myOLED.setFont(MegaNumbers); // отображение часов if (chas < 10) { // если число меньше 10 myOLED.print("0", 4, 12); // первый знак будет 0 (01) myOLED.print(String(chas), 27, 12); } else { myOLED.print(String(chas), 4, 12); } // Отображение Двоеточия if (ledState == LOW) { // мигаем двоеточием ledState = HIGH; // Переключаем порт myOLED.print("/", 51, 12); // Выводим ":" }else{ ledState = LOW; // Переключаем порт myOLED.print("-", 51, 12); // Выводим " " }
// Отображение минут if (minut < 10) { // если число меньше 10 myOLED.print("0", 75, 12); // первый знак будет 0 (01) myOLED.print(String(minut), 100, 12); }else { myOLED.print(String(minut), 75, 12); }
// Отображение секунд // Установка маленького шрифта myOLED.setFont(SmallFont); myOLED.print(":", 110, 5); // Выводим ":" if (sek < 10) { // если число меньше 10 myOLED.print("0", 115, 5); // первый знак будет 0 (01) myOLED.print(String(sek), 121, 5); }else { myOLED.print(String(sek), 115, 5); }
// Отображение дня if (den < 10) { // если число меньше 10 myOLED.print("0", 10, 55); // первый знак будет 0 (01) myOLED.print(String(den), 16, 55); }else { myOLED.print(String(den), 10, 55); }
// Отображение месяца myOLED.print(".", 22, 55); // Выводим "." if (mesac < 10) { // если число меньше 10 myOLED.print("0", 28, 55); // первый знак будет 0 (01) myOLED.print(String(mesac), 34, 55); }else { myOLED.print(String(mesac), 28, 55); }
// Отображение дня недели myOLED.setFont(RusFont); switch (nedela) { case 1: myOLED.print("GJYTLTKMYBR", CENTER, 0); break; //Понедельник case 2: myOLED.print(" DNJHYBR ", CENTER, 0); break; //Вторник case 3: myOLED.print(" CHTLF ", CENTER, 0); break; //Среда case 4: myOLED.print(" XTNDTHU ", CENTER, 0); break; //Четверг case 5: myOLED.print(" GZNYBWF ", CENTER, 0); break; //Пятница case 6: myOLED.print(" CE<<JNF ", CENTER, 0); break; //Суббота case 7: myOLED.print("DJCRHTCTYMT", CENTER, 0); break; //Воскресенье } // Обновление дисплея myOLED.update();
}
Последний раз редактировалось mic1960 Вт апр 04, 2023 19:56:43, всего редактировалось 1 раз.
Программный код для кнопок и установки времени и дату будет больше, чем написано . А точность встроенного в Arduino кварцевого резонатора (или кристаллического резонатора ??) и функции millis(), скорее всего, будет иметь большую повседневную (и температурную) погрешность. Вероятно схема и код являются демонстрационными?
Ориентируетесь на схему и программный код на DS3231.
Программный код для кнопок и установки времени и дату будет больше, чем написано . А точность встроенного в Arduino кварцевого резонатора (или кристаллического резонатора ??) и функции millis(), скорее всего, будет иметь большую повседневную (и температурную) погрешность. Вероятно схема и код являются демонстрационными?
Ориентируетесь на схему и программный код на DS3231.
Ну я их откоректировал за пару дней изменением ///long interval = 1000;/// Сейчас считают уже сутки ровно с компутерным временем.
Кнопки через DDRB,DDRA, PINB, PINA и тому подобное(либо через digitalRead и pinMode). Обработку кнопок в основном цикле либо в таймере. А так да, лучше, конечно, поставить DS3231. на кварцах по прерыванию(у миллисов, подозреваю, точность пониже) вроде и норм получалось, но тут основное что при потере питания сбрасывается счёт - оно вам надо?