Как вывести время с DS1302 на дисплей OLED I2C 1.5′′ 128×128 px

Здравствуйте.

Для начала я попробовал установить и вывести время в консоль:

#include <Ds1302.h>

const int RST_PIN = 29;  // Пин для управления
const int DAT_PIN = 28;  // Пин для передачи данных
const int CLK_PIN = 27;  // Пин для синхронизации тактов

Ds1302 rtc(RST_PIN, CLK_PIN, DAT_PIN);

void printTime(Ds1302::DateTime dateTime) {
  Serial.print(dateTime.year + 2000); // год (0-99) — добавляем 2000
  Serial.print('-');
  if (dateTime.month < 10);
  Serial.print(dateTime.month);
  Serial.print('-');
  if (dateTime.day < 10);
  Serial.print(dateTime.day);
  Serial.print(' ');
  if (dateTime.hour < 10);
  Serial.print(dateTime.hour);
  Serial.print(':');
  if (dateTime.minute < 10);
  Serial.print(dateTime.minute);
  Serial.print(':');
  if (dateTime.second < 10);
  Serial.println(dateTime.second);
}

void setup() {
  Serial.begin(9600);
  
  // Инициализация RTC
  rtc.init();

  // Проверяем, установлено ли время
  // Обычно, если RTC первый раз включен, время останавливается
  // или нужно его установить вручную. В этом случае просто устанавливаем.
  Ds1302::DateTime dt;
  dt.year = 25; // 2023 год
  dt.month = 12; // Сентябрь
  dt.day = 15;
  dt.hour = 1;
  dt.minute = 9;
  dt.second = 0;

  // Устанавливаем время
  rtc.setDateTime(&dt);
}

void loop() {
  Ds1302::DateTime now;
  rtc.getDateTime(&now);
  printTime(now);
  delay(1000);
}

Но, время всё равно показывает 2000-0-0 0:0:0, хотя я установил время. Библиотека #include <Ds1302.h>

Далее хотелось бы вывести его на дисплей: U8G2_SH1107_128X128_F_HW_I2C display(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); (объявление для дисплея)

Основная программа вот:

#include <Wire.h>
#include <U8g2lib.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Servo.h>
#include <Ds1302.h>

// Пин для DS18B20
#define ONE_WIRE_BUS 2

Servo motor;
const int relayPin1 = 22;  // Реле для вентилятора  
const int relayPin2 = 23;  // Реле для питания сервопривода
const int relayPin3 = 24;
const int relayPin4 = 25;
const int relayPin5 = 26;
const int RST_PIN = 29;  // Пин для управления
const int DAT_PIN = 28;  // Пин для передачи данных
const int CLK_PIN = 27;  // Пин для синхронизации тактов

// Пины для остальных датчиков
const int soilMoisturePin = A0;  // Влажность почвы
const int photoPin = A1;         // Освещенность
const int trigPin = 12;          // Триггер ультразвука
const int echoPin = 11;          // Эхо ультразвука

// Объявление для DS18B20
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
Ds1302 rtc(RST_PIN, CLK_PIN, DAT_PIN); //время

// Объявление для дисплея
U8G2_SH1107_128X128_F_HW_I2C display(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

// Переменные для хранения данных
float temperatureC = 0.0;
int soilPercent = 0;
int brightness = 0;
int distance_mm = -1;

float a = 24.0;

// Таймеры для разных обновлений
unsigned long lastTempUpdate = 0;
unsigned long lastSoilUpdate = 0;
unsigned long lastLightUpdate = 0;
unsigned long lastDistUpdate = 0;
unsigned long lastDisplayUpdate = 0;
unsigned long moveStartTime = 0;    // Время начала движения сервопривода
const long tempInterval = 1000;   // Опрашивать температуру раз в 1000 мс
const long moveInterval = 600;      // Держать сервопривод включённым 600 мс
const long checkInterval = 50;       // Интервал проверки состояния: 50 мс
bool isMoving = false;               // Флаг: движется ли сервопривод сейчас?
int currentState = 0;             // 0 = влево, 1 = вправо

void setup() {
  Serial.begin(9600);
  sensors.begin();

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  
  display.begin();
  display.clearBuffer();
  display.setContrast(128);

  pinMode(relayPin1, OUTPUT);         
  pinMode(relayPin2, OUTPUT);         
  pinMode(relayPin3, OUTPUT);
  pinMode(relayPin4, OUTPUT);
  pinMode(relayPin5, OUTPUT);         
  digitalWrite(relayPin1, LOW);       
  digitalWrite(relayPin2, HIGH);       
  digitalWrite(relayPin3, LOW);
  digitalWrite(relayPin4, LOW);
  digitalWrite(relayPin5, LOW);

  //motor.attach(9);  // Подключить сервопривод к пину 9

  rtc.init();
}

void loop() {
  unsigned long currentMillis = millis();

  // 2. Обновление температуры каждую секунду
  if (currentMillis - lastTempUpdate >= tempInterval) {
    lastTempUpdate = currentMillis;
    sensors.requestTemperatures();
    temperatureC = sensors.getTempCByIndex(0);

    if ((temperatureC < a) && (temperatureC > 29.0 && temperatureC < 25.0)) {
      digitalWrite(relayPin3, HIGH); //вкл
  } else {
      digitalWrite(relayPin3, LOW); //выкл
    }
    
    if (temperatureC > 25.0) {
      digitalWrite(relayPin3, LOW); //вкл
    } 

    if (temperatureC < 29.0) {
      digitalWrite(relayPin3, HIGH); //вкл
    } 

    if ((temperatureC > a) && (temperatureC < 29.0)) {
      digitalWrite(relayPin3, LOW); //выкл
  }
    a = temperatureC;

    if (temperatureC < 29.0) {
      digitalWrite(relayPin1, HIGH); //вкл
  } else {
      digitalWrite(relayPin1, LOW); //выкл
    }

}

  // 4. Обновление влажности (каждые 100 мс)
  if (currentMillis - lastSoilUpdate >= 100) {
    lastSoilUpdate = currentMillis;
    int soilVal = analogRead(soilMoisturePin);
    soilPercent = map(soilVal, 1023, 0, 0, 100);
    if (soilPercent < 0) soilPercent = 0;
    if (soilPercent > 100) soilPercent = 100;
  }

  // 5. Обновление освещённости (каждые 100 мс)
  if (currentMillis - lastLightUpdate >= 100) {
    lastLightUpdate = currentMillis;
    brightness = analogRead(photoPin);
  }

  // 6. Обновление расстояния (каждые 100 мс)
  if (currentMillis - lastDistUpdate >= 100) {
    lastDistUpdate = currentMillis;
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    unsigned long duration = pulseIn(echoPin, HIGH, 30000);
    distance_mm = (duration == 0) ? -1 : (int)((duration * 0.343) / 2);
  }

  // 7. Обновление дисплея (каждые 400 мс)
// 7. Обновление дисплея (каждые 400 мс)
if (currentMillis - lastDisplayUpdate >= 400) {
  lastDisplayUpdate = currentMillis;

  // Читаем текущее время из DS1302
  Ds1302::DateTime now;
  rtc.getDateTime(&now);  // Важно: передаём указатель!

  int hours = now.hour;
  int minutes = now.minute;
  int seconds = now.second;

  display.clearBuffer();
  display.setFont(u8g2_font_ncenB08_tr);

  char timeStr[50];
  snprintf(timeStr, sizeof(timeStr), "           Time: %02d:%02d:%02d", hours, minutes, seconds);
  display.drawStr(0, 10, timeStr);

  char tempStr[50];
  dtostrf(temperatureC, 4, 1, tempStr);
  display.drawStr(0, 20, "           Temp: ");
  display.drawStr(70, 20, tempStr);
  display.drawStr(90, 20, " C");

  char soilStr[50];
  snprintf(soilStr, sizeof(soilStr), "           Soil: %d%%", soilPercent);
  display.drawStr(0, 30, soilStr);

  if (distance_mm >= 0) {
    char distStr[50];
    snprintf(distStr, sizeof(distStr), "           Dist: %d mm", distance_mm);
    display.drawStr(0, 40, distStr);
  } else {
    display.drawStr(0, 40, "           Dist: no signal");
  }

  char lightStr[50];
  int luxValue = map(brightness, -200, 1000, 0, 100); // или другой диапазон по желанию
  int invertedLux = 100 - luxValue;
  snprintf(lightStr, sizeof(lightStr), "           Lux: %d", invertedLux);
  display.drawStr(0, 50, lightStr);

  if (invertedLux < 70) {
    digitalWrite(relayPin4, LOW);  // Включить
} else {
    digitalWrite(relayPin4, HIGH); // Выключить
}

  display.sendBuffer();
}
}

Спасибо

ну вот оно примерно так и работает, как написано

1 лайк

Оно мне в консоль выводит 2000-0-0 0:0:0, хотя я установил актуальное время.

если не трогать пару минут
меняется вывод?

нет, всё равно нули выводит.

ну значит бесполезно пытаться в модуль время загонять
проблема в подключении видимо.

Хорошо, спасибо, я проверю

Попробуй другой пример.
Например:

@BOOM
хм… а ничего что у автора DS1302, а твой пример для 3231?
Или они совместимы?

У них даже интерфейсы разные ))

Проглядел…

Тогда вот это ))

А с библиотекой Ds1302(которая у меня) не получится?

А к ней примеров нету? Примеры тоже не работают?

Я не про статьи в интернете. С каждой ардуино-библиотекой обычно идут примеры, обычно они лежат в папке examples. Или можно запустить прямо из IDE

Этот пример тоже не работает? Если так, то ищите проблемы с подключением и/или нерабочим модулем

Хорошо, спасибо, позже посмотрю.

У меня в пользовательских библиотеках нету её.

А прокрутить? Или у вас ТОЛЬКО четыре библиотеки установлено? Пример к ней есть, ищите

Дальше не прокручивается, всего 4 библиотеки есть в примерах