Постоянный посетитель
|
ARDUINO для автоматизации аквариума (страница 11) |
Создал отдельную тему по вопросам использования простых и не дорогих плат ARDUINO для целей автоматизации аквариума. Схема коммутации в случае использования платы NANO: Программа для среды программирования Arduino: //*************************************************** // Скетч для управления релейным модулем, в котором * // использовано два канала. Используется также RTC * // Релейный модуль - с инверсной логикой на входе * // Автор: ZORS * // Версия 1. Дата 21.12.2013 02:40 * //*************************************************** //----------ИМПОРТ БИБЛИОТЕК------------------------- #include //Подключаем библиотеку для использования I2C интерфейса с модулем RTC #include //Подключаем библиотеку для использования модуля часов реального времени RTC RTC_DS1307 RTC; //Создаем переменную класса - для использования RTC //----------Объявляем разные переменные------------ const int RelayChn1 = 6; //Используем цифровой ПОРТ 6 для ПЕРВОГО канала релейного модуля const int RelayChn2 = 7; //Используем цифровой ПОРТ 7 для ВТОРОГО канала релейного модуля //----------Настройки времени и продолжительности включения реле //----------ПЕРВЫЙ канал---------------------------- const long StartRelCn_1 = 25200; //Время срабатывания в ПЕРВОМ канале релейного модуля (в секундах от начала суток) //в данном случае 25200 - это 7 часов 00 минут = ( 60секунд *60 минут *7 = 25200) const long DurationCh_1 = 10; //ДЛИТЕЛЬНОСТЬ срабатывания реле в ПЕРВОМ канале (в секундах) //----------ВТОРОЙ канал---------------------------- const long StartRelCn_2 = 37800; //Время срабатывания во ВТОРОМ канале релейного модуля (в секундах от начала суток) //В данном случае 10 часов 30 минут = (60 секунд * 60 минут * 10 часов + 60сек*30мин = 37800) const long DurationCh_2 = 15; //ДЛИТЕЛЬНОСТЬ срабатывания реле во ВТОРОМ канале (в секундах) //----------Модуль инициализации setup() - выполняется один раз при инициализации платы при подаче напряжение (и аналогичных событиях) void setup(){ pinMode(RelayChn1,OUTPUT); //Инициализируем порт для ПЕРВОГО канала как ВЫХОД pinMode(RelayChn2,OUTPUT); //Инициализируем порт для ВТОРОГО канала как ВЫХОД digitalWrite(RelayChn1,HIGH); //Устанавливаем на входах релейного модуля ВЫСОКИЙ уровень digitalWrite(RelayChn2,HIGH); //Т.к. используемый релейный модуль с опторазвязкой - управляется инверсной логикой Wire.begin(); //Инициируем I2C интерфейс RTC.begin(); //Инициирум RTC модуль // RTC.adjust(DateTime(__DATE__, __TIME__)); //С этой строки необходимо убрать комментарии один раз в начале, //для того, чтобы загрузить в RTC дату и время на момент компиляции программы //Иногда необходимо заливать СКЕТЧ на плату со снятым комментарием - для поправки //времени в RTC, НО оставлять такой СКЕТЧ в работе НЕЛЬЗЯ !!!!!!!!!!!!! } // КОНЕЦ ИНИЦИАЛИЗАЦИИ //-------------------------------------------------- void loop() // ПРОГРАММЫй безусловный ЦИКЛ { DateTime myTime = RTC.now(); //Читаем данные времени из RTC при каждом выполнении цикла //----------Раздел обработки реле по времени ---- long utime = myTime.unixtime(); //сохраняем в переменную - время в формате UNIX utime %= 86400; //Сохраняем в этой же переменной остаток деления на кол-во секнд в сутках, //Это дает количество секунд с начала текущих суток //------------КАНАЛ 1------------------------------ if ((utime >= StartRelCn_1) && (utime //Если секунд с начала суток больше, чем задано для включения //Но, одновременно и меньше, чем задано для включения + длительность { digitalWrite(RelayChn1,LOW); //Устанавливаем на ПЕРВОМ входе релейного модуля НИЗКИЙ уровень - реле срабатывает } else //во всех остальных случаях { digitalWrite(RelayChn1,HIGH); //Устанавливаем на ПЕРВОМ входе релейного модуля ВЫСОКИЙ уровень - реле выключается } //------------КАНАЛ 2 - все аналогично ----------- if ((utime >= StartRelCn_2) && (utime { digitalWrite(RelayChn2,LOW); //Устанавливаем на ВТОРОМ входе релейного модуля НИЗКИЙ уровень - реле срабатывает } else { digitalWrite(RelayChn2,HIGH); //Устанавливаем на ВТОРОМ входе релейного модуля ВЫСОКИЙ уровень - реле выключается } }//------------Конец ЦИКЛА----------------------------- (Редактор текста на данном сайте - к сожалению, "ломает" красивое форматирование. PS: Выложил этот скетч на файлообменник : http://my-files.ru/h... В данной программе реализован, довольно-таки простой подход, а простота - основа надежности. Каждое из 2-х реле срабатывают один раз в сутки в указанное время, причем время указывается в количестве секунд от начала суток, и удерживается указанное количество времени в секундах. Такой способ задания времени - несколько сложен для понимания, но за это - не нагружает программу и процессор лишним функционалом, который понадобится всего один раз. Для определения времени наступления события начала включения и выключения реле - используется время в формате UNIX. Такой подход хорош тем, что даже если включение или перезагрузка платы произойдет в промежутке времени включения, то реле включится в оставшееся время. В случае с дозированием, это не много что дает, но в случае, если по аналогии будет сделано управление светом, то при подаче напряжения на плату, например, после пропадания напряжения питания, или после посадки напряжения, или др. аналогичных событий, включение и выключение реле произойдет корректно. У комплектных минутных и секундных таймеров "с розеткой" - об этом можно только мечтать....не реализован такой функционал, и еще у них есть один минус. Реле в таких таймерах - не удерживаемое, а переключаемое, со всеми вытекающими последствиями.... Для программирования нескольких включений каждого реле в течение суток - естественно, потребуется несколько другой подход....спрашивайте когда кому-то потребуется, пока не хочу все усложнять... В принципе, можно добавить константных переменных, содержащих время и длительность срабатывания, и соответственно добавить проверку на условия. Если количество необходимых срабатываний каждого реле в сутках больше чем 2 - лучше оформить проверку условий в отдельной функции. Как, говорил человек, учивший меня программированию - "все, что ты делаешь в программе больше двух раз - оформляй отдельной процедурой, или функцией". Главное ограничение этого подхода - включение и выключение реле - должно произойти в одних сутках. Если необходимо чтобы, реле включилось в одних сутках, а выключилось в других - необходимо разбить это задание на 2 задания, или применить другой метод проверки условий наступления событий включения и выключения. Весь этот пример тестировался на "живом" железе : Для наглядности отладки был еще подключен LCD дисплей 16 сим в 2 строках. Схема итоговая была такая: Обратите внимание, что при использовании I2C последовательного интерфейса - соединения значительно упрощаются. И LCD дисплей подключен транзитом через модуль RTC (часов реального времени). Никаких паяных соединений нет вообще....все скоммутировано - проводами с разъемами. Скетч - естественно, несколько другой использовался с добавлением строк инициализации и использования LCD 16x2. Плата использовалась типа такой: http://www.ebay.com/... цена примерно 350 руб. Релейный модуль http://www.ebay.com/... цена примерно 150 руб. Модуль часов реального времени: http://www.ebay.com/... Цена примерно 55 руб. Для сокращения бюджета можно использовать плату проще: http://www.ebay.com/... Цена примерно 200 руб. Если есть потребность подключить ЖК дисплейчик, то лучше брать ЖК дисплей (LCD) c I2C интерфейсом - это сильно упрощает коммутацию, и сокращает количество использованных портов на микроконтроллере. Например такой можно использовать : http://www.ebay.com/... цена около 180 руб. На ЖК можно выводить статусную информацию, информацию об ошибках, диагностическую информацию. Все это, конечно, можно и в последовательный порт компьютера выводить, но это не всегда удобно (скорее наоборот), поэтому я всегда использую какой-нибудь девайс для вывода информации. Для использования I2C интерфейса - необходима библиотека Wire. Она есть в стандартном дистрибутиве среды программирования Arduino. Для использования модуля RTC на микросхеме DS1307 нужна библиотека RTClib. Если ее не будет в стандартном дистрибутиве, то ее можно взять в интернет. Например здесь : http://arduino-info.... Необходимо, скачать, и разархивировать zip-файл в папку с понятным названием, например RTCLib. Затем эту папку поместить в папку, где среда Arduino хранит свои библиотеки. Если ставили среду программирования с настройками по умолчанию, то этой папкой будет : C:Program FilesArduinolibraries Сюда и помещайте папки с подключаемыми библиотеками. Если на этот момент, среда программирования была запущена - ее необходимо закрыть, и запустить заново. После этого библиотека будет доступна в меню Скетч/Импортировать библиотеку. Микросхема RTC модуля DS1307, как правило использует адрес на шине I2C равный 0x68 поэтому, необходимо проверить в библиотечных файлах, библиотеки RTClib наличие строки типа этой: #define DS1307_ADDRESS 0x68 Если будет использоваться LCD 16x2 с I2C интерфейсом, то - понадобиться библиотека LiquidCrystal_I2C. Можно скачать здесь : http://dvrobot.ru/lc... Как подключить к среде программирования Arduino - см. выше ВАЖНО : при использовании I2C устройств - в скетче, библиотека Wire - должна быть объявлена первой, иначе - будут ошибки компиляции. По этому примеру - все.... в следующем - присоединение термо-датчика DS18B20, и создание несложного терморегулятора..... Изменено 24.12.13 автор Z0RS |
|
#1907148 |
Новичок
1
10 года |
Программирование нескольких включений каждого реле в течение суток (страница 11) |
Z0RS Уважаемый ZORS, если вас не затруднит, помогите пожалуйста с кодом для включения реле несколько раз в сутки.(до 20 раз на 5-10 минут) Хочу использовать вашу схему для авто полива гидропоники. Заранее Спасибо. |
|
#2044255 |
|
Малёк
17
Санкт-Петербург 1 года |
|
senatorowARDUINO для автоматизации аквариума в этом посте автор все очень подробно разжевал на примере своего секундного таймера. все очень просто struct Task TaskList[] PROGMEM = { {RelPin1, 600,60,20, LOW}, {RelPin2, 600,120,20, LOW}, {RelPin3, 600,180,20, LOW}, {RelPin4, 600,270,20, LOW}, вот отрывок из его скетча где я изменил время срабатывания каждые десять минут мои помпы срабатывают на 20 секунд. |
|
#2051701 |
Посетитель
|
|
Заинтересовала идея бюджетного ледконтроллера на базе Arduino Nano, в связи с этим вопрос. |
|
#2068399 |
Посетитель
|
|
скептик а зачем переменные резисторы? PWM можно управлять с Arduino nano по программе, в ней 2 контакта под это точно есть |
|
#2068411 |
Посетитель
|
|
Если переменники планировались в качестве "аналогового" регулятора уставки (вместо кнопок и памяти), то нет проблем подключить к аналоговому входу ардуины. |
|
#2068416 |
|
Посетитель
|
|
Переменные резисторы для задания параметров. |
|
#2068461 |
Новичок
4
10 года |
|
//Инициирум RTC модуль |
|
#2101575 |
Завсегдатай, Кандидат в Советники
|
|
сообщение Alex112 Именно так и будет выглядеть. Просто убираете знак комментария перед строкой - и все. В самих скобках ничего не меняем. После инициализации часиков нужно ОБЯЗАТЕЛЬНО вернуть на место знак комментария и загрузить этот же скетч еще раз. Иначе при каждом выключении/включении питания ардуины часы будут возвращаться к тому времени, когда вы их загрузили. |
|
#2101602 |
|
Новичок
4
10 года |
|
Дядька-рыбомор Пробывал убирал коментарий и ставил заново. не пойму что не так? //*************************************************** // Скетч для управления релейным модулем, в котором * // использовано два канала. Используется также RTC * // Релейный модуль - с инверсной логикой на входе * // Автор: ZORS * // Версия 1. Дата 21.12.2013 02:40 * //*************************************************** //----------ИМПОРТ БИБЛИОТЕК------------------------- #include //Подключаем библиотеку для использования I2C интерфейса с модулем RTC #include //Подключаем библиотеку для использования модуля часов реального времени RTC RTC_DS1307 RTC; //Создаем переменную класса - для использования RTC //----------Объявляем разные переменные------------ const int RelayChn1 = 6; //Используем цифровой ПОРТ 6 для ПЕРВОГО канала релейного модуля const int RelayChn2 = 7; //Используем цифровой ПОРТ 7 для ВТОРОГО канала релейного модуля //----------Настройки времени и продолжительности включения реле //----------ПЕРВЫЙ канал---------------------------- const int StartRelCn_1 = 25200; //Время срабатывания в ПЕРВОМ канале релейного модуля (в секундах от начала суток) //в данном случае 25200 - это 7 часов 00 минут = ( 60секунд *60 минут *7 = 25200) const int DurationCh_1 = 28800; //ДЛИТЕЛЬНОСТЬ срабатывания реле в ПЕРВОМ канале (в секундах) //----------ВТОРОЙ канал---------------------------- const int StartRelCn_2 = 32400; //Время срабатывания во ВТОРОМ канале релейного модуля (в секундах от начала суток) //В данном случае 10 часов 30 минут = (60 секунд * 60 минут * 10 часов + 60сек*30мин = 37800) const int DurationCh_2 = 37800; //ДЛИТЕЛЬНОСТЬ срабатывания реле во ВТОРОМ канале (в секундах) //----------Модуль инициализации setup() - выполняется один раз при инициализации платы при подаче напряжение (и аналогичных событиях) void setup(){ pinMode(RelayChn1,OUTPUT); //Инициализируем порт для ПЕРВОГО канала как ВЫХОД pinMode(RelayChn2,OUTPUT); //Инициализируем порт для ВТОРОГО канала как ВЫХОД digitalWrite(RelayChn1,HIGH); //Устанавливаем на входах релейного модуля ВЫСОКИЙ уровень digitalWrite(RelayChn2,HIGH); //Т.к. используемый релейный модуль с опторазвязкой - управляется инверсной логикой Wire.begin(); //Инициируем I2C интерфейс RTC.begin(); //Инициирум RTC модуль // RTC.adjust(DateTime(__DATE__, __TIME__)); //С этой строки необходимо убрать комментарии один раз в начале, //для того, чтобы загрузить в RTC дату и время на момент компиляции программы //Иногда необходимо заливать СКЕТЧ на плату со снятым комментарием - для поправки //времени в RTC, НО оставлять такой СКЕТЧ в работе НЕЛЬЗЯ !!!!!!!!!!!!! } // КОНЕЦ ИНИЦИАЛИЗАЦИИ //-------------------------------------------------- void loop() // ПРОГРАММЫй безусловный ЦИКЛ { DateTime myTime = RTC.now(); //Читаем данные времени из RTC при каждом выполнении цикла //----------Раздел обработки реле по времени ---- long utime = myTime.unixtime(); //сохраняем в переменную - время в формате UNIX utime %= 86400; //Сохраняем в этой же переменной остаток деления на кол-во секнд в сутках, //Это дает количество секунд с начала текущих суток //------------КАНАЛ 1------------------------------ if ((utime >= StartRelCn_1) && (utime //Если секунд с начала суток больше, чем задано для включения //Но, одновременно и меньше, чем задано для включения + длительность { digitalWrite(RelayChn1,LOW); //Устанавливаем на ПЕРВОМ входе релейного модуля НИЗКИЙ уровень - реле срабатывает } else //во всех остальных случаях { digitalWrite(RelayChn1,HIGH); //Устанавливаем на ПЕРВОМ входе релейного модуля ВЫСОКИЙ уровень - реле выключается } //------------КАНАЛ 2 - все аналогично ----------- if ((utime >= StartRelCn_2) && (utime { digitalWrite(RelayChn2,LOW); //Устанавливаем на ВТОРОМ входе релейного модуля НИЗКИЙ уровень - реле срабатывает } else { digitalWrite(RelayChn2,HIGH); //Устанавливаем на ВТОРОМ входе релейного модуля ВЫСОКИЙ уровень - реле выключается } }//------------Конец ЦИКЛА----------------------------- |
|
#2101635 |
Завсегдатай, Кандидат в Советники
|
|
сообщение Alex112 А что именно не так? Опишите проблему, какой у вас ардуино, какие комплектующие контролера, и вам постараются помочь. А вы просто привели выдернутый из контекста кусок кода из одного из скетчей ZORSа. А еще лучше: можно обратиться на специализированные форумы ардуинистов, я так и делал несколько раз, и мне давали очень дельные советы. Здесь все-таки аквариумисты, а не программисты обитают |
|
#2101763 |
Посетитель
|
|
подскажите а что такое БИТ и как число влияет на регулировку яркости? |
|
#2103047 |
|
Завсегдатай, Кандидат в Советники
|
|
zelda78 По-моему, вы сами не знаете, чего хотите. С одной стороны, вам нужны лишь закаты/рассветы и терморегуляция. С другой - вы проводите в пример какие-то запредельно навороченные чужие разработки и тут же говорите - там слишком много лишнего. Так определитесь - делаете сами или покупаете готовое. Если делаете сами - ну так за вас никто собирать конструкцию и писать код не будет. Вы должны сами понять свой нужный функционал, поставить перед собой конкретную цель. Если долько диммирование - то данная тема все разжевала и в рот положила. Боюсь показаться нескромным, но Простой Arduino-контроллер "чайника" - от макета до готового изделия я выложил все этапы постройки - заметьте - работоспособного девайса. Но у каждого есть свои маленькие пожелания, а поэтому код и конструкция могут отличаться. К примеру, у меня три канала диммирования, а вам нужно два. Значит, разбрайтесь в коде и пишите его под два. Или, к примеру, вы хотите часы ds3231. Да, их можно поставить, даже библиотеку менять не надо. Но тогда из кода нужно выбросить кусок коррекции времени, т.к. эти часы довольно точные и не нуждаются в программном исправлении хода. Но сделать это нужно САМОМУ. Поймите, пока не начнете сами ковыряться в коде - ничего не поймете и не сможете настраивать контроллер "под себя любимого". Это довольно просто, я уже вам писал в личку, что ни разу не программист, а вообще гуманитарий. Бит - это единица информации, равная одному разряду в двоичном коде. |
|
#2103176 Нравится lexx8691
|
Завсегдатай, Кандидат в Советники
|
|
сообщение zelda78 Это очень спорное утверждение. Ну, например, СО2 растения получают все же через листья. А поэтому утверждать - ВСЕ ЧЕРЕЗ КОРНИ - неверно. А потом мы имеем дело с водными растениями, которые в процессе эволюции приспособлены к листовому питанию. Конечно, крипты или эхи значительную массу веществ берут из грунта. Но вы попробуйте накормить через корни наяс или амбулию. Зачахнут, я вас уверяю. А у мхов корней вообще нет, только ризоиды для прикрепления к субстрату. Так то. Но это к данной теме не относится, модераторы - не губите за флуд |
|
#2103177 |
Посетитель
|
|
я привел чужую разработку, по той причине что среди всех контроллеров котоые сейчас идут на форумах у этого мне больше всех понравился внешний вид, ведь внешний вид или так сказать симпатия тоже не мало важно.... |
|
#2103185 |
|
Посетитель
|
|
читал так и не понял как и с чего происходит управление настройками (кнопки или что иное предусмотрено) может кто то просветить. |
|
#2104262 |
Завсегдатай, Кандидат в Советники
|
|
zelda78 Управление только программно, т.е. в приведенных данных примерах те параметры (время, температура, скорость и др.) которое вы установите в скетче, то и будет испольнять контроллер. Мне сначала показалось неудобным (нельзя менять время вкл/выкл света, только путем изменения проги и ее загрузки), а потом понял, что этого вполне хватает, т.к. менял установки ну от силы пару раз за год. Есть, конечно, и решения с кнопочным управлением установок, их довольно много, но нужно поискать. Я остановился на более простом. |
|
#2104401 |
Постоянный посетитель
|
|
#2104631 |
|
Посетитель
|
|
Bloody Адаптер для i2c в таком экране как у автора служит лишь исключительно для экономии ножек МК (2 вместо 6, да и те общие для нескольких модулей). Если ножек хватает - то можно подключать напрямую, параллельным интерфейсом. Ищите схему LCD Shield. Еще потребуется постоянный резистор для ограничения тока светодиода подсветки (если таковой уже на экране не припаян) и подстроечный для настройки контрасности. |
|
#2104658 |
Завсегдатай, Кандидат в Советники
|
|
Bloody Необязательно. Вот тут схема подключения без I2C, но в таком случае требуется больше проводов. I2C позволяет обойтись всегт четыремя: "+" и "-" 5В и еще два: SDA и SCL. |
|
#2104737 |
Постоянный посетитель
|
|
Дядька-рыбомор всем большое спасибо . Уже подключил дисплей , сначала не получалось , думаю из за хренового контакта , поэтому я злился и бесился на китайцев . Сегодня взял паяльник и жестко припаял штырьки к лсд . Теперь всё работает , сейчас приделаю батарейку и релюшки . Ручки чешутся ))))) если все получился , это же сколько можно будет выкинуть таймеов 220 , контроллеры с куллерами.... |
|
#2104915 |
|
Завсегдатай, Кандидат в Советники
|
|
сообщение Bloody Абсолютно верное решение. У меня на аквариуме с контроллером раньше стояло 4 таймера: свет утро/вечер, основной свет, СО2 и кулер для охлаждения воды. Теперь все в одной коробочке контроллера с блоком из 4-х реле. |
|
#2105004 |
Постоянный посетитель
|
|
Прошу помощи . =) |
|
#2105664 |
Посетитель
|
|
if (tempc > 26 ){ |
|
#2105667 Нравится Bloody
|
|
Посетитель
|
|
Если честно, на "пропеллер", я бы ставил немного по другому, что бы его не колбасило на пограничной температуре и лишний раз не входить в условия , для перезаписи команды, это в теории, на практике надо тестировать, какие значение приходят от датчика температуры.. Если он перепрыгиваться данные значения.. то немного поменять код.. |
|
#2105704 |
Постоянный посетитель
|
|
Filter Можно проще, если помнить, что конструкции кода для проверки логических условий сами дают в итоге значения типа TRUE или FALSE, что одно и тоже что HIGH и LOW. Будет всего одна строка в коде. Ее необходимо вставить в тело основного цикла: digitalWrite(RelayChn3,!(tempc > 26 )) // это если реле включается инверсным сигналом т.е. уровнем LOW иначе убрать восклицательный знак. Кстати, при применении данной конструкции и скомпиленный код будет лучше, т.е. компактнее и эффективнее. Если нужен гистерезис, т.е. "зазор" между температурой включения то, это - тоже можно вставить в проверку условия. Наверное, сами догадаетесь как? И еще в данном коде есть ошибка...Нельзя сравнивать значния типа float со значением типа int. А компилятор именно так и поймет в большинстве случаев. Лучше использовать 26.0 или использовать для сравнения переменную соответствующего типа. Изменено 6.7.15 автор Z0RS |
|
#2105707 |