Постоянный посетитель
|
ARDUINO для автоматизации аквариума (страница 10) |
Создал отдельную тему по вопросам использования простых и не дорогих плат 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 |
Малёк
46
10 года |
|
[q]SilverSwift |
|
#1967965 |
|
Постоянный посетитель
|
|
kirex05 Так и должно быть.... Мне тоже было очень интересно посмотреть как "заработает" конструкция char str[7]; sprintf(str, "T=%0.2f", celsius); т.к. проблема заключается в том, что функции форматированного вывода не реализованы в базовой библиотеке, точнее сильно недореализованы. Советчик, ошибся, т.к. просто этого не знал...мне вышеуказанная конструкция тоже приходила в голову, когда я писал свои примеры..но она - не заработала... Есть другая конструкция, которая работает в одном из моих экспериментальных скетчах...(его в теме нет, это было продолжение работы с температурным датсчиком): float temp = getTemp(); char sBuffer[7]; char* strTemp = dtostrf(temp,1,2,sBuffer); где getTemp() - функция возвращающая температуру в переменной типа float, а функция преобразования в строковую переменную dtostrf() - реализована в базовой библиотеке и прекрасно работает. Но надо понимать, что Вам совершенно ясно, что strTemp - это строковая переменная и с ней нужно обращаться соответственно. Изменено 29.4.14 автор Z0RS |
|
#1968056 |
Посетитель
|
|
Написал так как вы сказали, но вместо температуры выводит только знак "?". Печаль, просто в Arduino IDE так заданы параметры сборки. В принципе, это можно обойти, если вместо Arduino IDE использовать Makefile, но это слишком муторно. Можно попробовать такую конструкцию: [q] char output[7]; char temperature[5]; dtostrf(celsius,5,2,temperature); sprintf(output, "T=%s", temperature); lcd.print(output); delay (10); [/q] Сейчас под рукой нет ни платки, ни компилятора, могут вылезти косяки, если что пишите - поправим. проблема заключается в том, что функции форматированного вывода не реализованы в базовой библиотеке, точнее сильно недореализованы В библиотеке avr-gcc все реализовано, просто сборка в среде Arduino сконфигурирована так, что этот функционал не поддерживается. Достаточно прилинковать нужную библиотеку ключиком -lprintf_flt и все заработает. Просто для этого нужно слезть с ардуинских средств разработки. Изменено 30.4.14 автор SilverSwift |
|
#1968150 |
Посетитель
|
|
Сейчас под рукой нет ни платки, ни компилятора, могут вылезти косяки, если что пишите - поправим. Косяков нет, все должно работать. Изменено 30.4.14 автор SilverSwift |
|
#1968251 |
Завсегдатай, Кандидат в Советники
|
|
Пришли долгожданные драйверы с e-bay, MW LDD 1000H. Подключил DIM-вход драйвера к PWM-выходу ардуины, запустил - и ничего. Покумекал и понял свою ошибку. Сама ардуина получает свои 5V через USB от телефонной зарядки, а драйвер свои 12V от AC/DC конвертера (временно, для опытов с одним диодом). Нужно было, видимо, соединить GND ардуины и "-" вход драйвера. Сделал - и все заработало! Даже несколько раз прогнал программу диммирования, быстрее и медленнее, наслаждался зрелищем. На всякий случай я измерил ток между GND и "-" драйвера - менее 0.1 мА. |
|
#1968338 |
|
Завсегдатай, Кандидат в Советники
|
|
сообщение Z0RS Кстати, хотел спросить. В даташите рекомендован резистор 4,7 ком. У вас написан 4,3 ком по ошибке или по своим соображениям? |
|
#1968358 |
Постоянный посетитель
|
|
Дядька-рыбомор А на самом деле, из-за отсутствия вышеуказанных номиналов - был использован 9,1 кОм. Иногда, подтягивающие резисторы в даташите указывают в широком диапазоне. Я уже не помню, откуда я взял 4.3 кОм - всего скорее из какого-нибудь описания OneWire. Кстати , я рад что у Вас получается разобраться со светом. Да, при соединении нескольких устройств, для обмена сигналами TTL уровня или сопоставимого. При наличии однополярных питающих напряжений, минусовые полюса питания они же земляные - необходимо соединять, иначе, понятно, не соберется цепь для протекания тока управления. Да и это же явно следует из схемы соединений, которую я приводил в теме. Дядька-рыбомор Это как раз ток электрода диммирования и есть. Изменено 30.4.14 автор Z0RS |
|
#1968365 |
Завсегдатай, Кандидат в Советники
|
|
сообщение Z0RS Ну тогда и мне лень выпаивать 4,3 ком |
|
#1968481 |
|
Завсегдатай, Кандидат в Советники
|
|
Всех с праздниками! Это пока временное подключение для тестов. Хорошо виден диммирующий электрод от ардуины (желтый) и шунт между GND ардуины (на монтажной плате) и "-" драйвера, без которого ШИМ не работает (красный проводок). Меню немного доработано: при повышении температуры вывше установленной и включении кулера загорается симфол "*", типа значок кулера. При выключенной СО2 горит "0", при включеннос соответственно "1". На ручном режиме управления СО2 - символ "Н" (Hand), на автомате - "А" (Auto). Реализовал работу двух кнопок. Одна - режимы СО2 (ручной и авто), вторая - сброс времени на 21:00 (ручная корреция RTC). Ручной режим СО2 мне необходим в ряде случаев, когда настраиваю аппарат Киппа. Выключение света решил организовать аппаратным способом - тумблером, выключающим питание драйверов. Так мне проще. Кнопки подключил к цифровым выводам 2 и 3. Сначала хотел к аналоговому входу (А0) через подобранные резисторы АЦП (2.3 ком, 4.7 ком) и подтягивающий резистор (10 ком). Но потом решил свой первый проект упростить. Скетч можно посмотреть тут. Учел некоторые замечания ZORS и SilverSwift по оптимизации кода, что-то оставил преждним. Теперь осталось собрать светильник, а контроллер запихнуть в коробочку. ЗЫ.Продолжение про мой контроллер Простой Arduino-контроллер "чайника" - от макета до готового изделия Изменено 1.5.14 автор Дядька-рыбомор Изменено 2.5.14 автор Дядька-рыбомор |
|
#1968504 |
Малёк
46
10 года |
|
[q]SilverSwift |
|
#1969253 |
Посетитель
|
|
через некоторое время пявляется 3-й знак, а потом и 4-й. Значит эти знаки не относятся к температуре, еще что-то выводится. Выложите файлик с текущей реализацией программы - посмотрю на досуге. Также участились ложные срабатывания реле в автоматическом режиме. Надо смотреть код. Либо с разной частотой обновляется температура на экране и для реле, либо не корректно описано управление обогревом. |
|
#1969268 |
|
Малёк
46
10 года |
|
сообщение SilverSwift Спасибо за помощь. Код кинул в личку. |
|
#1969289 |
Постоянный посетитель
|
|
kirex05 Вы очень долго можете "крутиться" в разбирательствах вокруг конвертации температуры и вывода на дисплей. Но лучше по-изучать шину OneWire и посмотреть какое значение возвращает шина при сбоях получения данных от датчиков. OneWire - шина очень "нежная" и сбои на ней - очень вероятны, особенно при использовании нескольких устройств на шине. Отсюда похоже возникают и сбои кода, обслуживающего реле. Точнее код отрабатывает правильно, но используемые значения - неверны. В принципе, в самих сбоях - ничего экстраординарного - нет. Необходимо программно "отлавливать" значения заведомо ложные, которые как раз и приходят с шины при сбоях чтения. Просто отфильтровать их программно и все. Сами сбои могут иметь кучу причин. Это и плохое качество датчиков, не верно подобранное соединение, неверно подобранное значение подтягивающего резистора, наводки от индуктивных источников и очень много чего другого. Изменено 5.5.14 автор Z0RS |
|
#1969295 |
Посетитель
|
|
Сегодня очень много времени потерял пока подключал свои строковые дисплейчики по I2C. |
|
#1969471 |
|
Малёк
46
10 года |
|
сообщение Z0RS Всё-таки проблема была с самим датчиком, он был не герметичен. Сделал сам другой датчик из антенной трубки и все проблемы исчезли. Сегодня уже 5-й день в работе, левые цифры не появляются и реле срабатывает как положено. Теперь прошу помощи по поводу света. Как сделать в ручном режиме включение и выключение света плавным для обоих каналов (LW и LR), чтобы яркость для каждого канала былы как в автоматичеком режиме. Вот кусок кода: case btnUP: { lcd.setCursor(9, 0); lcd.print("L"); for(int fadeValue = 0 ; fadeValue { analogWrite(PWM_LW_PIN, fadeValue); analogWrite(PWM_LR_PIN, PWM_LR_MAX); delay(250); } break; } case btnDOWN: { lcd.setCursor(9, 0); lcd.print("0"); for(int fadeValue = PWM_LW_MAX ; fadeValue >= 0; fadeValue -=1) { analogWrite(PWM_LR_PIN, 0); analogWrite(PWM_LW_PIN, fadeValue); delay(150); } break; } |
|
#1972153 |
Посетитель
|
|
arch07 Вот в этом и у меня была проблема) |
|
#1973003 |
Новичок
2
10 года |
ШИМ для управления светодиодной подсветкой аквариума(через RTC) (страница 10) |
Z0RS Привет, подскажи пжл, как можно организовать "умную" подсветку для аквариума? Имееется Pro Mini 328, куча светодиодов SMD 3528 спаянных в одну линию параллельно(около 50шт), транзистор, резистор, RTC модуль Tiny. Хотелки: работа света в режиме 00-00 - 07-00 уровень свечения value = 5 (ночник), далее рассвет 07-01 - 08-00 value = 50 08-01 - 09-00 value = 100 09-01 - 10-00 value = 150 10-01 - 11-00 value = 200 11-01 - 12-00 value = 250 12-01 - 13-00 value = 250 13-01 - 14-00 value = 250 14-01 - 15-00 value = 250 15-01 - 16-00 value = 250 16-01 - 17-00 value = 250 17-01 - 18-00 value = 250 18-01 - 19-00 value = 250 19-01 - 20-00 value = 200 20-01 - 21-00 value = 150 21-01 - 22-00 value = 100 22-01 - 23-00 value = 50 23-01 - 23-59 value = 50 Как это можно в код упаковать? Заранее спасибо! Изменено 19.6.14 автор ramon6 |
|
#1979529 |
|
Постоянный посетитель
|
|
ramon6 Посмотрите вторую страницу этой темы. Там пример и последующие дополнения, которые содержат информацию для решения Вашей задачи. Вслучае чего...ссылка на файл с кодом http://my-files.ru/8... Код примера подойдет практически без необходимости изменения. Необходимо установить следующие назначения констант и макросов: #define PWM_MIN 5 Это будет минимальным занчением ШИМ - как Вы говорите "ночник". Потом, если перефразировать Ваши требования - примерно с 8-00 до 12-00 вы хотите линейно поднять яркость LED с минимального значения до максимального. Затем с 19-00 до 23-00 будет закат - т.е. снижение значения ШИМ с максимального до минимального. В терминах кода примера это будет так: long sunrise_start = 8*hr; //Начало восхода в 8 - 00 long sunrise_duration = 4*hr; //Длительность восхода 4 часа long sunset_start = 19*hr; //начало заката в 19-00 long sunset_duration = 4*hr; //Длительность заката 4 часа Я так понимаю, что LED вы присоединяете через драйвер с ШИМ управлением? |
|
#1979854 |
Новичок
2
10 года |
|
Z0RS Спасибо за скетч, пока все сделано на коленке, не то что драйвера, даже транзистора управляемого ШИМ нет, все подключено напрямую. Сопли, но пока работает, планирую поставить транзистор, т.к. светодиодам нехватает тока(или напряжения), горят в 40-50% от номинала. |
|
#1980081 |
Постоянный посетитель
|
|
ramon6 Вообще, это плохо. Это говорит о том, что всего скорее, ток в цепочке светодиодов ограничивается током ввывода, который в свою очередь ограничем схемой микроконтроллера и схемой питающего преобразователя. Несмотря на то, что микроконтроллеры ATMEL с TTL уровнями 5V - очень и очень живучие и практически не убиваемые, всеже от длительного воздействия токов на выводах, превышающих номиналы - они выходят из строя. Кстати, своей неубиваемостью они мне и нравятся. Также не плохо противостоят эл.магнитным полям. |
|
#1980097 |
|
Посетитель
|
|
Добрый день. Наконец-то собрал схему из темы Простой Arduino-контроллер "чайника" - от макета до готового изделия скетч взял в конце темы. Но вот незадача, не работает шим. как можно проверить работает ли он вообще, придерживаясь схемы? |
|
#1984763 |
Малёк
46
10 года |
|
Люди добрые, снова прошу у вас помощи. |
|
#2013427 |
Посетитель
|
|
kirex05 Если код в порядке, то мне кажется варианта два: 1. Включение релюшки дает помеху по питанию и микрокотроллер перегружается, коротко дергая выводами. Реле инерционное и для него проходит незаметно, а мосфет успевает среагировать. Отследить программно перезагрузки, лечить конденсаторами на линии питания. 2. Провод на затвор слишком длинный или не подтянут к земле и ловит помеху из воздуха и транзистор шалит. Укоротить, поставить драйвер, или хотя бы резистивный делить для стекания наловленного. http://caxapa.ru/lib... Изменено 31.10.14 автор dkozyrev |
|
#2013468 |
|
Малёк
46
10 года |
|
сообщение dkozyrev Спасибо за быстрый отклик. 1. Т.е. поставить конденсаторы большей ёмкости? А как отследить программно перезагрузки? 2. Провода вроде не сильно длинные. Что значит не подтянут к земле? Какой драйвер? А что если вместо реле поставить оптрон типа МОС3062, решит ли это проблему? Изменено 31.10.14 автор kirex05 |
|
#2013563 |
Посетитель
|
|
что бы не мудрить, сделал так (ebay в помощь, привожу названия 1:1 с сайта) |
|
#2013711 |