Постоянный посетитель
|
ARDUINO для автоматизации аквариума (страница 15) |
Создал отдельную тему по вопросам использования простых и не дорогих плат 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 |
Посетитель
|
|
bonlik 1. Вы цифры то подставляете? 2. У вас скетч компилируется и прошивается без ошибок? 3. Выложите скетч который вы заливаете, тогда можно будет глянуть что не так. Я помню это был один из первых сделанных мной контроллеров, понравилась простота программы и именно она мне помогла с ардуино разобраться. |
|
#2300395 |
|
Малёк
11
Липецк 8 года |
|
здравствуйте. цифры я подставляю. компилируется и заливается посмотрите подскажите |
|
#2300439 |
Малёк
11
Липецк 8 года |
|
Да ещё модуль часов ds3231 . |
|
#2300446 |
Новичок
3
8 года |
Доброго времени суток всем. (страница 15) |
Большое спасибо автору за подробное описание своих проектов. Я собрал себе контроллер по 2 примеру с небольшими изменениями, все работает отлично. Теперь задумал подключить сервопривод для управления кормушкой, не могу добиться срабатывания в определенное время поворота на 180* и возврата обратно в 0. Помогите со скетчем пожалуйста. |
|
#2305397 |
Новичок
1
8 года |
Интересует скетч (страница 15) |
Добрый день, а можно у вас попросить этот скетч, а то по ссылке его уже удалили. |
|
#2309763 |
|
Новичок
3
8 года |
|
#2311499 |
Новичок
3
8 года |
|
Kornetus "Спасибо большое" всем кто "откликнулся". Дотумкал сам. Если кому надо: #include //используем библиотеку для работы с сервоприводом Servo servo; //объявляем переменную servo типа Servo int angle1 = 0; //устанавливаем положение вала сервопривода const long Startservo = .......; //Время срабатывания сервопривода const long Durationservo = ......; //ДЛИТЕЛЬНОСТЬ срабатывания сервопривода void setup servo.attach(3); //привязываем сервопривод к порту 3 void loop if ((utime >= Startservo) && (utime { servo.write(180); //ставим вал сервопривода под угол 180* } else { servo.write(0); //ставим вал сервопривода под угол 0* } |
|
#2311513 |
Новичок
|
|
Господа умельци, выкидывайте это барахло DS1307 и ставьте ds3231. Не пожалеете. |
|
#2329076 |
|
Новичок
9
8 года |
|
Приветствую. Я совсем не программер, но коряво и нудно написать скетч для рассвета-заката на основе этого поста мне удалось. Только одно но: в данном посте скетч под модуль 1307, а у меня на руках только модуль времени 1302. Никак не могу заставить скетч работать с ним в формате unixtime. Может кто подсказать начальные параметры? |
|
#2330245 |
Посетитель
|
|
Roywalk 1. 1302 - это не I2С, потому нафиг не нужны #include и Wire.begin(); //Инициируем I2C интерфейс 2. Что у вас такое time.h я не знаю, но видимо тоже не нужно 3. Проблема я так понимаю здесь long utime = myTime.unixtime(); ? Ну нет в DS1302.h преобразования даты в число секунд удобное для сравнений, но в чем проблема выдрать нужный код из либы для 1307? Код перед loop: #include #define SECONDS_FROM_1970_TO_2000 946684800 const uint8_t daysInMonth [] PROGMEM = { 31,28,31,30,31,30,31,31,30,31,30,31 }; // number of days since 2000/01/01, valid for 2001..2099 static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) { if (y >= 2000) y -= 2000; uint16_t days = d; for (uint8_t i = 1; i days += pgm_read_byte(daysInMonth + i - 1); if (m > 2 && y % 4 == 0) ++days; return days + 365 * y + (y + 3) / 4 - 1; } static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) { return ((days * 24L + h) * 60 + m) * 60 + s; } uint32_t unixtime(uint16_t y, uint8_t m, uint8_t d, uint8_t h, uint8_t m, uint8_t s) { uint32_t t; uint16_t days = date2days(y, m, d); t = time2long(days, h, m, s); t += SECONDS_FROM_1970_TO_2000; // seconds from 1970 to 2000 return t; } Код в loop: long utime = unixtime(t.yr, t.mon, t.date, t.hr, t.min, t.sec); Изменено 23.1.17 автор dkozyrev |
|
#2330343 |
Новичок
9
8 года |
|
dkozyrev Спасибо за быстрый ответ и готовый код. Просто то, что для вас кажется простым, для меня, никогда не занимавшимся программированием, лес дремучий (причем даже литературу усердно читал - не доходит). В общем, убрал лишние библиотеки, скопировал Ваш код (в void setup и void loop соответственно, хотя первую часть пытался скопировать и до loop). Снова вылезают ошибки в скопированном коде. Хрен с ним. Дождусь модуля 1307 и попробую на нем (там хоть компиляция проходит). Если и там не заработает, то напишу назад простой код рассвета-заката через delay (громадный, но хоть понятный и работает) и оставлю так. Просто свет часто моргает и рассвет-закат заново начинаются. Часы только для этого и нужны по сути... |
|
#2330355 |
|
Посетитель
|
|
#2330357 |
Свой на Aqa.ru, Кандидат в Советники
|
|
#2330359 |
Новичок
9
8 года |
|
Стоп. Сейчас добью и скину ошибки. сюда же. |
|
#2330365 |
|
Посетитель
|
|
Roywalk In function 'void setup()': error: a function-definition is not allowed here Не надо внутрь функции setup пихать определение других функций, вставляйте в начало. А еще есть файлообменники, туда можно закинуть лог или программу, а на форуме дать ссылку. |
|
#2330376 |
Новичок
9
8 года |
|
dkozyrev Скинул на Гугл диск полностью весь скетч. Но за мое варварство в Loop шибко не пинайте, лень было голову напрягать с математикой ))) https://drive.google... |
|
#2330382 |
Посетитель
|
|
#2330407 |
|
Свой на Aqa.ru, Кандидат в Советники
|
|
Roywalk Или так https://drive.google... Используя функцию unixtime из RTClib П.с. про циклы обязательно почитайте |
|
#2330411 |
Новичок
9
8 года |
|
Спасибо! Пойду дальше ковырять. У меня что-то видимо еще с самим компилятором. Снова пишет ошибки о не существующих переменных. |
|
#2330418 |
Свой на Aqa.ru, Кандидат в Советники
|
|
#2330421 |
|
Новичок
9
8 года |
|
Библиотеки норм подгружает, я сверял пути. |
|
#2330426 |
Свой на Aqa.ru, Кандидат в Советники
|
|
DS1302 отсюда https://github.com/m... ? |
|
#2330431 |
Новичок
9
8 года |
|
Тьфу блин. Похоже, что нет))) В ютубе брал по ссылке библиотеку. Какая-то косячная видимо) С этой все нормально)) Огромнейшее спасибо. |
|
#2330438 |
|
Новичок
9
8 года |
|
dkozyrev Ваш скетч работает, но не полностью. Сначала нашел свою ошибку (диоды горели с одной яркостью), на выход подал логическое значение вместо аналогового, заменил на analogWrite и эта проблема исчезла. Далее прописал инициализацию порта в setup и вывод текущего формата времени в unix (показывает нормально, отчет идет верно, совпадает со временем в компьютере если перевести в привычное значение). Но при заливке полного скетча светодиоды быстро мигают и то только если ардуино подключено к порту, если отключить от порта и сбросить питание светильника, то ничего не горит (пока не подключишь в USB, хотя питание на ардуинку идет от отдельного блока на 5V). Пробовал писать в таком формате убрав рассвет и закат: if ((utime >= StartLed) && (utime { analogWrite(Led, 255); analogWrite(Led2, 255); } else { analogWrite(Led, 0); analogWrite(Led2, 0); } В итоге все горит, но опять до отключения ардуино от USB. Такое ощущение, что цикл не начинает свою работу. С чем это связано никак не пойму. Если вручную забивать значения через analogWrite (как в примерах Blink или Fade), то все нормально меняется. На всякий случай скинул последний вариант https://drive.google... |
|
#2330842 |
Посетитель
|
|
Roywalk По ссылке старая версия скетча. Если ведет себя по разному при питании от разных источников - проверяйте тестером на гнездах 5V/GND, может напряжение просаживается или где-то в КЗ. И почему не пользуетесь отладкой? Можно же накидать по всей программе Serial.println() для вывода значений переменных или просто меток, что зашло в такую-то ветку, подключить USB и смотреть в терминале чего там творится. А при автономном питании и без дисплеев можно подключить несколько светодиодов (на D13 уже есть встроенный) и зажигать их в нужных местах программы. По крайней мере узнаете, что код выполняется и в каком месте. |
|
#2330978 |