• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Делюсь опытом астротаймер (восход/заход солнца)

Jon

Member
Давно искал программу для вычисления восхода и захода солнца, чтобы прикрутить ее к своему аквариуму.
На Муске нашел обзор под Ардуину: Бюджетный астротаймер за 4$
Автор грамотно все расписал, что покупать и как это все запустить.
Но мне нужно было под ESP 8266. Используемая библиотека часов реального времени в Ардуине немного иначе работает чем в ESP. Пришлось немного под шаманить скетч.
Вот что получилось:
Код:
// Астротаймер лайт — для управления освещением по времени заката и восхода солнца
// До использования настроить в модуле RTC текущее время: Примеры->DS1307RTC->SetTime
// При использовании настроить в TimeLord текущую дату, часовой пояс и географические координаты
// Прописать выход управления нагрузкой в #define REL

//исходный скетч под Ардуину опубликован на Муске, спасибо автору: http://mysku.ru/blog/aliexpress/42668.html
//библиотека TimeLord.h восход/закат берется от сюда: https://github.com/probonopd/TimeLord

#include <TimeLord.h> // вычисление времени заката и рассвета
#include <Wire.h>  // must be incuded here so that Arduino library object file references work
#include <RtcDS3231.h>

RtcDS3231 Rtc;

#define REL 12 // выход управления реле
#define DEBUG 1 // 1 включает сообщения отладки в монитор серийного порта. Скорость 115200

const int TIMEZONE = +3; // установка часового пояса (С-Петербург)
const float LATITUDE = 59.93, LONGITUDE = 30.26; // установка координат: широта, долгота

TimeLord myLord; // переменные TimeLord
byte sunTime[6];
int minNow, minLast = -1, hourNow, hourLast = -1, minOfDay; // -1 отрабатывает при первом запуске
int mSunrise, mSunset; //время рассвета и заката в минутах от начала дня (0-1439)

// настройка
void setup()
{
  Serial.begin(9600); // старт соединенияи и установка скорости
  pinMode(REL, OUTPUT); // инициализируем порт для канала реле как выход
  digitalWrite(REL , HIGH); // устанавливаем на входе релейного модуля высокий уровень — реле выключено
  myLord.TimeZone(TIMEZONE * 60);
  myLord.Position(LATITUDE, LONGITUDE);

  //--------RTC SETUP ------------
  Rtc.Begin();
  //#if defined(ESP8266)//если ESP8266-01
  //    Wire.begin(0, 2);
  //#endif
  Wire.begin(); //иначе по умолчанию GPIO 4,5

  RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);

  if (!Rtc.IsDateTimeValid())
  {
    Serial.println("RTC lost confidence in the DateTime!");
    Rtc.SetDateTime(compiled);
  }

  RtcDateTime now = Rtc.GetDateTime();
  if (now < compiled)
  {
    Serial.println("RTC is older than compile time!  (Updating DateTime)");
    Rtc.SetDateTime(compiled);
  }

  Rtc.Enable32kHzPin(false);
  Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmBoth);
 
      Serial.println();
}

// основной цикл
void loop()
{
  if (Rtc.IsDateTimeValid())
  {
    RtcDateTime now = Rtc.GetDateTime();
    delay(10000); // ten seconds

    DateTime(now);

    if (minNow != minLast)
    {
      minLast = minNow;
      minOfDay = hourNow * 60 + minNow; //текущая минута дня 0-1439
#if DEBUG == 1
      Serial.print("TimeNow: ");
      Serial.print(hourNow);
      Serial.print("-");
      Serial.print(minNow);
      Serial.println();
#endif
      if (hourNow != hourLast) // расчет времени рассвета и заката при изменении часа (раз в час)
      {
        //Время рассвета и заката в минутах от начала дня
        myLord.SunRise(sunTime); // расчетные данные рассвета из TimeLord
#if DEBUG == 1
        Serial.print(" SUNRISE:");
        Serial.print(sunTime[2]);
        Serial.print(":");
        Serial.print(sunTime[1] + 1); //уточненные данные +1 мин
#endif
        mSunrise = sunTime[2] * 60 + sunTime[1];// где "+20" задержка выключения реле утром в минутах
        myLord.SunSet(sunTime); // расчетные данные заката из TimeLord
#if DEBUG == 1
        Serial.print(" SUNSET:");
        Serial.print(sunTime[2]);
        Serial.print(":");
        Serial.print(sunTime[1] + 1); //уточненные данные +1 мин
#endif
        mSunset = sunTime[2] * 60 + sunTime[1];// +15 задержка вкл реле вечером
#if DEBUG == 1
        Serial.print(" ");
        Serial.print("DATE: ");
        Serial.print( sunTime[3]);
        Serial.print("/");
        Serial.print( sunTime[4]);
        Serial.print("/");
        Serial.print( sunTime[5]);
        Serial.println();
#endif
        hourLast = hourNow;
      }
      //управляем реле
      if (minOfDay < mSunrise || minOfDay >= mSunset) // если минут с начала суток меньше, чем время рассвета, но больше, чем время заката
        digitalWrite(REL, LOW); // то устанавливаем на входе релейного модуля низкий уровень уровень — реле срабатывает
      else // во всех остальных случаях
        digitalWrite(REL, HIGH); // устанавливаем на входе релейного модуля высокий уровень — реле выключается
#if DEBUG == 1
      Serial.print("RELE:");
      Serial.print(minOfDay < mSunrise || minOfDay >= mSunset);
      Serial.println();
#endif
    } // End: if (minNow != minLast)
  } // End: if (timeStatus()!= timeNotSet)
} // End loop()


void DateTime(const RtcDateTime& dt)
{
  sunTime[3] = dt.Day();
  sunTime[4] = dt.Month();
  sunTime[5] = dt.Year() - 2000;
  hourNow = dt.Hour();
  minNow = dt.Minute();
}
////////////////////////////////////////
У меня почему то на одну минуту занижал время восхода и захода. Добавил корректировкой.
 
Сверху Снизу