Здравствуйте!
Требуется управление уличным освещением. Установка фото-реле невозможна, суточне реле времени неудобны из-за частой подстройки особенно весной и осенью. Появилась идея сделать календарное реле. Данные времени и даты буду брать с модуля часов реального времени.
Вопрос в том, что я придумал это сделать на операторе if. Но такой способ не совсем удобен, т.к. получается в идеале для 365 дней нужно расписать время включения и выключения освещения по восходу и закату солнца.
Бывает ли какой более простой способ сравнения даты для установки времени включения и выключения?
Вот мой пример на операторе if, здесь подстройка по времени происходит каждые 10 дней, т.е. 3 раза в месяц, но хочется каждый день и как-то попроще.
//Январь
if (mo == 1 && dd >= 1 && dd < 11) // mo - месяц, dd - день
{rel1off = 9*60+15
rel1on = 16*60+6
}
if (mo == 1 && dd >= 11 && dd < 21)
{rel1off = 9*60+9
rel1on = 16*60+21
}
if (mo == 1 && dd >= 21 && dd <= 31)
{rel1off = 8*60+56
rel1on = 16*60+40
}
//Февраль
if (mo == 2 && dd >= 1 && dd < 11)
{rel1off = 8*60+37
rel1on = 17*60+4
}
if (mo == 2 && dd >= 11 && dd < 21)
{rel1off = 8*60+16
rel1on = 17*60+27
}
if (mo == 2 && dd >= 21 && dd <= 31)
{rel1off = 7*60+53
rel1on = 17*60+49
}
//Март
if (mo == 3 && dd >= 1 && dd < 11)
{rel1off = 7*60+30
rel1on = 18*60+10
}
if (mo == 3 && dd >= 11 && dd < 21)
{rel1off = 7*60+3
rel1on = 18*60+31
}
if (mo == 3 && dd >= 21 && dd <= 31)
{rel1off = 6*60+36
rel1on = 18*60+53
}
//Апрель
if (mo == 4 && dd >= 1 && dd < 11)
{rel1off = 6*60+6
rel1on = 19*60+16
}
if (mo == 4 && dd >= 11 && dd < 21)
{rel1off = 5*60+39
rel1on = 19*60+37
}
if (mo == 4 && dd >= 21 && dd <= 31)
{rel1off = 5*60+13
rel1on = 19*60+58
}
//Май
if (mo == 5 && dd >= 1 && dd < 11)
{rel1off = 4*60+49
rel1on = 20*60+19
}
if (mo == 5 && dd >= 11 && dd < 21)
{rel1off = 4*60+27
rel1on = 20*60+40
}
if (mo == 5 && dd >= 21 && dd <= 31)
{rel1off = 4*60+80
rel1on = 21*60+0
}
//Июнь
if (mo == 6 && dd >= 1 && dd < 11)
{rel1off = 3*60+53
rel1on = 21*60+18
}
if (mo == 6 && dd >= 11 && dd < 21)
{rel1off = 3*60+45
rel1on = 21*60+29
}
if (mo == 6 && dd >= 21 && dd <= 31)
{rel1off = 3*60+48
rel1on = 21*60+33
}
//Июль
if (mo == 7 && dd >= 1 && dd < 11)
{rel1off = 3*60+59
rel1on = 21*60+26
}
if (mo == 7 && dd >= 11 && dd < 21)
{rel1off = 4*60+16
rel1on = 21*60+10
}
if (mo == 7 && dd >= 21 && dd <= 31)
{rel1off = 4*60+35
rel1on = 20*60+52
}
//Август
if (mo == 8 && dd >= 1 && dd < 11)
{rel1off = 4*60+55
rel1on = 20*60+30
}
if (mo == 8 && dd >= 11 && dd < 21)
{rel1off = 5*60+16
rel1on = 20*60+6
}
if (mo == 8 && dd >= 21 && dd <= 31)
{rel1off = 5*60+38
rel1on = 19*60+37
}
//Сентябрь
if (mo == 9 && dd >= 1 && dd < 11)
{rel1off = 5*60+59
rel1on = 19*60+10
}
if (mo == 9 && dd >= 11 && dd < 21)
{rel1off = 6*60+19
rel1on = 18*60+43
}
if (mo == 9 && dd >= 21 && dd <= 31)
{rel1off = 6*60+39
rel1on = 18*60+15
}
//Октябрь
if (mo == 10 && dd >= 1 && dd < 11)
{rel1on = 7*60+0
rel1off = 17*60+48
}
if (mo == 10 && dd >= 11 && dd < 21)
{rel1on = 7*60+21
rel1off = 17*60+23
}
if (mo == 10 && dd >= 21 && dd <= 31)
{rel1on = 7*60+45
rel1off = 16*60+56
}
//Ноябрь
if (mo == 11 && dd >= 1 && dd < 11)
{rel1off = 8*60+08
rel1on = 16*60+35
}
if (mo == 11 && dd >= 11 && dd < 21)
{rel1off = 8*60+29
rel1on = 16*60+17
}
if (
}
//Декабрь
if (mo == 12 && dd >= 1 && dd < 11)
{rel1off = 9*60+3
rel1on = 15*60+57
}
if (mo == 12 && dd >= 11 && dd < 21)
{rel1off = 9*60+13
rel1on = 15*60+56
}
if (mo == 12 && dd >= 21 && dd <= 31)
{rel1off = 9*60+15
rel1on = 15*60+57
}
timenow = hh*60 + mm
if (timenow > rel1off && timenow < rel1on)
{rel1 = 0
}
elese
{rel1 =1
}
Берем календарь, смотрим восход - закат на каждый день для своей местности. Прописываем зависимость, вводим поправку от количества прошедших дней от 22 декабря в +, с 22 июня в -.
Эта поправка нелинейная, бывает за 10 дней на 5 минут разница, или за 3 дн на полчаса в зависимости от времени года.
Господи, а что прям такая точность нужна?
Ну заведите массив из 366 элементов, забейте туда время восхода и берите готовое время из массива по дню года в качестве индекса (только не спрашивайте, где взять день года, когда есть дата, а то я не люблю материться).
А что, ручками вбивать 366 значений времени не лень? Если лень, то сделайте ещё проще, добавьте к ардуине какой-никакой вай-фай и тупо спрашивайте время восхода для текущей даты у какого-нибудь астрономического сайта.
Отлично! Время восхода и захода солнца у меня для каждого дня есть.
Вопрос в том, как уйти от оператора if, как работать в моем случае с массивами (я не работал с ними).
Вопрос в том, как уйти от оператора if, как работать в моем случае с массивами (я не работал с ними).
А чего с ним работать?
ну, допустим. что мы считаем 1-ое января нулевым днём года, второе - первsм и т.п.
Пишем массив
int sunRise [] = {
xxx, //время для 1 января
yyy, //время для 2 января
...
zzz //время для 31 декабря
};
Ну а теперь, когда нам нжуно время восхода для n-го дня года, просто пишем
int srTime = sunRise[n];
Если я получил дату 22.12 с часов реального времени, то как к ней обратиться в массив, как точно посчитать какой она будет в массиве?
Забейте поправку в епром с интервалом 1 минута (тот же массив, только память не жрет) и берите требуемые ячейки в зависимости от количества дней прошедших с 22 декабря. Вангую, что потребуется только на 187 дней, только знак менять.
Если я получил дату 22.12 с часов реального времени, то как к ней обратиться в массив, как точно посчитать какой она будет в массиве?
Так, ну я же говорил, в массиве она будет находиться по индексу, равному номеру дня в году.
для 01.01 - sunRise[0]
для 02.01 - sunRise[1]
..
для 31.12 - sunRise[365] // для вискокосного года или 364 для невисокосного.
Забиваете массив для текущего года и не паритесь.
Через год забиваете новый массив для нового года (если там что-то меняется, я не знаю).
Это я понял. Но с модуля часов я получу dd=22, mm=12,
а в массиве конкретно например 322 день, как стыковать массив с месяцем и днем из часов?
Забейте поправку в епром с интервалом 1 минута (тот же массив, только память не жрет) и берите требуемые ячейки в зависимости от количества дней прошедших с 22 декабря. Вангую, что потребуется только на 187 дней, только знак менять.
спасибо, пока сложно, попробую разобраться с массивом впринципе
Это я понял. Но с модуля часов я получу dd=22, mm=12,
а в массиве конкретно например 322 день, как стыковать массив с месяцем и днем из часов?
Т.е. у Вас есть номер дня в месяце и номер года, а Вы не можете посчитать номер дня в году?
Ну, я же просил Вас не спрашивать у меня этого! Ну. чо Вы не можете посчитать из месяца и дня, день года? ну, напрягитесь уж как-нибудь, посчитайте.
Получается их надо перемножать как-то, в каждом месяце разное число дней и февраль меняется
Т.е. у Вас есть номер дня в месяце и номер года, а Вы не можете посчитать номер дня в году?
Ну, я же просил Вас не спрашивать у меня этого! Ну. чо Вы не можете посчитать из месяца и дня, день года? ну, напрягитесь уж как-нибудь, посчитайте.
Евгений, просьба отклонена!!! У меня с математикой, так себе. Я бы просто просуммировал по месяцам. Как тоже самое, но проще?
Когда-то я даже формулу рожал, сейчас найду - не проще. но прикольнее, тупо формула и всё, только год надо знать, чтобы учесть високосность. Ща. поищу. где-то валялось.
Почтенная публика в курсе, что время восхода и заката для одной и той же даты каждый год разные?
я посмотрел по астрономическим сайтам разница в 1-2 минуты за 50 лет
я посмотрел по астрономическим сайтам разница в 1-2 минуты за 50 лет
Подскажите, если я сделаю 365-366 дней на операторе if ардуино не зависнет, или по часу думать будет?
Подскажите, если я сделаю 365-366 дней на операторе if ардуино не зависнет, или по часу думать будет?
С ума сошли? Да и памяти то хватит?
Дальше ведь смешнее. Астрономические данные верны для равнины, в лесу, горах, городах это будут другие значения. Освещение ведь предназначенно для комфорта населения, а не солнышко приветствовать.))))
Либо я не в курсе, но думаю, А5021 имел в виду наш високосный цикл. Допускаю, что в корне не прав.
Нашёл формулу!
Это маленький задачник с пояснениями, котрый я писал для своих студентов почти 20 лет назад (в 1997, я тогда преподавал в двух универах сразу :))))
В общем, всё, что нужно знать о календаре и о том, как его программировать, содержится в первой главе. Там и формулы и пояснения и куски программ.
Нашёл формулу!
Это маленький задачник с пояснениями, котрый я писал для своих студентов почти 20 лет назад (в 1997, я тогда преподавал в двух универах сразу :))))
В общем, всё, что нужно знать о календаре и о том, как его программировать, содержится в первой главе. Там и формулы и пояснения и куски программ.
Пасибки, весьма познавательно. Но, на мой взгляд, проще ссуммировать месяца и учесть високосный (для данной задачи).))))
Ну, енто ж скучно :)
Ну, енто ж скучно :)
Не отрицаю, для того, у кого мозг в правильном направлении заточен.))) У меня вот только алгоритмика получается (разложить задачу на минимальные составляющие).
Бляха муха, а подоткнуть к ардуине на вход ацп фотодатчик...или не айс?
Евгений, надеюсь ТС не обидится за оффтоп, с младости (проффесиональной) мучал вопрос, есть ли способ замены метода последовательного приближения (простых иттераций) при расчетах в металлургии, например:
Дано - общая масса 12000кг,
хрома содержится 8,5%, требуется 12,5%
Содержание Cr в феррохроме 70%. (это простой пример, сложный содержит 6-8 элементов)
Расчет идет исключительно на логарифмической линейке ( калькулятор на большом кол-ве элементов пустой номер), плюсовую поправку даю сам интуитивно.
Когда добрался до EC-ки просто крутил цикл 1000 раз.
Есть ли более простые варианты? С точки зрения математика?
Что-то мне кажется, что время рассвета и заката на протяжении года меняется по синусоиде.
Период - можно считать известен.
Фаза - тоже известна.
Амплитуда - зависит от географической широты.
Нет, можно конечно, воспользоваться и табличной функцией, но мне кажется, раз в сутки посчитать тригонометрию Ардуину особенно не напряжет. Ну а для любителей таблиц - можно эту таблицу не вбивать ручками, а насчитать программно - по синусоиде.
andriano, пп. 1, 2.
Использование аналогового датчика таит опасность, что в жаркие и холодные дни он будет выдавать разные показания при одинаковой освещенности, а калибровать его на сей счет замахаешься.
Использование аналогового датчика таит опасность, что в жаркие и холодные дни он будет выдавать разные показания при одинаковой освещенности, а калибровать его на сей счет замахаешься.
Ну не знаю, делал аналоговое реле, 8 лет проработало...потом я уволился )))
Ничего кроме единожды не калибровалось
andriano, пп. 1, 2.
И на что мы здесь ссылаемся? На Конституцию РФ?
andriano, пп. 1, 2.
И на что мы здесь ссылаемся? На Конституцию РФ?
На функцию, возможно она и синусоида.
Большое спасибо всем, интересная ветка получилась, буду делать. Еще нашел формулы для астрономического расчета по координатам местности.
Ничего кроме единожды не калибровалось
Вполне допускаю, что так и было дело. Только сегодня, когда цифровые датчики освещенности, выдающие показатели сразу в люксах и гарантирующие заявленную точность измерений во всем индустриальном диапазоне, торгуются на али дешевле доллара, какой смысл прикручивать фоторезисторы ко входам АЦП?
я бы так считал: дней в году 361
в месяце - дней 30
ну и получается N=30*mm+dd-30
ну и массив с временем восхода/ заката в eeprom
как то так...
будет конечно погрешность, но вам же не самолеты сажать...
Отлчино, по Вашей формуле получается погрешность максимум в 1-2 дня на протяжении всего года.
Потянет ли ардуино нано 2 массива по 366 чисел (восход и закат) и несколько строк работы с часами и сравнения времени?
Евгений, надеюсь ТС не обидится за оффтоп, с младости (проффесиональной) мучал вопрос, есть ли способ замены метода последовательного приближения (простых иттераций) при расчетах в металлургии, например:
Дано - общая масса 12000кг,
хрома содержится 8,5%, требуется 12,5%
Содержание Cr в феррохроме 70%. (это простой пример, сложный содержит 6-8 элементов)
Расчет идет исключительно на логарифмической линейке ( калькулятор на большом кол-ве элементов пустой номер), плюсовую поправку даю сам интуитивно.
Когда добрался до EC-ки просто крутил цикл 1000 раз.
Есть ли более простые варианты? С точки зрения математика?
Простите, а что нужно сделать? Определить сколько добавить феррохрома, чтобы получить 12,5% хроме в результате?
Да, убрав все промежуточные приближения. Молодежь висла минут на 10-15 (допустимо 3-4), с опытом делаешь за 3-5 пересчетов. И чуял, что есть какая то зависимость, но сформулировать не смог.((((
Эт дела давние, так что если неинтересно, забейте.
Евгений, надеюсь ТС не обидится за оффтоп, с младости (проффесиональной) мучал вопрос, есть ли способ замены метода последовательного приближения (простых иттераций) при расчетах в металлургии, например:
Дано - общая масса 12000кг,
хрома содержится 8,5%, требуется 12,5%
Содержание Cr в феррохроме 70%. (это простой пример, сложный содержит 6-8 элементов)
Расчет идет исключительно на логарифмической линейке ( калькулятор на большом кол-ве элементов пустой номер), плюсовую поправку даю сам интуитивно.
Когда добрался до EC-ки просто крутил цикл 1000 раз.
Есть ли более простые варианты? С точки зрения математика?
Простите, а что нужно сделать? Определить сколько добавить феррохрома, чтобы получить 12,5% хроме в результате?
задача класса курса химии за 8 класс однако, решать надо в молях
Евгений, надеюсь ТС не обидится за оффтоп, с младости (проффесиональной) мучал вопрос, есть ли способ замены метода последовательного приближения (простых иттераций) при расчетах в металлургии, например:
Дано - общая масса 12000кг,
хрома содержится 8,5%, требуется 12,5%
Содержание Cr в феррохроме 70%. (это простой пример, сложный содержит 6-8 элементов)
Расчет идет исключительно на логарифмической линейке ( калькулятор на большом кол-ве элементов пустой номер), плюсовую поправку даю сам интуитивно.
Когда добрался до EC-ки просто крутил цикл 1000 раз.
Есть ли более простые варианты? С точки зрения математика?
Простите, а что нужно сделать? Определить сколько добавить феррохрома, чтобы получить 12,5% хроме в результате?
задача класса курса химии за 8 класс однако, решать надо в молях
Увы, решать надо в килограммах и тоннах. Для молей весов не придумали.
массив нужно записать в еепром (атмега328 - 1024 байта) тоже нехитрыми формулами можно прописать восход с 4 до 9 утра и закат с 17 до 23 часов. т.е. получается на закат 6 часов, придется обойтись точность около двух минут (плюс погрешность от моей формулы, той что выше) т.е. прибавка в одно значение переменной в массиве увеличивает время заката на две минуты.
Вот примерный код, прошу проверить:
---------------------------------------------------
А что здесь проверять, в EEPROM уже не лезет, почти везде 2-х байтовое значение: 365*2*2 = 1460 байт. Притом, что на вскидку у Вас действительно синусоида. Попробуйте график построить, может получится просто формулой синуса обойтись. И начинайте все таки от солнцестояния.
А если ее в таком виде залить, будет работать?
Я еще только жду ардуино и раньше не видел ее, поэтому задаю такие вопросы.
Оно и не поместится в EEPROM. В моём проекте астротаймера эта информация находится во флеше, как и в других подобных, объявляется как const byte data[12][31] PROGMEM={{/*jan*/},{/*feb*/},.....};, выводится из флеша назад в ОЗУ командой byte time=pgm_read_byte(&(data[hour-1][min-1]));, инклуд (библиотека с pgm_read_byte()) называется avr/pgmspace.h
Если охота ещё упростить, надо уже думать в ту сторону, в которую думают создатели архиваторов. Видно что в первом массиве часы часто повторяются, от 17 до 21 и обратно. Если назад преобразовать массив в одномерный (без координат месяц/день), то легко будет забить другой массив, в котором будут тупо индексы, с которых меняется час. Итого надо знать цифру 17, единицу, 32 (второе февраля, когда из 17 впервые станет 18) и ещё 7 подобных цифр и 7, итого получаем в идеале 12 байт информации против 372 исходных, ну реально ещё некоторый байт-код скомпилированного wiring с нужными действиями, получающими из этих 12 байт остальные 360.
В массиве минут этот номер не проходит т. к. цифры заметно меняются, однако видно, что меняются незначительно. Точно так же, считаем разницу между ними, и вот уже таблица разниц поддаётся такому же сжатию как часы. Там их будет просто больше, среди них будут отрицательные, но опять же, всю таблицу реально запихать в те же десятки байт, т. к. 2/-2, 1/-1 будет повторяться часто но бывют редкие 3/-3, 5/-5, но они настолько редки что записывать их в общую очередь нет никакого смысла, потеряем больше постоянно возвращаясь на 2/-2, 1/-1. Просто запоминаем их абсолютные координаты и запишем уже на втором проходе, когда вся таблица будет ещё состоять из 1/-1, 2/-2. После, затолкав туда все разницы, берем исходное число (в моем случае так же 17), получаем из таблицы разниц нормальную таблицу с минутами и можно подставлять в условие.
Более короткие данные в EEPROM/флеше не значат однако, более простой код. Смотрите как вам будет меньше работы, в моём случае астротаймер норм живёт с таблицей во флеше, её можно обновлять (да-да, на другой год таблица уже будет отличаться, незначительно но отличаться), и флеша не жалко, плюс находясь там, таблица не жрёт ОЗУ - вместе с ней спокойно уживаются меню с экраном, кнопки которые можно нажимать кратко, длинно и прям ваще длинно, работа с EEPROM типа будильника и всяких настроек и т. п.
А если ее в таком виде залить, будет работать?
1. Взял эмулятор (хоть тот же proteus)
2. Залил
3. Посмотрел
4. Рассказал нам
поэтому задаю такие вопросы.
Вы задаёте такие вопросы потому, что Вы ленивы и инфантильны. Вам лень попробовать самому и Вы считаете, что все вокруг обязаны делать Вашу работу за Вас.
Не знал, что есть эмулятор, спасибо за наводку. Вопросы задаю, потому что есть срочность, а ардуино похоже придет только через месяц. Просто у кого есть опыт ответили ли бы сразу, что ардуино потянет эту программу или нет. Все, что нужно мне в этом приборе я написал, никаких кнопок, меню, расчетов, экранов ненужно. Подойдет время заменить батарейку - заменю, перезалью программу и дальше на год-два. Таких приборов будет работать несколько, будут резервные, чтобы один выбросить если что, поставить сразу другой исправный. Вопрос на три минуты.
массив нужно записать в еепром
Вы всерьез думаете, что параметры земеной орбиты за время жизни прибора изменятся настолько существенно, что придется неоднократно их перепрограммировать?
d_kin, вы для себя это колхозите? Если для организации, то лучше купить готовый промышленный астротаймер. В них используют GPS модуль, можно один раз запрограммировать и больше никогда не знать забот. Ну а если самому собирать "велосипед", то опять же удобнее на GPS.
...ардуино потянет эту программу или нет. Все, что нужно мне в этом приборе я написал...
Что-то я не нашел, где Вы пишете о требуемой точности установки времени восхода/захода. А без этого ответить на вопрос "потянет или не потянет" невозможно, не говоря уже о конкретном алгоритме.