Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Продам/куплю/услуги » Куплю функцию Рассвет-Закат


Куплю функцию Рассвет-Закат

Сообщений 1 страница 11 из 11

1

Куплю функцию для BascomAVR
Входные данные - координаты GPS
Выходные данные -  Рассвет, Восход, Полдень, Закат, Сумерки (Гражданские)

0

2

Можно попробовать; но

А. сформулируйте, пожалуйста, поточнее ТЗ:

1) формат координат: десятичные / минуты-секунды;
2) допустимо ли подавать на вход смещение часового пояса относительно GMT/UTC + (-), либо функция должна определять часовой пояс, а также декретные (летние) времена автоматически по координатам? (не рекомендую, т.к. это изменчивая материя);
3) очевидно, на вход также должна подаваться дата

В. требования к объему занимаемой памяти и быстродействию; дело в том, что в расчет привлекаются тригонометрические ф-ции и числа типа single, которые занимают много памяти и/или работают медленно.

С. требуемая точность. если +-5 мин, можно не принимать в расчет диаметр солнечного диска; если +-2 мин, то его, а также кое-какие еще факторы следует учитывать; если +-1 мин, то требуются дополнительные тонкие коррекции.

D. оплата: размер, способ и т.д.

Отредактировано Cirno_9 (2019-11-06 13:50:47)

0

3

См. книгу Н.Заяц. Вроде там это встречал.
там ассемблер PIC, но был подробный алгоритм.

Отредактировано Александр Д. (2019-11-06 15:50:03)

0

4

Спасибо что откликнулись.

Не большое пояснение для лучшего понимания ситуации, эта функция нужна для создаваемых мной часов и брелков с LoRA-модемом которые почти постоянно будут работать в связке с андроид телефоном через блютуз.

А.1 Формат тот что возвращает GPS в андроиде.
А.2 Часовой пояс, время и т.д. можно высчитывать при получении GPS координат от телефона на андроиде. Телефон передаст и коородинаты и текущее время и время с GPS.
А.3 Да. Она также передается с телефона по блютузу в МК AVR.

В. Функция будет запускаться не чаще чем один раз в час и то при условии существенных изменений координат. Так что времени будет более чем предостаточно. Так же на борту будет слот для MicroSd карты. Так что флешпамяти хоть 128 Гб можно поставить.

С. Точности +-5 минут более чем достаточно. Если есть смысл, можно еще загрубить точность.

D. Оплата проще всего на карту сбербанка.

Готов, по предварительной договоренности, почти в любое время пообщаться голосом по телефону, вайберу или ватсапу +7 девять два три семерки 018 две семерки.

0

5

Александр Д. написал(а):

См. книгу Н.Заяц. Вроде там это встречал.
там ассемблер PIC, но был подробный алгоритм.

Вот что я нашел в процессе изучения данного вопроса.

https://esp8266.ru/forum/threads/astrot … lnca.1512/
https://mysku.ru/blog/aliexpress/42668.html
http://www.tdoc.ru/c/delphi-sources/alg … -luny.html
http://www.tdoc.ru/c/delphi-sources/alg … page2.html
http://mikereedell.github.io/sunrisesunsetlib-java/
https://switch-case.ru/10681204
http://www.cyberforum.ru/assembler-math … 54264.html
https://github.com/Vinalex/solarEvent?files=1

# coding=utf-8
from datetime import  timedelta, date, datetime
from math import floor, sin, cos, tan, asin, acos, atan
from tools import *
import cities
class Sun:
def __init__(self, city=cities.Moscow):
#Словарь интервала дат + 2 даты (крайние для расчета солнечного дня), со значениями восхода\захода
self.dateRangeSun = dict()
#Объект - город, содержащий параметры координат и часового смещения
self.city = city
#Углы зенита для разных положения солнца
self.zenith = {'Offical': time2deg([90, 50, 0]),
   'Civil': time2deg([96, 0, 0]),
   'Nautical': time2deg([102, 0, 0]),
   'Astronomical': time2deg([108, 0, 0])}
#Главная функция
def getResult(self, dates=date.today().strftime('%d.%m.%Y')):
#Получаем диапазон дат, dstetime
dates = self._datesRange(dates)
#Для всез дат из диапазона
for focusDate in dates:
#Получаем параметры солнца
self._getSun(focusDate)
#Создания списка дат из диапазона
def _datesRange(self, dates):
dates = {datetime.strptime(focusDate, '%d.%m.%Y').date() for focusDate in dates.split('-')}
if len(dates) == 2:
dateBegin, dateEnd = sorted(dates)
daysRange = dateEnd-dateBegin
for i in range(daysRange.days+1):
dates.add(dateBegin+timedelta(i))
return dates
#Получение параметров солнца
def _getSun(self, focusDate):
#Список смещений для соседей
directDisp = range(-1, 2)
#Срез с данными мз 3х дат для расчета светового и темного дня
section = list()
#Для всех смещений
for disp in directDisp:
#Получаем дату со смещением относительно фокусной даты
dispDate = focusDate + timedelta(disp)
#Если такой даты в глобальном списке нет, то
if not dispDate in self.dateRangeSun:
#Определяем параметры солнца в глобальном словаре дат
self.dateRangeSun[dispDate] = self._sunInfo(dispDate)
#Попутно, составляем список-срез из 3х дат для расчета светлого и темного времени суток
section.append([self.dateRangeSun[dispDate], chSign(disp)])
#ПРоверяем, если для фокусной даты, уже расчитаны эти параметры, то опускаем расчеты
if not (self.dateRangeSun[focusDate].get('Light') and self.dateRangeSun[focusDate].get('Dark')):
self.dateRangeSun[focusDate].update(self._lightDark(section))
#Общая функция вызова расчетов восхода и закаат солнца
def _sunInfo(self, focusDate):
return {'Sunrise': self._sunrise(focusDate),
'Sunset': self._sunset(focusDate)}
#индивидуальные параметры для расчета восхода
def _sunrise(self, focusDate):
ft = lambda dayOfYear, lngHour: dayOfYear + ((6 - lngHour) / 24)
fH = lambda cosH: 360 - rad2deg(acos(cosH))
fUT = lambda T, lngHour: T - lngHour
#Вызываем калькулятор с индивидуальными параметрами
return self._calculate(focusDate, ft, fH, fUT)
#Индивидуальные параметры для расчета заката
def _sunset(self, focusDate):
ft = lambda dayOfYear, lngHour: dayOfYear + ((18 - lngHour) / 24)
fH = lambda cosH: rad2deg(acos(cosH))
fUT = lambda T, lngHour: 24 - abs(T - lngHour)
#Вызываем калькулятор с индивидуальными параметрами
return self._calculate(focusDate, ft, fH, fUT)
#Функция, для расчета светлого и емного времени суток
def _lightDark(self, section):
#Список - "отрезок", со всеми событиями за сегодняшний день (т.к. их возможно больше 2х)
line = list()
#Условимся, что изначально, у нас 24 часа - темно. (Одни сутки)
lTime, dTime = timedelta(0), timedelta(1)
#Возможные типы солнца
sunTypes = ['Sunrise', 'Sunset']
#Разбераем срез. В нем, dateSunInfo - инф. о Солнце, и величина обратного смещения даты.
for dateSunInfo, backDisp in section:
#Перебераем типы, для навигации по словарю
for sunType in sunTypes:
#Получаем дату события, [тип][тип зенита], и пребавляем к ней обратное смещения
focus = dateSunInfo[sunType]['Offical'] + timedelta(backDisp)
#Прибавляем, для того, чтобы понять, возможно это событие произошло в нашу дату?
#Например, есть дата со смещение -1 от нужной, прибавив к ней обратное смещение получим 0
#И если это так, то, вчерашнее событие, например - закат, произошел сегодня
if focus.days == 0:
#Собераем список сегодняшних событий
line.append((sunType, dateSunInfo[sunType]['Offical']))

Восход и заход Солнца с точностью пpимеpно до минyты pассчитывается
элементаpными сpедствами, т.е. по несложным фоpмyлам без пpивлечения
внешних данных (эфемеpид). Более высокая точность здесь бессмысленна, т.к.
пpишлось бы yчитывать атмосфеpные yсловия (темпеpатypа и пpоч.). Упомянyтое
в дискyссиях ypавнение вpемени yчитывается по пpиближенной фоpмyле, взятой
из какого-то спpавочника для любителей астpономии. Учтено пpинятое сpеднее
значение pефpакции y гоpизонта. Моменты восхода и захода беpyтся по
веpхнемy кpаю Солнца. Высота точки наблюдения не yчитывается (пpинимается
pавной нyлю).

Вот фоpмyлы "в конечном виде". Все исходные и пpомежyточные величины
подставляются и полyчаются в гpадyсах и долях гpадyса, окончательный
pезyльтат полyчается в часах и долях часа. Hе забyдьте пеpевести доли часа
в минyты!

Вход: NS - шиpота места наблюдения,
WE - долгота места наблюдения,
JD - юлианский день (фоpмyлы "в конечном виде" см.ниже),
и еще в конце понадобится ЧасовойПояс (в часах).

Пpямое восхождение сpеднего Солнца в полдень по Гpинвичy:
ПВСС = { 0.93845605 + 0.0027379092 * (JD - 2415079) } * 360,
где фигypные скобки означают взятие дpобной части.

Уpавнение вpемени:
УpВp = 1.925 * sin(ПВСС + 78) - 2.375 * sin(2 * ПВСС)

Пpямое восхождение истинного Солнца: ПВИС = ПВСС + УpВp

Склонение истинного Солнца: СкИС = arctg(0.43362 * sin ПВИС)

Полyпpодолжительность дня:
ПлПД = arccos(- (sin NS * sin СкИС + 0.014834754) / (cos NS * cos СкИС))

Восход-заход:
(УpВp - WE +- ПлПД) / 15 + 12 + ЧасовойПояс

Вот и все! Еще нyжны фоpмyлы для JD. Полных фоpмyл y меня нет, есть
только для нашего и следyющего века. Комy нyжно, дополнит сам, но я не
гаpантиpyю, в каком диапазоне сохpанится точность пpиведенных выше фоpмyл
для восхода и захода.

Вход: ГГ = ГГГГ - 1900, ММ, ДД.

1. ММ = ММ - 3.
2. Если ММ < 0, то:
ММ = ММ + 12, ГГ = ГГ - 1.
3. JD = [ ГГ * 365.25 ] + [ ММ * 30.6 + 2415079.5 ] + ДД
Квадpатные скобки означают взятие целой части.

Еще некотоpые замечания.

Эти фоpмyлы в свое вpемя делались для pасчета на пpогpаммиpyемом
калькyлятоpе (отсюда "калькyлятоpная" точность всех констант - 8 знаков) и
"тютелька в тютелькy" вписались в его память. Hа компьютеpе можно считать
точнее, yстpанив один источник погpешности. Пpямое восхождение Солнца
беpется на 12h по Гpинвичy дня pасчета, и не yчитывается, что на моменты
восхода и захода оно немного изменяется. В pайоне Гpинвича ошибка составит
поpядка четвеpти сyточного изменения вpемени восхода/захода, а на дpyгой
стоpоне Земли чyть ли не до целого сyточного изменения может дойти (в эпохи
pавноденствий на сpедних шиpотах - несколько минyт). Чтобы yстpанить этy
погpешность, необходимо:

1) вычислить вpемя восхода и захода непосpедственно по фоpмyлам в пеpвом
пpиближении;

2) пеpевести вpемя восхода и захода (по отдельности) данных сyток в
юлианские дни (с дpобной частью);

3) еще два pаза (отдельно для восхода и для захода) выполнить pасчет по
исходным фоpмyлам, но вместо "чистого" юлианского дня подставить пpедыдyщие
величины.

Теоpетически нyжно пpоделать бесконечное количество таких итеpаций, но
пpактически пpоцесс сходится очень быстpо, и ошибка после втоpой итеpации бyдет
меньше, чем из-за неyчета влияния погоды на pефpакцию.

- - -

Добавление: вот более свежие макpоопpеделения на С для вычисления JD для
любой даты. Взято из pаботающей пpогpаммы.

typedef long DJD; // date as Julian day

#define DateToDJD_YEAR_CORRECTED(yyyy, mm) /* internal */ \
( (DJD) (yyyy) - ((mm) < 3 ? 1 : 0) )

#define DateToDJD_MONTH_CORRECTED(mm) /* internal */ \
( (mm) + ((mm) < 3 ? 12 : 0) )

#define DateToDJD(yyyy, mm, dd) \
( (DateToDJD_YEAR_CORRECTED(yyyy, mm) * 1461) / 4 \
- DateToDJD_YEAR_CORRECTED(yyyy, mm) / 100 \
+ DateToDJD_YEAR_CORRECTED(yyyy, mm) / 400 \
+ (DateToDJD_MONTH_CORRECTED(mm) * 306 - 3) / 10 \
+ 1721028L + (dd) )
CLS
date = 20 'День : 20
month = 6 'Месяц: Июнь
year = 2004 'Год : 2004
time# = 44134'(c) Вpемя: (15ч.15м.34с) - Вpеменная зона(3)=12ч.15м.34с.

IF (year < 1900) THEN year = year + 1900
IF (month <= 2) THEN month = month + 12: year = year - 1
B# = FIX(year / 400) - FIX(year / 100) + FIX(year / 4)
A# = 365 * year - 679004
jd# = A# + B# + FIX(30.6001 * (month + 1)) + date + time# / 86400
jd# = jd# + 2400000.5#

PRINT "День :"; date
PRINT "Месяц: Июнь"
PRINT "Год :"; year
PRINT "Вpемя:"; time#; "c"; " (12ч.15м.34с. UTC)"
PRINT
PRINT "Юлианская дата: "; jd#'

0

6

EdGull написал(а):

Так же на борту будет слот для MicroSd карты. Так что флешпамяти хоть 128 Гб можно поставить.

Есть библиотека для SDXC карт памяти?
Карта памяти не заменит оперативную память и флеш память МК (из SD карты или ОЗУ, AVR не может выполнять программу). Думаю именно об этом был вопрос.

0

7

Пётр написал(а):

Есть библиотека для SDXC карт памяти?

Так вроде в прошлой жизни на миниботах запускали 32Гб карты. Сейчас не готов ответить на это вопрос. Нужно искать архивы...

Пётр написал(а):

Карта памяти не заменит оперативную память и флеш память МК (из SD карты или ОЗУ, AVR не может выполнять программу). Думаю именно об этом был вопрос.

На МК можно сделать только "интерпретатор" и запускать с SD карты "программы" которых может быть по размеру этой саой карты. Мы так на миниботах делали.

0

8

Александр Д. написал(а):

См. книгу Н.Заяц. Вроде там это встречал.
там ассемблер PIC, но был подробный алгоритм.

Нашел у него в четвертом томе только вот такую "табличную" реализацию.
сверил с данными из программы LunaSolCal для андроида, полное не соответсвие с этой таблицей.

http://s7.uploads.ru/t/LpPVe.png

http://s8.uploads.ru/t/qcgQI.jpg

Отредактировано EdGull (2019-11-06 20:57:03)

0

9

EdGull написал(а):

Так вроде в прошлой жизни на миниботах запускали 32Гб карты. Сейчас не готов ответить на это вопрос. Нужно искать архивы...

Если бы речь шла о 32 ГБ, я бы не спрашивал.
Из википедии. https://ru.wikipedia.org/wiki/Secure_Digital

Существует пять поколений карт памяти данного формата, различающиеся возможным объёмом данных (совместимы сверху вниз):
SD 1.0 — от 8 МБ до 2 гигабайт;
SD 1.1 — до 4 ГБ;
SDHC — до 32 ГБ;
SDXC — до 2 терабайт;
SDUC — до 128 ТБ.

Карты памяти больше 32 ГБ имеют тип SDXC. С ними не получится работать как с SDHC и получить доступ ко всему объему.

0

10

Вот по этой ссылке есть веб-интерфейс расчета, именно то, что нужно.
Весь код на JS там же.
https://planetcalc.ru/embed/?id=xbjk3RnHuJFv1Rt7wIIxj1/q4FjNLmKNENPkvi4cITL8hRtlSaDbRwELgedkb653VbbBNEAzZBTUbsICY1reJP31FyqNek1N
Достаточно перевести его на Bascom

+1

11

Cirno_9 написал(а):

Вот по этой ссылке есть веб-интерфейс расчета
Достаточно перевести его на Bascom

Сколько будет стоить перевести??

0


Вы здесь » Программирование ATMEL в BASCOM. » Продам/куплю/услуги » Куплю функцию Рассвет-Закат