├── .gitattributes
├── .github
└── workflows
│ └── tg-send.yml
├── LICENSE
├── README.md
├── README_EN.md
├── doc
└── angles.png
├── examples
└── demo
│ └── demo.ino
├── keywords.txt
├── library.properties
└── src
└── SunPosition.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/workflows/tg-send.yml:
--------------------------------------------------------------------------------
1 |
2 | name: Telegram Message
3 | on:
4 | release:
5 | types: [published]
6 | jobs:
7 | build:
8 | name: Send Message
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: send telegram message on push
12 | uses: appleboy/telegram-action@master
13 | with:
14 | to: ${{ secrets.TELEGRAM_TO }}
15 | token: ${{ secrets.TELEGRAM_TOKEN }}
16 | disable_web_page_preview: true
17 | message: |
18 | ${{ github.event.repository.name }} v${{ github.event.release.tag_name }}
19 | ${{ github.event.release.body }}
20 | https://github.com/${{ github.repository }}
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Alex
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/GyverLibs/SunPosition/releases/latest/download/SunPosition.zip)
2 | [](https://registry.platformio.org/libraries/gyverlibs/SunPosition)
3 | [](https://alexgyver.ru/)
4 | [](https://alexgyver.ru/support_alex/)
5 | [](https://github-com.translate.goog/GyverLibs/SunPosition?_x_tr_sl=ru&_x_tr_tl=en)
6 |
7 | [](https://t.me/GyverLibs)
8 |
9 | # SunPosition
10 | Библиотека для определения положения солнца по геолокации и времени
11 | - Берёт широту, долготу и unix время
12 | - Выдаёт угол по азимуту, угол возвышения и склонения солнца
13 |
14 | ### Совместимость
15 | Совместима со всеми Arduino платформами (используются Arduino-функции)
16 |
17 | ## Содержание
18 | - [Установка](#install)
19 | - [Инициализация](#init)
20 | - [Использование](#usage)
21 | - [Пример](#example)
22 | - [Версии](#versions)
23 | - [Баги и обратная связь](#feedback)
24 |
25 |
26 | ## Установка
27 | - Библиотеку можно найти по названию **SunPosition** и установить через менеджер библиотек в:
28 | - Arduino IDE
29 | - Arduino IDE v2
30 | - PlatformIO
31 | - [Скачать библиотеку](https://github.com/GyverLibs/SunPosition/archive/refs/heads/main.zip) .zip архивом для ручной установки:
32 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64)
33 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32)
34 | - Распаковать и положить в *Документы/Arduino/libraries/*
35 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив
36 | - Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
37 | ### Обновление
38 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
39 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
40 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!
41 |
42 |
43 |
44 | ## Инициализация
45 | ```cpp
46 | // инициализировать без расчёта
47 | SunPosition pos;
48 |
49 | // указать широту (градусы), долготу (градусы), unix время (секунды), будет выполнен расчёт
50 | SunPosition(latitude, longitude, unix);
51 | SunPosition(latitude, longitude, unix, gmt); // + часовой пояс в часах или минутах
52 | ```
53 |
54 |
55 | ## Использование
56 | ```cpp
57 | // выполнить расчёт, указать широту (градусы), долготу (градусы), unix время (секунды)
58 | void compute(float latitude, float longitude, uint32_t unix);
59 |
60 | // выполнить расчёт, указать широту (градусы), долготу (градусы), unix время (секунды), часовой пояс в часах или минутах
61 | void compute(float latitude, float longitude, uint32_t unix, int16_t gmt);
62 |
63 | int sunrise(); // время рассвета, в минутах от начала дня по локальному времени
64 | int noon(); // полдень, в минутах от начала дня по локальному времени
65 | int sunset(); // время заката, в минутах от начала дня по локальному времени
66 | int daylight(); // длительность светового дня, в минутах
67 | float altitude(); // угол возвышения
68 | float declination(); // угол склонения
69 | float zenith(); // угол зенита в полдень
70 | float azimuth(); // азимут солнца, от севера по часовой стрелке
71 | int azimuthMin(); // азимут рассвета
72 | int azimuthMax(); // азимут заката
73 | int angle180(); // азимут, масштабированный в диапазон 0-180 градусов для поворота солнечной панели (летом 0..180, зимой 50.. 130)
74 | int angle90(); // азимут, масштабированный в диапазон -90..90 градусов для поворота солнечной панели (летом -90..90, зимой -20.. 20)
75 | ```
76 |
77 | - Широту и долготу места можно взять из любых карт (Яндекс, Google)
78 | - Unix время можно взять из любого источника реального времени (RTC, NTP), а также конвертировать из даты и времени при помощи библиотеки [UnixTime](https://github.com/GyverLibs/UnixTime)
79 |
80 | 
81 | - **Угол склонения** - угол от направления на солнце в точке равноденствия, меняется в течение года. Сам угол равноденствия равен `90 - широта`
82 | - **Азимут** - направление на солнце по горизонтали, считается от направления на Север по часовой стрелке
83 | - **Возвышение** - направление на солнце по вертикали от горизонта
84 |
85 |
86 | ## Пример
87 | ```cpp
88 | #include
89 |
90 | void setup() {
91 | Serial.begin(9600);
92 | SunPosition sun(55.75, 37.62, 1658325600);
93 | //sun.compute(55.75, 37.62, 1658325600);
94 | Serial.println(sun.altitude());
95 | Serial.println(sun.azimuth());
96 | Serial.println(sun.declination());
97 | }
98 |
99 | void loop() {
100 | }
101 | ```
102 |
103 |
104 | ## Версии
105 | - v1.0
106 | - v1.1 - полностью переписаны уравнения, добавлен вывод времени и азимута заката/рассвета и другие полезные углы (см. доку)
107 |
108 |
109 | ## Баги и обратная связь
110 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
111 | Библиотека открыта для доработки и ваших **Pull Request**'ов!
112 |
113 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:
114 | - Версия библиотеки
115 | - Какой используется МК
116 | - Версия SDK (для ESP)
117 | - Версия Arduino IDE
118 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
119 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности
120 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код
121 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | This is an automatic translation, may be incorrect in some places. See sources and examples!
2 |
3 | # Sunposition
4 | Library for determining the position of the Sun by geolocation and time
5 | - takes breadth, longitude and unix time
6 | - gives an angle by azimuth, the angle of elevation and declination of the sun
7 |
8 | ## compatibility
9 | Compatible with all arduino platforms (used arduino functions)
10 |
11 | ## Content
12 | - [installation] (# Install)
13 | - [initialization] (#init)
14 | - [use] (#usage)
15 | - [Example] (# Example)
16 | - [versions] (#varsions)
17 | - [bugs and feedback] (#fedback)
18 |
19 |
20 | ## Installation
21 | - The library can be found by the name ** suposition ** and installed through the library manager in:
22 | - Arduino ide
23 | - Arduino ide v2
24 | - Platformio
25 | - [download the library] (https://github.com/gyverlibs/sunposition/archive/refs/heads/main.zip) .Zip archive for manual installation:
26 | - unpack and put in * C: \ Program Files (X86) \ Arduino \ Libraries * (Windows X64)
27 | - unpack and put in * C: \ Program Files \ Arduino \ Libraries * (Windows X32)
28 | - unpack and put in *documents/arduino/libraries/ *
29 | - (Arduino id) Automatic installation from. Zip: * sketch/connect the library/add .Zip library ... * and specify downloaded archive
30 | - Read more detailed instructions for installing libraries [here] (https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%BD%D0%BE%BE%BE%BED0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
31 | ### Update
32 | - I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added
33 | - through the IDE library manager: find the library how to install and click "update"
34 | - Manually: ** remove the folder with the old version **, and then put a new one in its place.“Replacement” cannot be done: sometimes in new versions, files that remain when replacing are deleted and can lead to errors!
35 |
36 |
37 |
38 | ## initialization
39 | `` `CPP
40 | // initialize without calculation
41 | SunPounion POS;
42 |
43 | // indicate latitude (degrees), longitude (degrees), unix time (seconds), a calculation will be performed
44 | SunPounion (Latitude, Longitude, Unix);
45 | SunPounion (Latitude, Longitude, Unix, GMT);// + hourly belt in hours or minutes
46 | `` `
47 |
48 |
49 | ## Usage
50 | `` `CPP
51 | // perform the calculation, indicate the latitude (degrees), longitude (degrees), unix time (seconds)
52 | Void Compute (Float Latitude, Float Longitude, Uint32_T Unix);
53 |
54 | // perform the calculation, specify the latitude (degrees), longitude (degrees), unix time (seconds), an hourly belt in hours or minutes
55 | Void Compute (Float Latitude, Float Longitude, Uint32_T Unix, Int16_T GMT);
56 |
57 | int sunrise ();// Dawn time, minutes from the beginning of the day in local time
58 | int noon ();// Half, in minutes from the beginning of the day in local time
59 | int sunset ();// Sunset time, minutes from the beginning of the day in local time
60 | int daylight ();// Duration of daylight hours, in minutes
61 | Float altitude ();// Avoor angle
62 | Float Decline ();// angle of declension
63 | Float Zenith ();// Zenit angle at noon
64 | Float Azimuth ();// Azimuth of the Sun, from the north clockwise
65 | int Azimuthmin ();// Azimuth of Dawn
66 | int Azimuthmax ();// Azimuth of sunset
67 | int angle180 ();// azimuth, scaled in the range 0-180 degrees DCranberries of turning the solar panel (in summer 0..180, in winter 50 .. 130)
68 | int angle90 ();// Azimuth, scaled in the range -90..90 degrees for turning the solar panel (in summer -90..90, in winter -20 .. 20)
69 | `` `
70 |
71 | - The latitude and longitude can be taken from any cards (Yandex, Google)
72 | - Unix time can be taken from any real time source (RTC, NTP), and also converted from the date and time using the library [unixtime] (https://github.com/gyverlibs/unixtime)
73 |
74 | ! [Diagram] (/doc/angles.png)
75 | - ** The angle of declension ** - the angle from the direction to the sun at the point of the equinox, changes during the year.The angle of equinox itself is `90 - LATE`
76 | - ** azimuth ** - a direction in the sun is horizontally, it is considered from the direction to the north clockwise
77 | - ** elevation ** - a direction in the sun vertically from the horizon
78 |
79 |
80 | ## Example
81 | `` `CPP
82 | #include
83 |
84 | VOID setup () {
85 | Serial.Begin (9600);
86 | SunPounion Sun (55.75, 37.62, 1658325600);
87 | //sun.computE(55.75, 37.62, 1658325600);
88 | Serial.println (sun.altite ());
89 | Serial.println (sun.azimuth ());
90 | Serial.println (sun.Decline ());
91 | }
92 |
93 | VOID loop () {
94 | }
95 | `` `
96 |
97 |
98 | ## versions
99 | - V1.0
100 | - V1.1 - the equations are completely rewritten, the output of the time and the azimuth of sunset/dawn and other useful angles (see Doku) have been added
101 |
102 |
103 | ## bugs and feedback
104 | Create ** Issue ** when you find the bugs, and better immediately write to the mail [alex@alexgyver.ru] (mailto: alex@alexgyver.ru)
105 | The library is open for refinement and your ** pull Request ** 'ow!
106 |
107 | When reporting about bugs or incorrect work of the library, it is necessary to indicate:
108 | - The version of the library
109 | - What is MK used
110 | - SDK version (for ESP)
111 | - version of Arduino ide
112 | - whether the built -in examples work correctly, in which the functions and designs are used, leading to a bug in your code
113 | - what code has been loaded, what work was expected from it and how it works in reality
114 | - Ideally, attach the minimum code in which the bug is observed.Not a canvas of a thousand lines, but a minimum code
--------------------------------------------------------------------------------
/doc/angles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GyverLibs/SunPosition/f4b8d98fcc0ec3708846b9bd37d9344fbf755b39/doc/angles.png
--------------------------------------------------------------------------------
/examples/demo/demo.ino:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | void setup() {
4 | Serial.begin(9600);
5 | SunPosition sun(55.75, 37.62, 1658325600);
6 | //sun.compute(55.75, 37.62, 1658325600);
7 | Serial.println(sun.altitude());
8 | Serial.println(sun.azimuth());
9 | Serial.println(sun.declination());
10 | }
11 |
12 | void loop() {
13 | }
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map For SunPosition
3 | #######################################
4 |
5 | #######################################
6 | # Datatypes (KEYWORD1)
7 | #######################################
8 | SunPosition KEYWORD1
9 | SP_PRECISE KEYWORD1
10 |
11 | #######################################
12 | # Methods and Functions (KEYWORD2)
13 | #######################################
14 | compute KEYWORD2
15 | altitude KEYWORD2
16 | azimuth KEYWORD2
17 | azimuthMin KEYWORD2
18 | azimuthMax KEYWORD2
19 | declination KEYWORD2
20 | angle180 KEYWORD2
21 | angle90 KEYWORD2
22 | zenith KEYWORD2
23 | sunrise KEYWORD2
24 | noon KEYWORD2
25 | sunset KEYWORD2
26 | daylight KEYWORD2
27 |
28 | #######################################
29 | # Constants (LITERAL1)
30 | #######################################
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=SunPosition
2 | version=1.2.0
3 | author=AlexGyver
4 | maintainer=AlexGyver
5 | sentence=Library for tracking Sun position by location and time for Arduino
6 | paragraph=Library for tracking Sun position by location and time for Arduino
7 | category=Data Processing
8 | url=https://github.com/GyverLibs/SunPosition
9 | architectures=*
10 |
--------------------------------------------------------------------------------
/src/SunPosition.h:
--------------------------------------------------------------------------------
1 | /*
2 | Библиотека для определения положения солнца по геолокации и времени
3 | Документация:
4 | GitHub: https://github.com/GyverLibs/SunPosition
5 | Возможности:
6 | - Берёт широту, долготу и unix время
7 | - Выдаёт угол по азимуту, угол возвышения и склонения солнца
8 |
9 | AlexGyver, alex@alexgyver.ru
10 | https://alexgyver.ru/
11 | MIT License
12 |
13 | v1.1 - полностью переписаны уравнения, добавлен вывод времени и азимута заката/рассвета и другие полезные углы (см. доку)
14 | */
15 |
16 | /*
17 | Источники:
18 | Astronomical Almanac p C2
19 | https://www.astrogreg.com/snippets/equationoftime-simple.html
20 | https://www.itacanet.org/the-sun-as-a-source-of-energy/part-3-calculating-solar-angles/
21 | https://webcms3.cse.unsw.edu.au/ENGG1811/16s1/forums/514357
22 | https://gml.noaa.gov/grad/solcalc/calcdetails.html
23 | нужен double! http://users.electromagnetic.net/bu/astro/sunrise-set.php
24 |
25 | для проверки https://www.suncalc.org/
26 | http://www.geoastro.de/astro/suncalc/index.htm
27 | */
28 |
29 | #ifndef _SunPosition_h
30 | #define _SunPosition_h
31 | #include
32 |
33 | struct SunPosition {
34 | // просто создать
35 | SunPosition() {}
36 |
37 | // указать широту (градусы), долготу (градусы), unix время (секунды), часовой пояс в часах или минутах. Будет выполнен расчёт
38 | SunPosition(float lat, float lon, uint32_t unix, int16_t gmt = 0) {
39 | compute(lat, lon, unix, gmt);
40 | }
41 |
42 | // выполнить расчёт, указать широту (градусы), долготу (градусы), unix время (секунды), часовой пояс в часах или минутах
43 | void compute(float lat, float lon, uint32_t unix, int16_t gmt = 0) {
44 | lat = radians(lat);
45 | float hours = (unix % 86400ul) / 86400.0; // decimal hours
46 | #ifndef SP_PRECISE
47 | int day = fmod(unix / 86400.0, 365.25);
48 | float t = radians(279.342 + 0.985647 * day); // temp
49 | float eqTime = (-104.9 * sin(t) + 596.2 * sin(2 * t) + 4.3 * sin(3 * t) - 12.7 * sin(4 * t) - 429.3 * cos(t) - 2.0 * cos(2 * t) + 19.3 * cos(3 * t)) / 60.0; // time equation
50 | t = (day + hours / 24 - 1.5) * TWO_PI / 365; // temp
51 | decl = 0.006918 - 0.4 * cos(t) + 0.070257 * sin(t) - 0.006758 * cos(t * 2) + 0.000907 * sin(t * 2) - 0.002697 * cos(t * 3) + 0.00148 * sin(t * 3); // declination
52 | #else
53 | float JulCent = (unix / 86400.0 - 10957.5) / 36525.0; // Julian Century
54 | float GeomMeanLong = radians(fmod(280.46646 + JulCent * (36000.76983 + JulCent * 0.0003032), 360)); // Geom Mean Long Sun
55 | float GeomMeanAnom = radians(357.52911 + JulCent * (36000 - 0.0001537 * JulCent)); // Geom Mean Anom Sun
56 | float EccEart = 0.016708634 - JulCent * (0.000042037 + 0.0000001267 * JulCent); // Eccent Earth Orbit
57 | float SunEqCtr = radians(sin(GeomMeanAnom) * (1.914602 - JulCent * (0.004817 + 0.000014 * JulCent)) + sin(2 * GeomMeanAnom) * (0.019993 - 0.000101 * JulCent) + sin(3 * GeomMeanAnom) * 0.000289); // Sun Eq of Ctr
58 | float SunApp = GeomMeanLong + SunEqCtr - 0.0001 - 0.00008 * sin(radians(125.04 - 1934.136 * JulCent)); // Sun App Long
59 | float MeanOblq = 23 + (26 + ((21.448 - JulCent * (46.815 + JulCent * (0.00059 - JulCent * 0.001813)))) / 60.0) / 60.0; // Mean Obliq Ecliptic
60 | float ObliqCor = radians(MeanOblq + 0.00256 * cos(radians(125.04 - 1934.136 * JulCent))); // Obliq Corr
61 | decl = asin(sin(ObliqCor) * sin(SunApp)); // Sun Declin
62 | float y = tan(ObliqCor / 2) * tan(ObliqCor / 2);
63 | float eqTime = 4 * degrees(y * sin(2 * GeomMeanLong) - 2 * EccEart * sin(GeomMeanAnom) + 4 * EccEart * y * sin(GeomMeanAnom) * cos(2 * GeomMeanLong) - 0.5 * y * y * sin(4 * GeomMeanLong) - 1.25 * EccEart * EccEart * sin(2 * GeomMeanAnom)); // Eq of Time (minutes)
64 | #endif
65 | ha = degrees(acos(-0.01454 / (cos(lat) * cos(decl)) - tan(lat) * tan(decl))); // HA sunrise
66 | if (abs(gmt) <= 12) gmt *= 60; // gmt -> minutes
67 | noonT = 720 - 4 * lon - eqTime + gmt; // Solar Noon (min) + gmt
68 | float hrAngl = fmod(hours * 1440 + eqTime + 4 * lon, 1440) / 4; // True Solar Time (min)
69 | hrAngl = hrAngl + (hrAngl < 0 ? 180 : -180); // Hour Angle
70 | zen = acos(sin(lat) * sin(decl) + cos(lat) * cos(decl) * cos(radians(hrAngl))); // Zenith
71 | azm = degrees(acos(((sin(lat) * cos(zen)) - sin(decl)) / (cos(lat) * sin(zen)))); // Azimuth
72 | decl = degrees(decl);
73 | alt = 90 - degrees(zen);
74 | azm = (hrAngl > 0) ? (azm + 180) : (540 - azm);
75 | azm = fmod(azm, 360);
76 | zen = 90 - degrees(lat) + decl;
77 | //angle = round(ha); // 8 * ha * 360 / 60 / 24 / 2
78 | }
79 |
80 | // время рассвета, в минутах от начала дня по локальному времени
81 | int sunrise() {
82 | return noonT - ha * 4;
83 | }
84 |
85 | // полдень, в минутах от начала дня по локальному времени
86 | int noon() {
87 | return noonT;
88 | }
89 |
90 | // время заката, в минутах от начала дня по локальному времени
91 | int sunset() {
92 | return noonT + ha * 4;
93 | }
94 |
95 | // длительность светового дня, в минутах
96 | int daylight() {
97 | return ha * 8;
98 | }
99 |
100 | // угол возвышения
101 | float altitude() {
102 | return alt;
103 | }
104 |
105 | // угол склонения
106 | float declination() {
107 | return decl;
108 | }
109 |
110 | // угол зенита
111 | float zenith() {
112 | return zen;
113 | }
114 |
115 | // азимут солнца, от севера по часовой стрелке
116 | float azimuth() {
117 | return azm;
118 | }
119 |
120 | // азимут рассвета
121 | int azimuthMin() {
122 | return (180 - round(ha));
123 | }
124 |
125 | // азимут заката
126 | int azimuthMax() {
127 | return (180 + round(ha));
128 | }
129 |
130 | // азимут, масштабированный в диапазон 0..180 градусов для поворота солнечной панели (летом 0..180, зимой 50.. 130)
131 | int angle180() {
132 | int a = round(ha);
133 | a = map(azm, 180 - a, 180 + a, 90 - min(a, 90), 90 + min(a, 90));
134 | a = constrain(a, 0, 180);
135 | return a;
136 | }
137 |
138 | // азимут, масштабированный в диапазон -90..90 градусов для поворота солнечной панели (летом -90..90, зимой -20.. 20)
139 | int angle90() {
140 | return angle180() - 90;
141 | }
142 |
143 | float alt = 0, azm = 0, decl = 0, zen = 0, ha = 0;
144 | uint16_t noonT = 0;
145 | };
146 |
147 | /*
148 | // без оптимизации
149 | float JulDay = unixSecs / 86400.0 + 2440587.5; // Julian day
150 | float JulCent = (JulDay - 2451545.0) / 36525.0; // Julian Century
151 | float GeomMeanLong = fmod(280.46646 + JulCent * (36000.76983 + JulCent * 0.0003032), 360); // Geom Mean Long Sun
152 | float GeomMeanAnom = 357.52911 + JulCent * (35999.05029 - 0.0001537 * JulCent); // Geom Mean Anom Sun
153 | float EccEart = 0.016708634 - JulCent * (0.000042037 + 0.0000001267 * JulCent); // Eccent Earth Orbit
154 | float SunEqCtr = sin(radians(GeomMeanAnom)) * (1.914602 - JulCent * (0.004817 + 0.000014 * JulCent)); // Sun Eq of Ctr
155 | SunEqCtr += sin(2 * radians(GeomMeanAnom)) * (0.019993 - 0.000101 * JulCent);
156 | SunEqCtr += sin(3 * radians(GeomMeanAnom)) * 0.000289;
157 | float SunTrLong = GeomMeanLong + SunEqCtr; // Sun True Long
158 | float SunTrAnom = GeomMeanAnom + SunEqCtr; // Sun True Anom
159 | float SunRad = (1.000001018 * (1.0 - EccEart * EccEart)) / (1 + EccEart * cos(radians(SunTrAnom))); // Sun Rad Vector (AUs)
160 | float SunApp = SunTrLong - 0.00569 - 0.00478 * sin(radians(125.04 - 1934.136 * JulCent)); // Sun App Long
161 | float MeanOblq = 23 + (26 + ((21.448 - JulCent * (46.815 + JulCent * (0.00059 - JulCent * 0.001813)))) / 60.0) / 60.0; // Mean Obliq Ecliptic
162 | float ObliqCor = MeanOblq + 0.00256 * cos(radians(125.04 - 1934.136 * JulCent)); // Obliq Corr
163 | float SunDecl = degrees(asin(sin(radians(ObliqCor)) * sin(radians(SunApp)))); // Sun Declin
164 | float y = tan(radians(ObliqCor / 2)) * tan(radians(ObliqCor / 2));
165 | float EqTime = 4 * degrees(y * sin(2 * radians(GeomMeanLong)) - 2 * EccEart * sin(radians(GeomMeanAnom)) + 4 * EccEart * y * sin(radians(GeomMeanAnom)) * cos(2 * radians(GeomMeanLong)) - 0.5 * y * y * sin(4 * radians(GeomMeanLong)) - 1.25 * EccEart * EccEart * sin(2 * radians(GeomMeanAnom))); // Eq of Time (minutes)
166 | float HA = degrees(acos(cos(radians(90.833)) / (cos(radians(lat)) * cos(radians(SunDecl))) - tan(radians(lat)) * tan(radians(SunDecl)))); // HA Sunrise
167 | int GMT = 0;
168 | float SunN = 720 - 4 * lon - EqTime + GMT * 60; // Solar Noon (LST) + gmt
169 | float SunR = SunN - HA * 4; // Sunrise Time (LST) + gmt
170 | float SunS = SunN + HA * 4; // Sunset Time (LST) + gmt
171 | float SunL = 8 * HA; // Sunlight Duration (minutes) minutes
172 | float hours = (unixSecs % 86400) / 86400.0;
173 | float TrueSol = fmod(hours * 1440 + EqTime + 4 * lon, 1440); // True Solar Time (min)
174 | float HourAngle = (TrueSol / 4 < 0) ? TrueSol / 4 + 180 : TrueSol / 4 - 180; // Hour Angle
175 | float Zenith = degrees(acos(sin(radians(lat)) * sin(radians(SunDecl)) + cos(radians(lat)) * cos(radians(SunDecl)) * cos(radians(HourAngle))));
176 | float Elev = 90 - Zenith;
177 | float Azim = degrees(acos(((sin(radians(lat)) * cos(radians(Zenith))) - sin(radians(SunDecl))) / (cos(radians(lat)) * sin(radians(Zenith)))));
178 | if (HourAngle > 0) Azim = Azim + 180;
179 | else Azim = 540 - Azim;
180 | Azim = fmod(Azim, 360);
181 | */
182 | #endif
183 |
--------------------------------------------------------------------------------