• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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();
}
////////////////////////////////////////
У меня почему то на одну минуту занижал время восхода и захода. Добавил корректировкой.
 
Сверху Снизу