ARDUINO для автоматизации аквариума

<< 6789101112 1415 >>

Свой на Aqa.ru




693 77
Выкса
8 мес. назад
ARDUINO для автоматизации аквариума
Создал отдельную тему по вопросам использования простых и не дорогих плат ARDUINO для целей автоматизации аквариума.
Идея такая - довести это устройство до полнофункционального контроллера для аквариума, в итоге - с WEB сервером для управления по сети в т.ч. Интернет, и GSM модулем с отправкой SMS.
Начало обсуждения в теме про дозатор :
http://www.aqa.ru/fo...

Информация будет, в основном, в виде конкретных примеров.

Пример 1. Использоание плат Arduino UNO и Arduino NANO для управления по времени суток устройствами в 2-х каналах посредством релейного модуля.
Предполагается использование для создания 2-х канального дозатора, но и для включения света, например подойдет, и для многих других целей также.

Используется модуль часов реального времени, для точного планирования по времени суток, и релейный модуль. В данном примере используется 4-канальный, но 2 канала не используются...

Схема коммутации в случае использования платы UNO R3:


Схема коммутации в случае использования платы NANO:


Программа для среды программирования Arduino:
//***************************************************
// Скетч для управления релейным модулем, в котором *
// использовано два канала. Используется также RTC *
// Релейный модуль - с инверсной логикой на входе *
// Автор: ZORS *
// Версия 1. Дата 21.12.2013 02:40 *
//***************************************************
//----------ИМПОРТ БИБЛИОТЕК-------------------------
#include <Wire.h> //Подключаем библиотеку для использования I2C интерфейса с модулем RTC
#include <RTClib.h> //Подключаем библиотеку для использования модуля часов реального времени 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 < (StartRelCn_1+DurationCh_1)))
//Если секунд с начала суток больше, чем задано для включения
//Но, одновременно и меньше, чем задано для включения + длительность
{
digitalWrite(RelayChn1,LOW); //Устанавливаем на ПЕРВОМ входе релейного модуля НИЗКИЙ уровень - реле срабатывает
}
else //во всех остальных случаях
{
digitalWrite(RelayChn1,HIGH); //Устанавливаем на ПЕРВОМ входе релейного модуля ВЫСОКИЙ уровень - реле выключается
}

//------------КАНАЛ 2 - все аналогично -----------
if ((utime >= StartRelCn_2) &&
(utime < (StartRelCn_2+DurationCh_2)))
{
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 Files\Arduino\libraries
Сюда и помещайте папки с подключаемыми библиотеками. Если на этот момент, среда программирования была запущена - ее необходимо закрыть, и запустить заново. После этого библиотека будет доступна в меню Скетч/Импортировать библиотеку.

Микросхема 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
2013-12-21 добавлено 21/12/2013 15:57:48#1907148

Новичок




18 1
Борисоглебск
2 дн. назад
День добрый подскажите подойдут ли мои БП НИПТ-125300/350 и НИПТ-64350 для совместного использования с LDD-350H?
2016-02-29 добавлено 29/02/2016 23:23:34#2193653


Модератор
Модератор



1864 359
Москва
3 час. назад
Sk13dust

А совместное это как?
2016-02-29 добавлено 29/02/2016 23:29:11#2193655

Новичок




18 1
Борисоглебск
2 дн. назад
B_wolf
Могу ли я вставить ЛДД между моими БП и самим светильником и чтобы это все работало? ну соответственно ардуино будет присутствовать)

Изменено 29.2.16 автор Sk13dust
2016-02-29 добавлено 29/02/2016 23:31:48#2193657

Свой на Aqa.ru




3481 679
Санкт-Петербург
2
2 дн. назад
Sk13dust
Зачем их вообще использовать совместно-они вполне самодостаточные сетевые драйверы.
2016-02-29 добавлено 29/02/2016 23:32:25#2193658


Модератор
Модератор



1864 359
Москва
3 час. назад
Sk13dust

А зачем после одного драйвера ставить другой?
2016-02-29 добавлено 29/02/2016 23:32:39#2193659

Новичок




18 1
Борисоглебск
2 дн. назад
B_wolf
т.е. нужно будет покупать другой бок питание питающий ЛДД?
2016-02-29 добавлено 29/02/2016 23:34:42#2193660


Модератор
Модератор



1864 359
Москва
3 час. назад
Sk13dust

Угу
2016-02-29 добавлено 29/02/2016 23:35:29#2193663
Нравится Sk13dust

Новичок




1
Russian Federation
8 мес. назад
Z0RS
выложите пожалуйста скечт с дисплеем 1602
2016-03-06 добавлено 06/03/2016 12:24:01#2196369

Новичок




5 1
Russian Federation
5 мес. назад
сообщение Z0RS
Для программирования нескольких включений каждого реле в течение суток - естественно, потребуется несколько другой подход....спрашивайте когда кому-то потребуется


Изменено 24.12.13 автор Z0RS

Потребовалось, спрашиваю.
2016-03-23 добавлено 23/03/2016 16:01:36#2206056

Новичок




1
Russian Federation
8 мес. назад
Здравствуйте! Интересует такая задумка на базе платы ардуин. Сразу скажу в этом я полный профан в школе держал паяльник но руки вроде есть + есть мастера на работе которые сварганят если что)
Что имеется:
Основной свет
Компрессор
Светодиодная лента белый
Светодиодная лента синий
Термометр
Куллер
Обогреватель
Что хочу:
1. Утро- загорались светодиоды белые и синии например с 8 до 10 + компрессор с 6 до 13
2. С 10 до 13 включался основной свет в 13 - компрессор офф
3. С 13 до 17 работали светодиоды белые
4. С 17 до 21 работал основной свет + компрессор
5. С 21 до 22 работали светодиоды белые – компрессор
6. С 22 до 24 работали синии светодиоды
+ ко всему термометр измерял и включал при необходимости либо обогрев либо охлаждение

Хотелось бы узнать что нужно для этого купить Кроме платы Ардуин и читал, что там еще прописать что то надо?
2016-03-24 добавлено 24/03/2016 15:23:34#2206593

Новичок




5 1
Russian Federation
5 мес. назад
может кому пригодится, все работает.


#include <OneWire.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h> //Подключаем библиотеку для использования модуля часов реального времени RTC

RTC_DS1307 RTC;
LiquidCrystal_I2C lcd(0x27,16,2);
OneWire ds(10); // Порт подключения температурного датчика.

int i;
byte data[2];
byte addr[8];
float celsius;
byte resolution = 0x1F; // Разрешение датчика температуры. 0x7F - 12 бит (0.0625 C), 0x5F - 11 бит (0.125 C), 0x3F - 10 бит (0.25 C), 0x1F - 9 бит (0.5 C)
unsigned long utime;

//Порты подключения реле.
const int RelCh1 = 6;
const int RelCh2 = 7;
const int RelCh3 = 8;
const int RelCh4 = 9;

//Временные промежутки в секундах от начала суток для первого реле. (Настроены два временных диапазона. Если диапазон не требуется то в значениях указать 0).
const unsigned long RelCh1Start1 = 72600; //Начало первого промежутка.
const unsigned long RelCh1Duration1 = 14; //Длительность первого промежутка.
const unsigned long RelCh1Start2 = 0; //Начало второго промежутка.
const unsigned long RelCh1Duration2 = 0; //Длительность второго промежутка.

//Временные промежутки в секундах от начала суток для второго реле. (Настроены два временных диапазона. Если диапазон не требуется то в значениях указать 0).
const unsigned long RelCh2Start1 = 3600;
const unsigned long RelCh2Duration1 = 61200;
const unsigned long RelCh2Start2 = 72000;
const unsigned long RelCh2Duration2 = 10800;

//Временные промежутки в секундах от начала суток для третьего реле. (Настроены два временных диапазона. Если диапазон не требуется то в значениях указать 0).
const unsigned long RelCh3Start1 = 32400;
const unsigned long RelCh3Duration1 = 18000;
const unsigned long RelCh3Start2 = 57600;
const unsigned long RelCh3Duration2 = 18000;

//Диапазон температур срабатывания третьего реле.
const int TempLow = 28; //Нижняя граница.
const int TempHigh = 30;//Верхняя граница.

//Процедура проверки и включения реле по времени.
int relay (int ch, unsigned long start1, unsigned long duration1, unsigned long start2, unsigned long duration2){
if (((utime >= start1) && (utime < (start1+duration1))) || ((utime >= start2) && (utime < (start2+duration2))))
{digitalWrite(ch,LOW);}
else
{digitalWrite(ch,HIGH);}
}

void setup(void) {
pinMode(RelCh1,OUTPUT); //Инициализируем порт для ПЕРВОГО канала как ВЫХОД
pinMode(RelCh2,OUTPUT); //Инициализируем порт для ВТОРОГО канала как ВЫХОД
pinMode(RelCh3,OUTPUT);
pinMode(RelCh4,OUTPUT);
digitalWrite(RelCh1,HIGH); //Устанавливаем на входах релейного модуля ВЫСОКИЙ уровень
digitalWrite(RelCh2,HIGH); //Т.к. используемый релейный модуль с опторазвязкой - управляется инверсной логикой
digitalWrite(RelCh3,LOW);
digitalWrite(RelCh4,HIGH);
Serial.begin(9600);

Wire.begin(); //Инициируем I2C интерфейс
RTC.begin();
//RTC.adjust(DateTime(F(__DATE__), F(__TIME__))); //Установка даты времени. закомментировать в рабочей программе.
lcd.init();
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("Temp");
lcd.setCursor(6,0);
lcd.print("Time");

ds.search(addr);
ds.reset();
ds.select(addr);
ds.write(0x4E);
ds.write(0);
ds.write(0);
ds.write(resolution);

}

void loop(void) {
DateTime myTime = RTC.now(); //Читаем данные времени из RTC при каждом выполнении цикла
utime = myTime.unixtime(); //сохраняем в переменную - время в формате UNIX
utime %= 86400;
relay (RelCh1,RelCh1Start1,RelCh1Duration1,RelCh1Start2,RelCh1Duration2);
relay (RelCh2,RelCh2Start1,RelCh2Duration1,RelCh2Start2,RelCh2Duration2);
relay (RelCh3,RelCh3Start1,RelCh3Duration1,RelCh3Start2,RelCh3Duration2);


ds.reset();
ds.select(addr);
ds.write(0x44);
delay(380);
ds.reset();
ds.select(addr);
ds.write(0xBE);

for ( i = 0; i < 2; i++)
{data[i] = ds.read();}

int16_t raw = (data[1] << 8) + data[0];
celsius = (float)raw / 16.0;
if (celsius >= TempLow & celsius < TempHigh){digitalWrite(RelCh4,HIGH);}
else{digitalWrite(RelCh4,LOW);}

lcd.setCursor(0,1); //координаты расположение показаний температуры на эране
lcd.print(celsius); //температура в сельсиях
lcd.setCursor(6,1); //координаты расположения времени на экране
lcd.print (myTime.hour(),DEC); //часы
lcd.print (":");
lcd.print (myTime.minute(),DEC); //минуты
lcd.print (":");
lcd.print (myTime.second(),DEC); //секунды

}

Изменено 23.5.16 автор кикстартер
2016-05-22 добавлено 22/05/2016 22:19:51#2233374
Нравится Sk13dust

Новичок




3
Russian Federation
6 мес. назад
Доброго времени суток. Хочется посмотреть код рассвет/закат, который выкладывал Z0RS на второй-третей странице темы. К сожалению ссылки уже не работают. Если есть возможность, увидеть этот код, может кто на почту вышлет? Заранее благодарю
2016-05-25 добавлено 25/05/2016 15:27:34#2234571

Новичок




5 1
Russian Federation
5 мес. назад
Здесь по ходу дебаты закончились, но в других источниках мне попадались похожие темы, ищите.
2016-05-25 добавлено 25/05/2016 20:19:58#2234703

Новичок




3
Russian Federation
6 мес. назад
кикстартер
Здесь по ходу дебаты закончились, но в других источниках мне попадались похожие темы, ищите.


Ищу))) только мусора много..... Если что найдете, может поделитесь ссылкой?)))
2016-05-26 добавлено 26/05/2016 11:55:07#2234967

Постоянный посетитель




279 60
Ижевск
14 час. назад
У меня вот так работает:
//Функция рассвета/заката
void SunRisingAndSet (){
static byte ledValue = 0;
if (minutes > startSunRise + fadeDuration && minutes < startSunSet + fadeDuration){
ledValue = 0;}
if (minutes > startSunSet + fadeDuration || minutes <= startSunRise){
ledValue = 5;} // Ночное освещение
if (minutes >= startSunRise && minutes <= startSunRise + fadeDuration){ // Восход
ledValue = map(minutes - startSunRise, 0, fadeDuration, 0, 255);
}
if (minutes >= startSunSet && minutes <= startSunSet + fadeDuration){ // Закат
ledValue = map(minutes - startSunSet, 0, fadeDuration, 255, 5);
}
analogWrite(pinLedLight, ledValue);
}
2016-05-26 добавлено 26/05/2016 14:57:59#2235052

Посетитель




151 23
Москва
3 дн. назад
Mr.Sim
if (minutes > startSunRise + fadeDuration && minutes < startSunSet + fadeDuration){
ledValue = 0;}
Это условие немного странное, либо я его не понимаю. Т. е. если восход закончился, а закат еще нет, то уровень освещения (ШИМ) установить в ноль - правильно?
2016-05-27 добавлено 27/05/2016 15:19:40#2235443

Постоянный посетитель




279 60
Ижевск
14 час. назад
Совершенно верно - после процедуры восхода включается основное освещение и до процедуры заката подсветка led не работает.
2016-05-29 добавлено 29/05/2016 21:37:06#2236295

Посетитель




151 23
Москва
3 дн. назад
Mr.Sim
Тогда понятно.
Все же кажется, что логичнее было написать так:
if (minutes > startSunRise + fadeDuration && minutes < startSunSet){
ledValue = 0;}
2016-05-30 добавлено 30/05/2016 12:10:51#2236433

Постоянный посетитель




279 60
Ижевск
14 час. назад
Если электричество скакнёт во время заката, а закат ещё не завершился? Поэтому и прибавил время заката. Ведь закат с восходом можно сделать не по 30 минут как у меня, а больше.
2016-05-31 добавлено 31/05/2016 13:27:15#2236862

Новичок




2
Бийск
5 мес. назад
Z0RS

Спасибо за тему такую интересную сделал все по вашей схеме, та что в ds18b20, только немного добавил кода, реализовал включение подсветки дисплея утром и отключение вечером, чтобы не светила ночью
2016-06-16 добавлено 16/06/2016 06:54:23#2242546

Завсегдатай




351 43
Омск
7 дн. назад
iwizard7
На перпел.ру и фермер.ру есть готовые решения
2016-06-26 добавлено 26/06/2016 06:52:45#2245570

Новичок




2
Бийск
5 мес. назад
lexx8691

Полистал форумы эти, но увы не нашел готовых решений
2016-07-01 добавлено 01/07/2016 10:39:42#2247176

Посетитель




64 4
Russian Federation Ulyanovsk
4 час. назад
Здравствуйте. Интересует возможно ли использовать андруино вместе с драйвером от Mean Well Lcm-60.
У драйвера правда DIM 0-10V как я понял.

Изменено 17.7.16 автор megaagressor
2016-07-17 добавлено 17/07/2016 21:13:27#2252009


Модератор
Модератор



1864 359
Москва
3 час. назад
megaagressor
У драйвера правда DIM 0-10V

Не очень понятно о каких вы 0-10V. Но в общем верно. Или управление уровнем напряжения 0-10 вольт, или 10-вольтовый ШИМ.
2016-07-17 добавлено 17/07/2016 22:28:25#2252023

Посетитель




64 4
Russian Federation Ulyanovsk
4 час. назад

Управление ШИМ???
2016-07-17 добавлено 17/07/2016 22:36:26#2252026

<< 6789101112 1415 >> Создать новую темуБыстрый ответ