Включение/выключение реле по будильникам

Включает светодиод на 7 секунд 2 раза в день. Время живёт в RTC.

Спойлер
#include <Wire.h>
#include <RTClib.h> // Для работы с RTC модулем

RTC_DS3231 rtc; // Создаем объект для RTC DS3231

const int ledPin = 13; // Светодиод подключен к D13
bool ledState = false; // Состояние светодиода
unsigned long ledOnTime = 0; // Время включения светодиода
const unsigned long ledDuration = 7000; // Длительность включения (7 секунд)

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  // Инициализация RTC
  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  // Если RTC потерял питание, установим текущее время
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, setting time!");
    // Установите здесь текущее время после компиляции
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
}

void loop() {
  DateTime now = rtc.now(); // Получаем текущее время
  unsigned long unixTime = now.unixtime(); // Получаем Unix-время

  // Получаем часы и минуты текущего времени
  int currentHour = now.hour();
  int currentMinute = now.minute();
  int currentSecond = now.second();

  // Проверяем, наступило ли время включения (9:00:00 или 21:00:00)
  if ((currentHour == 9 && currentMinute == 0 && currentSecond == 0) || 
      (currentHour == 21 && currentMinute == 0 && currentSecond == 0)) {
    digitalWrite(ledPin, HIGH); // Включаем светодиод
    ledState = true;
    ledOnTime = millis(); // Запоминаем время включения
    Serial.println("LED turned ON");
  }

  // Если светодиод включен и прошло 7 секунд - выключаем
  if (ledState && (millis() - ledOnTime >= ledDuration)) {
    digitalWrite(ledPin, LOW);
    ledState = false;
    Serial.println("LED turned OFF");
  }

  // Выводим текущее время в монитор порта (для отладки)
  static unsigned long lastPrintTime = 0;
  if (millis() - lastPrintTime >= 1000) {
    lastPrintTime = millis();
    Serial.print("Current time: ");
    Serial.print(currentHour);
    Serial.print(":");
    Serial.print(currentMinute);
    Serial.print(":");
    Serial.print(currentSecond);
    Serial.print(" | Unix time: ");
    Serial.println(unixTime);
  }

  delay(200); // Небольшая задержка для стабильности
}
1 лайк

Будильник срабатывает, но не выключается через delay (7000) и время “зависает”.

//-------ПОДКЛЮЧЕНИЕ БИБЛИОТЕК
#include <Wire.h>                       // подключаем библиотеку I2C
#include <LiquidCrystal_I2C.h>          // подключаем библиотеку LCD-дисплея 1602
#include <iarduino_RTC.h>               // подключаем библиотеку RTC DS1302

//-------НАЗНАЧЕНИЕ ПИНОВ
const int PinRELE = 6;                  // вывод 6 к реле на "минус"

//МАССИВЫ ДЛЯ БУДИЛЬНИКОВ

uint8_t alarm_SEC    = 00;          // будильник №1 секунды
uint8_t alarm_MIN    = 46;          // будильник №1 минуты
uint8_t alarm_HOUR   = 10;          // будильник №1 часы

uint8_t alarm2_SEC   = 00;          // будильник №1 секунды
uint8_t alarm2_MIN   = 47;          // будильник №2 минуты
uint8_t alarm2_HOUR  = 10;          // будильник №2 часы

//-------ИНИЦИАЛИЗАЦИИ МОДУЛЕЙ
LiquidCrystal_I2C lcd(0x27,16,2);       // инициализируем LCD-дисплей 1602
iarduino_RTC time(RTC_DS1302, 5, 3, 4); // инициализируем модуль DS1302

//-------ОСНОВНАЯ НАСТРОЙКА
void setup() {
  delay(300);                          // задержка после иницализации
  Serial.begin(9600);                  // подключаем последовательный порт
  time.begin();                        // запускаем модуль RTC
  //time.settime(00,17,20,24,3,25,6);  // настраиваем время 0  сек, 17 мин, 20 часов, 24, март, 2025, суббота 

  lcd.init();                           // включаем LCD
  lcd.backlight();                      // включаем подсветку LCD
  lcd.setCursor(9,1);                   // помещаем курсор вниз вправо
  lcd.print("Rele-OF");                 // выводим надпись на LCD

  pinMode(PinRELE, OUTPUT);             // подключаем контакт реле на выход
  digitalWrite(PinRELE, HIGH);          // выключаем реле  - посылаем высокий сигнал

}

//-------ПРОГРАММА
void loop() {
  if (millis() % 1000 == 0) {                             // выводим время каждую секунду
      Serial.println(time.gettime("d-m-Y, H:i:s, D"));    // выводим время на последовательный порт
      delay(1);                                           // задержка в 1 мс

lcd.setCursor(0,0);                     // помещаем курсор вверх влево
lcd.print(time.gettime("d M Y"));       // выводим дату на LCD
lcd.setCursor(0,1);                     // помещаем курсор вниз влево
lcd.print(time.gettime("H:i:s"));       // выводим время на LCD
  }

//-------РАБОТА БУДИЛЬНИКОВ КОМПРЕССОРА
 if(time.Hours==alarm_HOUR){            // если совпали секунды
    if(time.minutes==alarm_MIN){        // если совпали минуты
      if(time.seconds==00){             // если совпали часы
        Func_alarm_action();
        delay(7000);                                                // задержка 7 секунд               // устанавливаем флаг, разрешающий будильнику №1 действовать
        }
      }
    }
 if(time.Hours==alarm2_HOUR){           // если совпали секунды
    if(time.minutes==alarm2_MIN){       // если совпали минуты
      if(time.seconds==00){             // если совпали часы
        Func_alarm2_action();           // устанавливаем флаг, разрешающий будильнику №2 действовать
        delay(7000);                    // задержка 7 секунд
       }
     }
   }

}
//-------ДЕЙСТВИЯ

void Func_alarm_action(){                                       // активируем действие
    lcd.setCursor(9,1);                                         // помещаем курсор вниз вправо
    lcd.print("Rele-ON");                                       // выводим надпись на LCD
    digitalWrite(PinRELE, LOW);                                 // выключаем/выключаем реле
}

void Func_alarm2_action(){                                      // активируем действие
    lcd.setCursor(9,1);                                         // помещаем курсор вниз вправо
    lcd.print("Rele-ON");                                       // выводим надпись на LCD
    digitalWrite(PinRELE, LOW);                                 // выключаем/выключаем реле
    delay(7000);                                                // задержка 7 секунд
}


Нашел ошибку в действии. Поправил, но ситуация не изменилась.

//-------ПОДКЛЮЧЕНИЕ БИБЛИОТЕК
#include <Wire.h>                       // подключаем библиотеку I2C
#include <LiquidCrystal_I2C.h>          // подключаем библиотеку LCD-дисплея 1602
#include <iarduino_RTC.h>               // подключаем библиотеку RTC DS1302

//-------НАЗНАЧЕНИЕ ПИНОВ
const int PinRELE = 6;                  // вывод 6 к реле на "минус"

//МАССИВЫ ДЛЯ БУДИЛЬНИКОВ

uint8_t alarm_SEC    = 00;          // будильник №1 секунды
uint8_t alarm_MIN    = 55;          // будильник №1 минуты
uint8_t alarm_HOUR   = 10;          // будильник №1 часы

uint8_t alarm2_SEC   = 00;          // будильник №1 секунды
uint8_t alarm2_MIN   = 56;          // будильник №2 минуты
uint8_t alarm2_HOUR  = 10;          // будильник №2 часы

//-------ИНИЦИАЛИЗАЦИИ МОДУЛЕЙ
LiquidCrystal_I2C lcd(0x27,16,2);       // инициализируем LCD-дисплей 1602
iarduino_RTC time(RTC_DS1302, 5, 3, 4); // инициализируем модуль DS1302

//-------ОСНОВНАЯ НАСТРОЙКА
void setup() {
  delay(300);                          // задержка после иницализации
  Serial.begin(9600);                  // подключаем последовательный порт
  time.begin();                        // запускаем модуль RTC
  //time.settime(00,17,20,24,3,25,6);  // настраиваем время 0  сек, 17 мин, 20 часов, 24, март, 2025, суббота 

  lcd.init();                           // включаем LCD
  lcd.backlight();                      // включаем подсветку LCD
  lcd.setCursor(9,1);                   // помещаем курсор вниз вправо
  lcd.print("Rele-OF");                 // выводим надпись на LCD

  pinMode(PinRELE, OUTPUT);             // подключаем контакт реле на выход
  digitalWrite(PinRELE, HIGH);          // выключаем реле  - посылаем высокий сигнал

}

//-------ПРОГРАММА
void loop() {
  if (millis() % 1000 == 0) {                             // выводим время каждую секунду
      Serial.println(time.gettime("d-m-Y, H:i:s, D"));    // выводим время на последовательный порт
      delay(1);                                           // задержка в 1 мс

lcd.setCursor(0,0);                     // помещаем курсор вверх влево
lcd.print(time.gettime("d M Y"));       // выводим дату на LCD
lcd.setCursor(0,1);                     // помещаем курсор вниз влево
lcd.print(time.gettime("H:i:s"));       // выводим время на LCD
  }

//-------РАБОТА БУДИЛЬНИКОВ КОМПРЕССОРА
 if(time.Hours==alarm_HOUR){            // если совпали секунды
    if(time.minutes==alarm_MIN){        // если совпали минуты
      if(time.seconds==00){             // если совпали часы
        Func_alarm_action();
        delay(7000);                                                // задержка 7 секунд               // устанавливаем флаг, разрешающий будильнику №1 действовать
        }
      }
    }
 if(time.Hours==alarm2_HOUR){           // если совпали секунды
    if(time.minutes==alarm2_MIN){       // если совпали минуты
      if(time.seconds==00){             // если совпали часы
        Func_alarm2_action();           // устанавливаем флаг, разрешающий будильнику №2 действовать
        delay(7000);                    // задержка 7 секунд
       }
     }
   }

}
//-------ДЕЙСТВИЯ

void Func_alarm_action(){                                       // активируем действие
    lcd.setCursor(9,1);                                         // помещаем курсор вниз вправо
    lcd.print("Rele-ON");                                       // выводим надпись на LCD
    digitalWrite(PinRELE, LOW);                                 // выключаем/выключаем реле
}

void Func_alarm2_action(){                                      // активируем действие
    lcd.setCursor(9,1);                                         // помещаем курсор вниз вправо
    lcd.print("Rele-OF");                                       // выводим надпись на LCD
    digitalWrite(PinRELE, HIGH);                                 // выключаем/выключаем реле
    delay(7000);                                                // задержка 7 секунд
}

Пипец вы темный
Вот вы свое реле в функции

включили. А выключать кто за вас будет, Пушкин?

Вам готовый пример выложили в #21 - что еще надо то? Даже просто скопировать не способны?

Только в условие в строке 40 стоит тоже проверку ledState добавить, а то светик на секунду дольше гореть будет.

Видимо гуманитарная составляющая доминирует.
…неясно зачем рыбкам секундная точность в кормлении.
…это к моменту :slight_smile:

иначе пришлось бы отслеживать срабатывание, чтобы не покормить рыбок дважды в течении одной минуты

:slight_smile:
Ох не знаю, я б тока часовой стрелкой при программировании пользовался бы.

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

Затроллили и зачмырили знатно))) Хочу просто понять, как работает. Спасибо всем за разъяснения!
Заработало, но есть нюансы…
Продолжительность будильника - 7 секунд. Когда он срабатывает, секунды “зависают” то на 6, то на 12 секунд, а выключается будильник через 12-16 секунд.

Помогите, плиз, понять проблему.

//-------ПОДКЛЮЧЕНИЕ БИБЛИОТЕК
#include <Wire.h>                        // подключаем библиотеку I2C
#include <LiquidCrystal_I2C.h>           // подключаем библиотеку LCD-дисплея 1602
#include <iarduino_RTC.h>                // подключаем библиотеку RTC DS1302

//-------НАЗНАЧЕНИЕ ПИНОВ
const int PinRELE = 6;                   // вывод 6 к реле на "минус"

//МАССИВЫ ДЛЯ БУДИЛЬНИКОВ
uint8_t alarm_SEC    = 00;               // будильник №1 секунды
uint8_t alarm_MIN    = 46;               // будильник №1 минуты
uint8_t alarm_HOUR   = 12;               // будильник №1 часы
uint8_t alarm2_SEC   = 00;               // будильник №1 секунды
uint8_t alarm2_MIN   = 47;               // будильник №2 минуты
uint8_t alarm2_HOUR  = 12;               // будильник №2 часы

//-------СТАТУСЫ
bool ReleState = false;                  // Состояние реле
unsigned long ReleTime = 0;              // Время включения реле
const unsigned long ReleDuration = 7000; // Длительность включения (7 секунд)

//-------ИНИЦИАЛИЗАЦИИ МОДУЛЕЙ
LiquidCrystal_I2C lcd(0x27,16,2);       // инициализируем LCD-дисплей 1602
iarduino_RTC time(RTC_DS1302, 5, 3, 4); // инициализируем модуль DS1302

//-------ОСНОВНАЯ НАСТРОЙКА
void setup() {
  delay(300);                          // задержка после иницализации
  Serial.begin(9600);                  // подключаем последовательный порт
  time.begin();                        // запускаем модуль RTC
  //time.settime(00,33,12,26,3,25,3);  // настраиваем время 0  сек, 17 мин, 20 часов, 24, март, 2025, суббота 

  lcd.init();                           // включаем LCD
  lcd.backlight();                      // включаем подсветку LCD
  lcd.setCursor(9,1);                   // помещаем курсор вниз вправо
  lcd.print("Rele-OF");                 // выводим надпись на LCD

  pinMode(PinRELE, OUTPUT);             // подключаем контакт реле на выход
  digitalWrite(PinRELE, HIGH);          // выключаем реле  - посылаем высокий сигнал

}

//-------ПРОГРАММА
void loop() {
  if (millis() % 1000 == 0) {                             // выводим время каждую секунду
      Serial.println(time.gettime("d-m-Y, H:i:s, D"));    // выводим время на последовательный порт
      delay(1);                                           // задержка в 1 мс

      lcd.setCursor(0,0);                                 // помещаем курсор вверх влево
      lcd.print(time.gettime("d M Y"));                   // выводим дату на LCD
      lcd.setCursor(0,1);                                 // помещаем курсор вниз влево
      lcd.print(time.gettime("H:i:s"));                   // выводим время на LCD
  }

//-------РАБОТА БУДИЛЬНИКОВ КОМПРЕССОРА

// если совпало время
 if(((time.Hours==alarm_HOUR) && (time.minutes==alarm_MIN) && (time.seconds==00)) || 
 ((time.Hours==alarm2_HOUR) && (time.minutes==alarm2_MIN) && (time.seconds==00))) { 
    lcd.setCursor(9,1);                                                         // помещаем курсор вниз вправо
    lcd.print("Rele-ON");                                                       // выводим надпись на LCD
    digitalWrite(PinRELE, LOW);                                                 // включаем реле
    ReleState = true;                                                           // ставим статус
    ReleTime = millis();                                                        // Запоминаем время включения
        }

//-------ВЫКЛЮЧЕНИЕ БУДИЛЬНИКА
 if (ReleState && (millis() - ReleTime >= ReleDuration)) {
    lcd.setCursor(9,1);                                         // помещаем курсор вниз вправо
    lcd.print("Rele-OF");                                       // выводим надпись на LCD
    digitalWrite(PinRELE, HIGH);                                // выключаем реле
    ReleState = false;                                          // ставим статус
   }
 }


Пробовал DS1302 менять. То же самое.

Для начала замените это на проверку разности, как в примере.

1 лайк

А где переменной time присваивается текущее время?
Зачем сравнение с time.seconds? При таком методе обновления данных легко можно не попасть в time.seconds==0

Вы про этот пример?

  static unsigned long lastPrintTime = 0;
  if (millis() - lastPrintTime >= 1000) {
    lastPrintTime = millis();

Да, про этот