Здравствуйте.
Для начала я попробовал установить и вывести время в консоль:
#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();
}
}
Спасибо

