Простые часы на Arduino (SSD1306)

Ардуинщики всех стран - объединяйтесь! В этом форуме, конечно.
Аватара пользователя
kelvin
Нашел транзистор. Понюхал.
Сообщения: 161
Зарегистрирован: Вс дек 19, 2010 14:37:45
Контактная информация:

Простые часы на Arduino (SSD1306)

Сообщение kelvin »

часы для OLED 0.96" 128x64
Возможно кому-то будет интересно...
По хорошему к ним надо еще корр. хода прикручивать, но по желанию.
у меня оно вот только - только "пошло".
Описание (краткое)
A4, A5 интерфейс. три кнопки для настройки, общий - минус.
НЕТ realTime, Скетч использует 18148 байт (61%) памяти устройства.
Изображение

Код: Выделить всё

#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDRESS 0x3C
#define BUTTON_MODE_PIN D3  // Mode button
#define BUTTON_PLUS_PIN D4
#define BUTTON_MINUS_PIN D5

struct TimeDate {   // Time and Date structure
  int year;
  int month;
  int day;
  int hour;
  int minute;
  int second;
};
TimeDate currentTime = {2026, 4, 6, 0, 0, 0}; // Variables
bool editing = false;
int editStage = 0;
/*
  Edit stages:
  Line 1 (Time HH:MM:SS):
    0 - Hour tens (H_)
    1 - Hour units (_H)
    2 - Minute tens (M_)
    3 - Minute units (_M)
    4 - Seconds (both digits together - SS)
  
  Line 2 (Date YY Mon DD):
    5 - Year tens (Y_)
    6 - Year units (_Y)
    7 - Month (full month)
    8 - Day tens (D_)
    9 - Day units (_D)
*/

unsigned long lastBlinkTime = 0;
bool showDigit = true;
const unsigned long blinkInterval = 500;
unsigned long lastSecondUpdate = 0;
// Month names
const char* months[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
bool lastBtnModeState = HIGH; // Button debounce
bool lastBtnPlusState = HIGH;
bool lastBtnMinusState = HIGH;

void setup() {
  Serial.begin(115200);
  pinMode(BUTTON_MODE_PIN, INPUT_PULLUP);
  pinMode(BUTTON_PLUS_PIN, INPUT_PULLUP);
  pinMode(BUTTON_MINUS_PIN, INPUT_PULLUP);

  display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS);
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
}

void loop() {
  unsigned long now = millis();
  // Update seconds every 1000ms
  if (now - lastSecondUpdate >= 1000) {
    lastSecondUpdate = now;
    if (!editing) {
      incrementSeconds();
    }
  }

  // Read buttons
  bool btnMode = digitalRead(BUTTON_MODE_PIN) == LOW;
  bool btnPlus = digitalRead(BUTTON_PLUS_PIN) == LOW;
  bool btnMinus = digitalRead(BUTTON_MINUS_PIN) == LOW;

  // Handle Mode button press
  if (btnMode && !lastBtnModeState) {
    delay(50); // Debounce
    if (digitalRead(BUTTON_MODE_PIN) == LOW) {
      handleModeButton();
    }
  }
  lastBtnModeState = btnMode;
  // Handle + and - buttons (only in edit mode)
  if (editing) {
    if (btnPlus && !lastBtnPlusState) {
      delay(50);
      if (digitalRead(BUTTON_PLUS_PIN) == LOW) {
        changeDigit(1);
      }
    }
    if (btnMinus && !lastBtnMinusState) {
      delay(50);
      if (digitalRead(BUTTON_MINUS_PIN) == LOW) {
        changeDigit(-1);
      }
    }
  }
  lastBtnPlusState = btnPlus;
  lastBtnMinusState = btnMinus;
  // Blink logic for editing
  if (editing && (millis() - lastBlinkTime >= blinkInterval)) {
    showDigit = !showDigit;
    lastBlinkTime = millis();
  }

  // Update display
  updateDisplay();

  delay(20);
}

void handleModeButton() {
  if (!editing) {
    // Enter edit mode - start with first digit (hour tens)
    editing = true;
    editStage = 0;
    showDigit = true;
    lastBlinkTime = millis();
  } else {
    // Move to next edit stage
    editStage++;
    
    // If seconds stage (4), reset seconds to 0
    if (editStage == 4) {
      currentTime.second = 0;
    }
    
    // After last stage (9 = day units), exit edit mode
    if (editStage > 9) {
      editing = false;
      editStage = 0;
    }
    
    showDigit = true;
    lastBlinkTime = millis();
  }
}

void changeDigit(int delta) {
  switch (editStage) {
    case 0: // Hour tens (0-2)
      {
        int tens = currentTime.hour / 10;
        int units = currentTime.hour % 10;
        tens = constrain(tens + delta, 0, 2);
        if (tens == 2 && units > 3) units = 3;
        currentTime.hour = tens * 10 + units;
      }
      break;
      
    case 1: // Hour units (0-9, but max 23)
      {
        int tens = currentTime.hour / 10;
        int units = currentTime.hour % 10;
        int maxUnits = (tens == 2) ? 3 : 9;
        units = constrain(units + delta, 0, maxUnits);
        currentTime.hour = tens * 10 + units;
      }
      break;
      
    case 2: // Minute tens (0-5)
      {
        int tens = currentTime.minute / 10;
        int units = currentTime.minute % 10;
        tens = constrain(tens + delta, 0, 5);
        currentTime.minute = tens * 10 + units;
      }
      break;
      
    case 3: // Minute units (0-9)
      {
        int tens = currentTime.minute / 10;
        int units = currentTime.minute % 10;
        units = constrain(units + delta, 0, 9);
        currentTime.minute = tens * 10 + units;
      }
      break;
      
    case 4: // Seconds (both digits - just reset to 0)
      currentTime.second = 0;
      break;
      
    case 5: // Year tens
      {
        int yearShort = currentTime.year % 100;
        int tens = yearShort / 10;
        int units = yearShort % 10;
        tens = constrain(tens + delta, 0, 9);
        currentTime.year = 2000 + tens * 10 + units;
      }
      break;
      
    case 6: // Year units
      {
        int yearShort = currentTime.year % 100;
        int tens = yearShort / 10;
        int units = yearShort % 10;
        units = constrain(units + delta, 0, 9);
        currentTime.year = 2000 + tens * 10 + units;
      }
      break;
      
    case 7: // Month (1-12)
      currentTime.month = constrain(currentTime.month + delta, 1, 12);
      break;
      
    case 8: // Day tens (0-3)
      {
        int tens = currentTime.day / 10;
        int units = currentTime.day % 10;
        tens = constrain(tens + delta, 0, 3);
        int newDay = tens * 10 + units;
        if (newDay < 1) newDay = 1;
        if (newDay > 31) newDay = 31;
        currentTime.day = newDay;
      }
      break;
      
    case 9: // Day units (0-9, but valid day)
      {
        int tens = currentTime.day / 10;
        int units = currentTime.day % 10;
        units = constrain(units + delta, 0, 9);
        int newDay = tens * 10 + units;
        if (newDay < 1) newDay = 1;
        if (newDay > 31) newDay = 31;
        currentTime.day = newDay;
      }
      break;
  }
}

void incrementSeconds() {
  currentTime.second++;
  if (currentTime.second >= 60) {
    currentTime.second = 0;
    currentTime.minute++;
    if (currentTime.minute >= 60) {
      currentTime.minute = 0;
      currentTime.hour++;
      if (currentTime.hour >= 24) {
        currentTime.hour = 0;
        currentTime.day++;
        if (currentTime.day > 31) {
          currentTime.day = 1;
          currentTime.month++;
          if (currentTime.month > 12) {
            currentTime.month = 1;
            currentTime.year++;
          }
        }
      }
    }
  }
}

void drawChar(int x, int y, char c, bool inverse) {
  if (inverse) {
    display.fillRect(x, y, 12, 16, SSD1306_WHITE);
    display.setTextColor(SSD1306_BLACK);
  } else {
    display.setTextColor(SSD1306_WHITE);
  }
  display.setCursor(x, y);
  display.print(c);
  display.setTextColor(SSD1306_WHITE);
}

void updateDisplay() {
  display.clearDisplay();
  display.setTextSize(2);
  char timeBuf[9];   // LINE 1: Time HH:MM:SS
  sprintf(timeBuf, "%02d:%02d:%02d", currentTime.hour, currentTime.minute, currentTime.second);
  
  int timeX = 4;
  int timeY = 8;
  int charW = 12;
  for (int i = 0; i < 8; i++) {
    bool inverse = false;
    if (editing) {
      switch (editStage) {
        case 0: inverse = (i == 0); break;
        case 1: inverse = (i == 1); break;
        case 2: inverse = (i == 3); break;
        case 3: inverse = (i == 4); break;
        case 4: inverse = (i == 6 || i == 7); break;
      }
      inverse = inverse && !showDigit;
    }
    drawChar(timeX + i * charW, timeY, timeBuf[i], inverse);
  }
  char dateBuf[12];    // LINE 2: Date YY Mon DD
  sprintf(dateBuf, "%02d %s %02d", currentTime.year % 100, months[currentTime.month - 1], currentTime.day);
  int dateX = 4;
  int dateY = 40;
  for (int i = 0; i < strlen(dateBuf); i++) {
    bool inverse = false;
    if (editing) {
      switch (editStage) {
        case 5: inverse = (i == 0); break;
        case 6: inverse = (i == 1); break;
        case 7: inverse = (i >= 3 && i <= 5); break;
        case 8: inverse = (i == 7); break;
        case 9: inverse = (i == 8); break;
      }
      inverse = inverse && !showDigit;
    }
    drawChar(dateX + i * charW, dateY, dateBuf[i], inverse);
  }
  display.display();
}
Arduin-ka на базе LGT8F328p - аналог AT328P
Кто стремится - тот добьется, кто ищет - тот найдет,
ибо выход всегда есть, напролом или в обход!
Rapra
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 16, 2026 17:30:02

Re: Простые часы на Arduino (SSD1306)

Сообщение Rapra »

В начале карьеры программиста мы все делали часы.

Названия месяцев можно и по-русски написать, чего стесняться русского языка. И формат даты у нас принят иной - ДД.ММ.ГГ. Да и комменты в проге тоже можно по-русски писать, это ж код чисто для себя, он никому, особенно в забугорье и особенно сейчас, неинтересен. Пушкин АС хорошо знал французский, но стихи почему-то писал на русском.
OKF
Это не хвост, это антенна
Сообщения: 1380
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Простые часы на Arduino (SSD1306)

Сообщение OKF »

Делать то делали, но по уму ли?
Насчёт формата даты согласен. А так оформлено всё вполне красиво, только под спойлер бы желательно код спрятать. Комментарии тоже стараюсь писать по английски, главное правильно и не нужно переключаться на другую кодировку. Какую? Вот когда у нас С++ придумают на русском, тогда и комментировать можно будет по русски. А еще и компилятор, а ещё и ОС...
Только часы от intrc - это как то не очень, это мягко говоря). У LGT же совсем без проблем ставится 32 кгц резонатор.
Ну и о резервном питании нужно бы написать.
Аватара пользователя
JackSmith
Потрогал лапой паяльник
Сообщения: 332
Зарегистрирован: Ср мар 09, 2016 08:07:41

Re: Простые часы на Arduino (SSD1306)

Сообщение JackSmith »

Код: Выделить всё

void incrementSeconds() {
  currentTime.second++;
  if (currentTime.second >= 60) {
    currentTime.second = 0;
    currentTime.minute++;
    if (currentTime.minute >= 60) {
      currentTime.minute = 0;
      currentTime.hour++;
      if (currentTime.hour >= 24) {
        currentTime.hour = 0;
        currentTime.day++;
        if (currentTime.day > 31) {
          currentTime.day = 1;
          currentTime.month++;
          if (currentTime.month > 12) {
            currentTime.month = 1;
            currentTime.year++;
          }
        }
      }
    }
  }
}
при такой логике, в каждом месяце будет 31 день.

Код: Выделить всё

  // Update display
  updateDisplay();

  delay(20);

Код: Выделить всё

void updateDisplay() {
  display.clearDisplay();
при ОЧИСТКЕ и перерисовке дисплея каждые 20 мс, он будет очень прилично мерцать.
Аватара пользователя
kelvin
Нашел транзистор. Понюхал.
Сообщения: 161
Зарегистрирован: Вс дек 19, 2010 14:37:45
Контактная информация:

Re: Простые часы на Arduino (SSD1306)

Сообщение kelvin »

Согласен, код сырой.
Про дату перелистывания месяцев как то не подумал,
надо будет исправить.
Пока ехал на работу, придумал как корректировку времени сделать,
за ночь опаздывают на 2 минуты назад.

Возможно кто-то знает/помнит АОНы типа Русь, Палеха,
Там вручную можно выставить корр.хода.
Дату, год поменяю, месяц попробую сделать русским.
----
Как код визуально урезать(под кат) не знаю. Куда здесь жмякать надо?
Я редко пишу.
Аватара пользователя
JackSmith
Потрогал лапой паяльник
Сообщения: 332
Зарегистрирован: Ср мар 09, 2016 08:07:41

Re: Простые часы на Arduino (SSD1306)

Сообщение JackSmith »

Как код визуально урезать(под кат) не знаю. Куда здесь жмякать надо?
пишите внутри тегов "spoiler"

Код: Выделить всё

[spoiler]текст[/spoiler]
Спойлертекст
Там вручную можно выставить корр.хода.
вам нужен часовой кварц. если нет желания что-то паять, возьмите DS1307, стоит копейки. у него ножку SQW/OUT можно настроить на частоту 1Гц. шина i2c у вас уже есть.
OKF
Это не хвост, это антенна
Сообщения: 1380
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Простые часы на Arduino (SSD1306)

Сообщение OKF »

[uquote="kelvin",url="/forum/viewtopic.php?p=4805072#p4805072"]Про дату перелистывания месяцев как то не подумал,
надо будет исправить.
Пока ехал на работу, придумал как корректировку времени сделать,
за ночь опаздывают на 2 минуты назад.[/uquote]
Если уж ты используешь библиотеки, то почему бы не использовать RTClib? Там все эти дни уже учтены. И в ней есть класс RTC_Millis.
Обычно LGT платы тактируются от intrc 32мгц. Это легко проверить, закоротив/отпаяв кварц при загрузке. А тогда ничто не мешает припаять 32 кгц вместо него, и использовать таймер 2 для генерации 1 сек. меток.
Аватара пользователя
JackSmith
Потрогал лапой паяльник
Сообщения: 332
Зарегистрирован: Ср мар 09, 2016 08:07:41

Re: Простые часы на Arduino (SSD1306)

Сообщение JackSmith »

[uquote="OKF",url="/forum/viewtopic.php?p=4805086#p4805086"][uquote="kelvin",url="/forum/viewtopic.php?p=4805072#p4805072"] А тогда ничто не мешает припаять 32 кгц вместо него.[/uquote]
а как же дисплей на Fast I2C частотой шины 400кГц?
Rapra
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 16, 2026 17:30:02

Re: Простые часы на Arduino (SSD1306)

Сообщение Rapra »

[uquote="OKF",url="/forum/viewtopic.php?p=4805055#p4805055"]Вот когда у нас С++ придумают на русском, с.[/uquote]
Программирование на русском - 1С.
Лично я пишу комменты на русском и не вижу причин писать их на английском. Я художник, я так вижу

Добавлено after 4 minutes 51 second:
[uquote="kelvin",url="/forum/viewtopic.php?p=4805072#p4805072"]Возможно кто-то знает/помнит АОНы типа Русь, Палеха,
Там вручную можно выставить корр.хода.[/uquote]
Да. Корректировка хода - это добавление или вычитание нескольких тиков через определенное число тиков. Например, в STM32F1 через каждые 2^20 тиков аппаратно убирается настраиваемое число тиков

Добавлено after 1 minute 51 second:
[uquote="kelvin",url="/forum/viewtopic.php?p=4805072#p4805072"]Согласен, код сырой.[/uquote]
Ничего страшного, свои первые коды мы все так писали

Добавлено after 7 minutes 6 seconds:
[uquote="kelvin",url="/forum/viewtopic.php?p=4805072#p4805072"]Про дату перелистывания месяцев как то не подумал,
надо будет исправить.шу.[/uquote]
В часах нужно ввести проверку месяцев на 30/31 день, а таг же для февраля проверку високосного года. Для упрощения, списко високосных годов можно внести табличкой на ближайшие 15 лет.
А еще есть стандартная для языка С библиотека Unix time
OKF
Это не хвост, это антенна
Сообщения: 1380
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Простые часы на Arduino (SSD1306)

Сообщение OKF »

[uquote="JackSmith",url="/forum/viewtopic.php?p=4805099#p4805099"][uquote="OKF",url="/forum/viewtopic.php?p=4805086#p4805086"][uquote="kelvin",url="/forum/viewtopic.php?p=4805072#p4805072"] А тогда ничто не мешает припаять 32 кгц вместо него.[/uquote]
а как же дисплей на Fast I2C частотой шины 400кГц?[/uquote]
Так МК как работал, так и продолжает работать на встроенном генераторе 32 мгц, а ноги кварцевого генератора - они же ноги низкочастотного кварцевого генератора асинхронного таймера 2. Ага?

Добавлено after 14 minutes 28 seconds:
[uquote="Rapra",url="/forum/viewtopic.php?p=4805110#p4805110"]В часах нужно ввести проверку месяцев на 30/31 день, а таг же для февраля проверку високосного года. Для упрощения, списко високосных годов можно внести табличкой на ближайшие 15 лет.
А еще есть стандартная для языка С библиотека Unix time[/uquote]
Ардуино использует С++, поэтому я и советую TC-у RTClib - там всё просто и с примерами.
Ещё раз. Комментарии на русском неудобны тем, что каждый раз нужно переключать кодировку. А если используешь фрагменты или файлы с другими семействами/компиляторами, то зачастую нужна перекодировка всего текста на русском. Вот это и есть неудобства. А так спор, ни о чём. Кто как хочет - так и пишет. Важно что бы комментарии были по делу и не засоряли текст программы.
Аватара пользователя
JackSmith
Потрогал лапой паяльник
Сообщения: 332
Зарегистрирован: Ср мар 09, 2016 08:07:41

Re: Простые часы на Arduino (SSD1306)

Сообщение JackSmith »

Ага?
интересное решение.
roman.com
Друг Кота
Сообщения: 9147
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

Re: Простые часы на Arduino (SSD1306)

Сообщение roman.com »

А у меня другая проблема...
Часы атмега328 с кварцем 32 кГц на таймера 2 убегают больше или меньше на несколько секунд за сутки.
Конечно можно каждый день подводить... Но хотелось бы точность хода получше.
:tea:
OKF
Это не хвост, это антенна
Сообщения: 1380
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Простые часы на Arduino (SSD1306)

Сообщение OKF »

[uquote="JackSmith",url="/forum/viewtopic.php?p=4805120#p4805120"]интересное решение.[/uquote] Стандартное, бюджетное.)
Неудобно тем, что нужно думать о резервном питании, а это тянет за собой отслеживание пропадания/появления основного питания и управление режимами сна. Проще отдельный модуль на отдельном RTC и ни о чём не думай.) А если модуль на DS3231, то имеем ещё и хорошую точность хода.
Да, в DS3231 имеем ещё и датчик температуры.)
Последний раз редактировалось OKF Вт апр 07, 2026 12:45:24, всего редактировалось 1 раз.
Аватара пользователя
JackSmith
Потрогал лапой паяльник
Сообщения: 332
Зарегистрирован: Ср мар 09, 2016 08:07:41

Re: Простые часы на Arduino (SSD1306)

Сообщение JackSmith »

[uquote="roman.com",url="/forum/viewtopic.php?p=4805123#p4805123"]А у меня другая проблема...
Часы атмега328 с кварцем 32 кГц на таймера 2 убегают больше или меньше на несколько секунд за сутки.
Конечно можно каждый день подводить... Но хотелось бы точность хода получше.
:tea:[/uquote]
я в свое время исходил из того, что ход кварца не меняется в течении его жизненного цикла. поэтому замерял расхождение конкретного экземпляра и прошивал поправку в EEPROM, откуда ее считывал алгоритм при достижении 24 часов.
а в качестве корректировки вывел одну утопленную кнопку, в которую надо нажимать спичкой, и при ее нажатии секунды округлялись.
Rapra
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 16, 2026 17:30:02

Re: Простые часы на Arduino (SSD1306)

Сообщение Rapra »

Кварцы то как раз стареют, и у них тоже есть некоторая зависимость по температуре. Поэтому, ручная корректировка хода - правильное решение

Добавлено after 3 minutes 28 seconds:
[uquote="OKF",url="/forum/viewtopic.php?p=4805116#p4805116"]А Комментарии на русском неудобны тем, что каждый раз нужно переключать кодировку. А есы.[/uquote]
Да че ее переключать то? Один раз выставил и нехай оно работает.

Добавлено after 1 minute 54 seconds:
А касательно содержимого комментариев - это вообще отдельное искусство - написать хорошие комментарии в коде

Добавлено after 6 minutes 55 seconds:
Лично я комментирую описание функций, методов, классов и структур, используя стиль doxygen

Код: Выделить всё

/**
 * @brief Функция делает то-то и нужна для того-то.
 * @param data - входные данные
 * @return Возвращается то-то
 */
int Foo(int* data) 
{
   /** @todo Написать суммирование данных */

  /** @bug какой-то баг, если данные меньше 1000000 */

OKF
Это не хвост, это антенна
Сообщения: 1380
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Простые часы на Arduino (SSD1306)

Сообщение OKF »

[uquote="Rapra",url="/forum/viewtopic.php?p=4805134#p4805134"]Да че ее переключать то? Один раз выставил и нехай оно работает.[/uquote]Так рус-лат же нужно переключать. Иной раз забываешь, и молотишь... Озлобляет.)
А касательно содержимого комментариев - это вообще отдельное искусство - написать хорошие комментарии в коде
Особенно прикольно, когда комментарии не соответствуют исходному коду). Один из вариантов запутывания.)
Rapra
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 16, 2026 17:30:02

Re: Простые часы на Arduino (SSD1306)

Сообщение Rapra »

А я научился "10-пальцевому" методу тыкания клавы и всегда вижу то, что набираю :)

Сам код я практически не комментирую, за исключением каких-то неочевидных блоков. Но вот описания функций (методов), их входные параметры и возвращаемые значения, описание классов/структур/энумераторов - это да. Есть достаточно распространенный "документатор" doxygen, который умеет даже генерировать html-справку по коду. Пример такой документации можно увидеть на сайте ARM.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15539
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Простые часы на Arduino (SSD1306)

Сообщение BOB51 »

Коррекция хода (даже при кварцевом резонаторе) даст более менее нормальный результат только при стабильном сетевом источнике питания. При аккумуляторном / батарейном питании уже будут погрешности.
Так что в пределах недели придется лапками корректировать +/- 1-2 минутки.
Для бытовых часиков вполне терпимо.
Комментарий - штука полезная, его необходимость (и корректировка) ощущается при попытке вспомнить проект с давностью более 1 года (а порой и более древнего).
8)
Для нашего начинающего kelvin вполне приличный макетик.
Поздравляю с началом вхождения в великие дебри электронных самоделок!
:beer:
Аватара пользователя
JackSmith
Потрогал лапой паяльник
Сообщения: 332
Зарегистрирован: Ср мар 09, 2016 08:07:41

Re: Простые часы на Arduino (SSD1306)

Сообщение JackSmith »

[uquote="BOB51",url="/forum/viewtopic.php?p=4805241#p4805241"]При аккумуляторном / батарейном питании уже будут погрешности.[/uquote]
нормально от батарейки работает, проверено. с автокоррекцией конечно. я делал ступенчатую автокоррекцию, через три дня, через десять и через месяц. норм.
Rapra
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 16, 2026 17:30:02

Re: Простые часы на Arduino (SSD1306)

Сообщение Rapra »

Чтобы делать коррекцию, надо иметь какой-то опорный источник времени.
Ответить

Вернуться в «Arduino»