Умная теплица на базе Arduino Mega

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

cofessor пишет:

Заказал не проанализировав ограничения платы чтобы не ждать пока разберусь полностью и не переплачивать. Но теперь, познакомившись поближе, вижу что народ позже сталкивается именно с нехваткой выводов, да ещё с переполнением памяти. Если бы заказывал сейчас, то заказал бы Мегу конечно, но для начала и Uno пойдёт. На уме есть вариант наоборот, система из нескольких Micro, переговаривающихся по беспроводному интерфейсу, но это нужно изучать, оставим на будущее.

Вы здорово ошибаетесь в возможностях своей платы. На данный момент занимаюсь разработкой аналогичной системы.

-Ардуино нано\про мини атмега 328
-dht11
-самодельный датчик температуры раствора для полива
-
датчик влажности грунта.
-lcd1602
-часики ds3231

-система включает\выключает свет
-поливает
-вентилирует
-греет

 

7 выходов ушло на lcd1602
3 выхода на кнопки!! тут даже без аналога обошелся
2 аналоговых на часы
1 цифровой Д13 на датчик влажности грунта. поджигаем только в момент когда снимаем показания с датчика. раз в 20 минут
1 пин на dht 11
1 пин на датчик влажности грунта
1 на температуру раствора
4 пина на управление релюхами

в аккурат 20 выходов!

памяти задействовано : 
Скетч использует 14 504 байт (47%) памяти устройства. Всего доступно 30 720 байт.
Глобальные переменные используют 1 179 байт (57%) динамической памяти, оставляя 869 байт для локальных переменных. Максимум: 2 048 байт.

В плане написать еще несколько встроенных программ под разные виды культуры.

Реализовано меню, принудительный полив, два варианта работы со светом. Свет как основной источник и досветка утром вечером, регулировка уровня влажности почвы и длительность полива, установка часов, задание температуры на день и ночь, ведет суточный лог максимальной и минимальной температуры, управляет четырьмя потребителями. всего используется 13 режимов меню. управление происходит тремя кнопками.

На экран в 16 символов и 2 строчки спокойно одновременно!! уместились часы, показания четырех датчиков и трех потребителей(обогрев,вентиляция,свет). При поливе экран моргает этими показаниями и надписью Watering.. Единственный минус не руссифицировал. Не вижу смысла!

Поверьте! эта плата на многое способна. На данный момент все выводы уже заняты, но!! можно освободить еще 2 вывода если переместить кнопки с цифры на аналог, а так же еще три выхода если докупить модуль для дисплея lcd1602 i2c вроде называется.

это второй вариант пульта. тестовый образец в котором используется про мини 328. пайка выполнена полностью самостоятельно и установлены оптические развязки. 

а вот так выглядел первый вариант блока. Он сейчас стоит в теплице. Его планирую модернизировать уже в готовый образец на продажу после обкатки второй версии. В первом варианте был всего один индикатор, который позволял работать со всеми этими функциями!

http://goodyear.org.ua/capella/capellagreenhouse.html

а так это выглядит на макетной плате. Спецом показываю как организован вывод инфы на дисплей.

Не обижайтесь. Код выложить не могу ибо проэкт коммерческий, разрабатывается совместно с компанией по производству теплиц, обтесываю его уже пару месяцев, но уверен Вам есть к чему стремиться!! А у топикстартера точно все выйдет! Таких упертых я еще не видел..

зы: проделав такой длинный путь могу сказать только одно - идите от простого к сложному. не стоит ставить все и сразу. сначала сделайте простое управление по заданным заранее температурам, потом допишите вывод инфы. меню оставьте на закуску, когда будете понимать весь функционал Вашего устройства.

bwn
Offline
Зарегистрирован: 25.08.2014

Немного добавлю к сказанному уважаемым exez, переделав дисплей на i2c, освободите 7, а не 3 вывода, т.к. он будет висеть на одних пинах с часами. Тоже самое можно и по кнопкам. Многие начинающие сегодня, просто забыли или не знают, что ОС Синклер занимала 16К вместе с интерпретатором Basic и была весьма неплохой системой. 86 PC умещали в 640К и ОС и программы, а это был уже полноценный ПК.
Для exez, вместо самодельных темп.датчиков использовал бы DS18B20, можете сразу мерять и темпреатуру почвы и кучу точек как в теплице, так и на улице. Вместо реле, для управления нагрузок 220В есть смысл использовать симисторные ключи, цена эквивалентная - возможности гораздо шире. Ну и из готовых шилдов, наверно только МК имеет право на жизнь. Все остальное разводить на нормальной плате, хотя я бы и МК развел туда же. ИМХО.

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

Огромное Вам спасибо bwn(К сожалению не знаю как Вас зовут). Ваши советы всегда очень полезны!

Относительно датчиков - самопалы дешевле. На данном этапе это важно + теплицы под которые они планирутся  маленькие 3х4, 3х6, 3х8. Вероятно, если будет большой проэкт будут использоваться DS18B20.

зы: обязательно посмотрю на рекомендуемые компоненты. эта плата тестовая. просто для пробы. естественно готовый продукт будет заказываться где то в печать.

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

Порывшись в нете нашел следующую статью. Думаю она будет полезна и ТС и остальным:

http://easyelectronics.ru/upravlenie-moshhnoj-nagruzkoj-peremennogo-toka.html

И возникли вопросы: 
есть вот такой вариант, как советует автор методы: http://ru.aliexpress.com/af/BT139.html?ltype=wholesale&SearchText=BT139&d=y&origin=n&initiative_id=SB_20151125230547&isViewCP=y&catId=0

Но ведь это же обычная кренка??

И есть вот такой вариант:
http://ru.aliexpress.com/af/MOC3041.html?ltype=wholesale&SearchText=MOC3041&d=y&origin=n&initiative_id=SB_20151125225244&isViewCP=y&catId=0

Честно говоря выглядит более впечатляюще..

bwn
Offline
Зарегистрирован: 25.08.2014

Bt139 это симистор, а корпуса одинаковые - ТО220. Для теплицы надо ставить вмесьте с моськой для развязки от сетевого напряжения. Для мощных нагрузок я предпочитаю симисторы с маркировкой BTA, у них теплоотвод изолирован, меньше шансов ухватиться за 220В. Ну а добавив еще один оптрон и три резистора, можем для активных нагрузок организовать плавное управление мощностью, в т.ч. на несколько каналов.
Чем на мой взгляд DS18 предпочтительнее для коммерческого проекта, при малых затратах, можем сказать клиенту: "5-10-20 точек измерения температуры".)))))

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

ткните плиз ссылочкой, а то опять на кренки выкидывает поиск.. или так и должно быть? :)

bwn
Offline
Зарегистрирован: 25.08.2014

В таких корпусах есть и кренки, и симисторы, и транзисторы и пр. Смотрится по маркировке и даташиту.

P/S для схем работающих в релейном режиме, брать моськи с отловом ноля. Для плавного регулирования, без.

cofessor
Offline
Зарегистрирован: 17.11.2015

Спасибо, Exez!

Cейчас я немного получше оцениваю возможность выбранной платы, однако надо учитывать ещё 2 момента.

1-й - я сейчас не способен написать компактный код, дай бог хоть какой пока состряпать. Вот с подключением датчика DHT получилось, с датчиками DS18B20 пока барахтаюсь. Потом буду оптимизировать весь код по новой, чтобы уменьшить занимаемую память.

2-й - функций со временем будет больше. Сейчас у меня пока, в минимальном варианте, будет без полива, 1 датчик на улице и 3 внутри. Функций управления - 6:
-включение тепловой пушки при t<15º
-закрытие форточек при t<20ºC;
-открытие форточек при t>25
ºC;
-включение туманообразователей при t>30
ºC
-включение вытяжного вентилятора;
-включение канального венилятора.

Радиоканал, передача данных и удалённое управление тоже на уме, но это, как говорят, хотелки. Вовсе не обязательно что всё будет реализовано в полном объёме, но там уже будем посмотреть.

С исполнительными механизмами не понимаю Ваших исканий. Стандартное решение - модули реле с опторазвязкой, как раз вход от 5V, специально для выходов МК. Коммутируют высокое напряжение, ток до 10А:

Конечно, если нужно обеспечить пропорциональное управление, тогда симисторы или мосфеты.

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

Очень рекомендую вот эту тему. Это практически основная часть кода в моем устройстве. На ее разработку, вернее на то, что бы  сформировать эту задачу, а потом решить ушло больше всего времени. Особенно на формирование вопроса. Как это реализовать. Тут же готовое решение в открытом доступе :).

Ведь растениям днем надо чтоб было теплее, а ночью прохладнее. И это надо учитывать при обогреве. Это во первых экономит электричество ночью, во вторых полезнее для растений!

http://arduino.ru/forum/programmirovanie/pomogite-reshit-logicheskuyu-zadachu

эта часть кода задает два массива. первый массив промежуточный. служит лишь для вывода на дисплей данных о включенном источнике света, второй массив рабочий. массив сравнивается с текущим временем в часах и если значение в массиве DNT = 1 - значит сейчас световой день. исходя из этого поддерживаем одну температуру, если значение 0 - поддерживаем температуру ночную. значение получаем примерно так:

hh = hourses;
if (DNT[hh] == 1) {день} else {ночь}

 

cofessor
Offline
Зарегистрирован: 17.11.2015

Скажу честно, я вообще не понял что Вы там пытаетесь достигнуть. Наверное для программистов это азбука, но для тех, кто только начал знакомиться с азами программирования и раньше с ним дела не имел, постановка задачи даже непонятна. Мне даже показалось что там тоже никто ничего не понял. Можно как-то попроще объяснить, чего мы добиваемся? Мне кажется, достаточно просто указать какая температура желательна днём, а какая - ночью.

Тогда уж надо рассматривать и изменение температуры в течение всего срока вегетации, потому что температурный режим рассады отличается от температурного режима зацветающих растений и от режима плодоносящих. Осенью же режим разумнее переключить на доращивание, когда Вы все завязи уже оборвали и нужно только чтобы дозрели остающиеся плоды.

Вообще я бы хотел всё это со временем реализовать.

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

cofessor пишет:

..

с датчиками DS18B20 пока барахтаюсь. Потом буду оптимизировать весь код по новой, чтобы уменьшить занимаемую память.

вот тут мне умные люди помогали решить вопрос.

http://arduino.ru/forum/programmirovanie/ds18b20-nuzhna-rabochaya-biblioteka

зы: относительно кода - не парьтесь! сомневаюсь что на начальном этапе у Вас получится забить всю память. Рекомендую везде писать Serial.print и отслеживать логику программы. Это здорово увеличивает занимаемую память, но очень помогает понимать что делается шаг за шагом. после отладки каждого отдельного участка программы просто подтирайте эти сериалы.

PaulIV
Offline
Зарегистрирован: 11.10.2015

exez пишет:

зы: проделав такой длинный путь могу сказать только одно - идите от простого к сложному. не стоит ставить все и сразу. сначала сделайте простое управление по заданным заранее температурам, потом допишите вывод инфы. меню оставьте на закуску, когда будете понимать весь функционал Вашего устройства.

Соглашусь с этим утверждением.

Сперва надо собрать информацию о процессе, который хотелось бы автоматизировать... Имея компетенцию в электронике/программировании, Вы можете и не догадываться о ботанике/агротехнике... Например, в университете Англии (забыл название) решают вопрос по измерению влажности почвы с помощью датчика, но не в земле (в грунте датчик долго не живет), а датчиком на самом растении для измерения натяжения листа, что явл. показателем здоровья растения (пока цена такого около 2 тыс фунтов). Рекомендую к просмотру, труды разных людей по автоматизации теплиц. Вдруг, пригодиться...

https://youtu.be/1yO6BQaPkbo

https://youtu.be/bBmWZa1q9Yg

https://youtu.be/4ZkP0jGYzBM

Удачи

И вопрос возник. Насколько точны часики, что в центре фотографии с батарейкой - убегают, отстают или стабильны? Спасибо

cofessor
Offline
Зарегистрирован: 17.11.2015

А через что я буду выводить Serial.print? Железа то ведь нет. Только через Proteus.

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

Serial.print выводит данные в монитор компилятора. Настоятельно рекомендую освоить эту матчасть!! Без нее дальше двигаться просто невозможно. http://arduino.ru/Reference/Serial

Самый простой пример работы:

int a = 11;

void setup() {
 Serial.begin(9600);

}

void loop() {
  Serial.print ("a = "); Serial.println (a);
  delay(1000);
}

 

Часы работают хорошо. на сколько точно не засекал, но за сутки сбоя даже в секунду не наблюдается. это вроде не плохо..

cofessor
Offline
Зарегистрирован: 17.11.2015

Откуда эти данные в монитор передаются, разве не с платы Arduino?

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

просто попробуйте предложенный скетч загрузить в Вашу дуинку и запустить монитор порта !

cofessor
Offline
Зарегистрирован: 17.11.2015

Так ведь я Вам объясняю и с самого начала писал что вместо железа использую программу-симулятор Proteus. Ни платы, ни дисплея, ни датчиков я ешё не имею - не пришли из Китая.

С адресом датчиков DS18B20 возможно и будут проблемы при параллельном подключении, ведь адреса уникальны и их тоже нужно где-то взять, однако не исключено что Proteus  может их сам генерировать. Пока не знаю ответа, скомпиллировал для примера скетч с 2-мя датчиками - протеус показывает на экране только один датчик, да и то с неправильной температурой - или скетч неправильный или протеус не может это симулировать.

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

ясно.. я видимо Вас не понял про железки. ну тогда ждите железяки.. или купите ардуинку у себя. это затягивает. на одной ардуине не остановитесь! 100%

Cyoko
Offline
Зарегистрирован: 22.08.2014

часы нормальные 3231 или как то так по маркировке. ds1307 убегают . В сети есть видео по переделке чтоб не убегали. arduinolab канал.

bwn
Offline
Зарегистрирован: 25.08.2014

cofessor пишет:

Так ведь я Вам объясняю и с самого начала писал что вместо железа использую программу-симулятор Proteus. Ни платы, ни дисплея, ни датчиков я ешё не имею - не пришли из Китая.

С адресом датчиков DS18B20 возможно и будут проблемы при параллельном подключении, ведь адреса уникальны и их тоже нужно где-то взять, однако не исключено что Proteus  может их сам генерировать. Пока не знаю ответа, скомпиллировал для примера скетч с 2-мя датчиками - протеус показывает на экране только один датчик, да и то с неправильной температурой - или скетч неправильный или протеус не может это симулировать.

С живыми датчиками проблем не будет, с протеусными затрудняюсь сказать. Вы только все в loop не пихайте, разбивайте на функции и обращайтесь к ним по мере надобности. Легче и в отладке и в доработках-переделках.

cofessor
Offline
Зарегистрирован: 17.11.2015

Да куды мне-то, "с одним лёгким". Я пока больше чужое пытаюсь приспособить. Вот этот вариант, несмотря на некоторую (возможно кажущуюся) заносчивость автора, с моей дилетантской точки зрения, очень недурён: http://arduino.ru/forum/programmirovanie/podklyuchenie-neskolkikh-ds18b20-na-odnu-shinu-i-na-raznye-vyvody#comment-137317. (См. пост #3). Хотел просто скопировать и здесь привести, но боюсь нарушить права автора.

Жаль у него недописано как выводить на LCD. Там массив, а я этого зверя пока не касаюсь.

bwn
Offline
Зарегистрирован: 25.08.2014

Вы там все плевки прочитали? 1. Смысл увеличивать количество пинов, если можно использовать один? 2. Адреса обязаны быть или в епроме или в прошивке, иначе с каждым отключением будете определять датчики по новой. Можно расположить на шлейфе по мере возрастания адреса, но что делать при замене? Юзайте обычную OneWire и пока деталей нет, наберите "DS18B20 Чернов.Г"

cofessor
Offline
Зарегистрирован: 17.11.2015

Нет, во 2-й версии у него всё к одному пину подключено. И у него всё именно в функции засунуто, как Вы советовали. У Чернова всё в loop и тоже вывод на LCD отсутствует. EEPROM, честно говоря, на данной стадии вообще не волнует. Можно потом дописать.

А ещё, я смотрю, задержка delay (750) в loop у многих авторов, но это же плохо? - Кнопки то не будут реагировать, если только их через прерывания не опрашивать.

 

bwn
Offline
Зарегистрирован: 25.08.2014

cofessor пишет:

Нет, во 2-й версии всё к одному пину подключено. И у него всё именно в функции засунуто, как Вы советовали. У Чернова всё в loop и тоже вывод на LCD отсутствует.

А ещё, я смотрю, задержка delay (750) в loop у многих авторов, но это же плохо? - Кнопки то не будут реагировать, если только их через прерывания не опрашивать.

Обычно пример делается без извращений, а максимально простым путем. Оттуда задержки, loop и прочее. Ваша задача, взять из примеров и кодов хорошие идеи и написать код, устраивающий вас.
Для вывода, какая разница между serial и lcd?
Будет не лень, почитайте этот холивар. Писалось 2 месяца, код простой лобовой, но с неоспоримым достоинством, он летает и уже скоро год как работает в железе. Там много размышлений и комментариев, думаю поймете.

cofessor
Offline
Зарегистрирован: 17.11.2015

Да нет, я там ничего не пойму, Вы слишком высокого мнения обо мне. Я строю свои задачи по принципу минимализма, вот так примерно:

1. Вычленить простейший фрагмент кода для вывода текста на LCD (скаладываю себе в каталог кучу скетчей, выбираю самые понятные)
2. Пробую их компиллировать, проверяю работу на симуляторе. 
3. Ага, получилось, протеус показывает что-то, но неправильно и мигает, разбираемся.
4. Добились, теперь простейший фрагмент подключения DHT22.
5. Температура с датчика не попадает на LCD
6. Теперь попадает, но протеус показывает на LCD не ту температуру, какая на элементе "Датчик DHT22", почему?

Ну и т.д.

То есть видите, пока на самом примитивном уровне. Ещё неделю только как впервые с программированием знакомиться стал. Сейчас, кроме того чтобы DS18B20 стал выводить на LCD температуру правильно, ничего не интересует - чкачал кучу файлов, сравниваю, выбираю, затем буду пробовать.

bwn
Offline
Зарегистрирован: 25.08.2014

Я бы на железе пробовал, что этот протеус у себя в голове мыслит мы не знаем. Если там можно отобразить значения переменных, выведите его и сверьте с lcd.

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

Вы не правильно начинаете.. Не стоит брать чужое и пытаться его компилировать. Одно дело взять готовый скетч для датчика с библиотекой и засунуть его в свое готовое, и совсем другое компилировать все подряд!

Открываете вот эту ссылку и начинаете подряд разбирать все функции языка. http://arduino.ru/Reference

Разбираете пример за примером. От простого к сложному. Для начала уделите внимание переменным. int и unsigned long. Первые работают со всеми целыми числами, вторая для работы со временем.

Уделите внимание операторам if\while 

попробуйте помигать диодом при нажатии на кнопку. потом сделайте плавное разгорание и плавное затухание путем уменьшения переменной в обычной функции delay().. и так далее.

Тупо компилить все подряд - результата не будет. Очень мало шансов что кто то написал именно то, что надо ВАМ!

И надо железо. Ардуинка, кнопочка, диодик. Чтоб все почувствовать..

как то так..

itjunky
Offline
Зарегистрирован: 15.09.2014

Фигасе понафлудили то =)
Я то же считаЮ что нужно не дёргать куски отовсюду, а брать и с нуля писать.

https://www.coursera.org/learn/roboty-arduino
Вот отлично и по-русски, с самого нуля и на уровне харда и на уровне софта учат как вообще в этом мире жить ;)

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

bwn пишет:

В таких корпусах есть и кренки, и симисторы, и транзисторы и пр. Смотрится по маркировке и даташиту.

P/S для схем работающих в релейном режиме, брать моськи с отловом ноля. Для плавного регулирования, без.

Если не сложно можно какие то циферки закинуть. чтоб проще было отыскать в гугле то что Вы советуете.. Заинтересовали и с плавным пуском (такие отменно подойдут для работы нагревателей на половину мощности) и просто вкл\выкл. буду очень признателен. Ожидаемые нагрузки: 220В 2кВт +\- переменный ток.

зы: а то по рынку сегодня бегал, но как то безрезультатно.

по симисторам вроде разобрался. надо брать что то типа bta24-600, а вот какие оптопары брать для моих нужд..?

bwn
Offline
Зарегистрирован: 25.08.2014

moc 3041, 3061 для релейного режима, 3021 для диммирования. Под 2кВт скорее всего теплоотвод надо будет на симистор.

cofessor
Offline
Зарегистрирован: 17.11.2015

Exez, я же написал что сижу и разбираюсь, почему Вы написали что я тупо компиллирую всё подряд?

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

Извините, возможно, жестко выразился, но все же советую писать самому..

cofessor
Offline
Зарегистрирован: 17.11.2015

cofessor пишет:
 У Чернова всё в loop и тоже вывод на LCD отсутствует. 

Ой-ё-ёй! Ашипка вышла, оговорил человека. Тот скетч, который я имел в виду, не Черновым был написан. Это Andbas написал, но в общем он там здорово всё объяснил - помочь может тому кто тоже только начал знакомство с DS1820 и обменом по 1-Wire. Вот ссылка: http://research.andbas.com/2012/02/1-wire-ds18s20.html

cofessor
Offline
Зарегистрирован: 17.11.2015

exez пишет:
Извините, возможно, жестко выразился, но все же советую писать самому..
Писать самому, Вы под этим что имеете в виду? Раз уж у меня своя система меню (читайте ранее), то Вы как, считаете что я могу найти скетч один к одному, реализующий моё меню? Первое меню то я, как раз, уже сделал, выдаёт на LCD1602 температуру и влажность в теплице, используя датчик DHT22, в первой строке и температуру на улице во второй строке, используется датчик DS18B20. Вот он:

#include "DHT.h"           //библиотека для датчика DHT22
#include <LiquidCrystal.h> //библиотека для дисплея LCD1602
#include <OneWire.h>       //библиотека для датчика DS18B20
//Формируем свои символы
byte l_kr[8] =
{
  B00011,
  B00111,
  B00101,
  B00101,
  B01101,
  B01001,
  B11001,
  B11001,
};
byte p_kr[8] =
{
  B11111,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
};
byte grad_kr[8] =
{
  B00110,
  B01001,
  B01001,
  B00110,
  B00000,
  B00000,
  B00000,
  B00000,
};
OneWire ds(A3);     //Датчик t на улице DS18B20 полключен к A3
#define DHTPIN A4   //Датчик t/w в теплице DHT22 подключен к А4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE); //Создаём объект dht
LiquidCrystal lcd(6, 8, 9, 10, 11, 12);
long previousMillis = 0;           //Точка отсчёта
long interval = 2000;             //Задержка
float t, h;
byte i;
byte present = 0;
byte data[12]; // массив для хранения информации с датчиков
byte addr[8];  // массив для хранения адреса датчиков
int TempMSB, TempMSB2, TH, TL;
float T, TReading, TempLSB;

void setup(){
lcd.createChar(1,l_kr);        //Нумеруем
lcd.createChar(2,p_kr);        //свои
lcd.createChar(3,grad_kr);     //знаки
lcd.begin(16,2);               //Инициализация LCD1602 
dht.begin();                   //Инициализация DHT22
}

void loop() {
unsigned long currentMillis = millis();         //Считать текущее значение таймера 0
  if(currentMillis-previousMillis > interval) { //Если интервал закончился - 
    previousMillis=currentMillis;               //установить новую точку отсчёта  
    h = dht.readHumidity();                     //и считать текущее значение 
    t = dht.readTemperature();                  //температуры и влажности
    if (isnan(t) || isnan(h)) {                 //и, если нет сбоя,
      lcd.setCursor(0, 0); 
      lcd.print("Failed to read from DHT");
      } else {
      } 
      //Меню №1. В 1-й строке отображаем тек. t и w  в теплице, во 2-й - t на улице.    
        lcd.setCursor(0, 0);
        lcd.print("TE\2\1=");
        lcd.print(t, 0);
        lcd.print("\3C ");
        lcd.print("W=");
        lcd.print(h, 0);
        lcd.print("%");
   }
    if ( !ds.search(addr)) {  //адрес не найден
  ds.reset_search();
  return;
  }
  ds.reset();
  ds.select(addr);   // выбираем датчик
  ds.write(0x44);  // запускаем конвертацию
  delay(750);        // даем время, чтобы датчик сконвертировал температуру
  present = ds.reset();
  ds.select(addr);     //выбираем датчик 
  ds.write(0xBE);      //считываем ОЗУ датчика
    for ( i = 0; i < 9; i++) { //записываем 9 байт полученных с ОЗУ датчика
    data[i] = ds.read();
    }
  TempLSB = data[0];    //высчитываем температуру
  TempMSB = data[1];
  TempMSB2 = TempMSB << 4 ;
    if (TempMSB2 > 1000) {
    TempMSB2 = TempMSB2 - 3968;
    TReading = TempMSB2 + TempLSB/16 - 128;
    } else {
    TReading = (TempMSB << 4) + TempLSB/16;
  }
lcd.setCursor(0, 1);  //посчитали - выводим на печать
lcd.print("BHE=");
lcd.print(TReading, 0);
lcd.print("\3C"); 
} 

Симулятор всё показывает правильно, и отрицательную температуру и положительную.
Просто я считаю что никакую свою программу на Ардуино Вы в принципе не напишете - всё предопределено. О какой своей программе можно говорить, когда за Вас всё делают готовые библиотеки?? Если хотите сами писать - осваивайте Си.
Не подскажете заодно как код программы под кат убрать?

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

странная реакция.. библиотека, библиотекой, а программа программой. :) ну да ладно. Что подумал Кролик никто не узнал, потому что он был очень воспитанный.

cofessor
Offline
Зарегистрирован: 17.11.2015

Вообще то кролик никому ничего не сообщал о том что он подумал... М-мм, ну да ладно, мне странно что Вам это странно. Посмотрите внимательней на эту программу: почти каждая строка - это вызовы функций из этих библиотек. Практически всё делает библиотека, а вся Ваша свобода, как программиста, заключается в лёгкой подстройке этих функций под Ваши хотелки.

yana
Offline
Зарегистрирован: 01.12.2015

Здравствуйте. я из китайской компании. хочу с вам сотрудничать. вы можете добавлять меня в скайп или вк? uslada100  https://vk.com/liboting

cofessor
Offline
Зарегистрирован: 17.11.2015

Ох, как давно я за скетч не садился? Уж и забыл когда в последний раз, всё недосуг. Поработал ещё немножко вчера и сегодня, доделал опрос исполнительных механизмов. Теперь по логике, в целом есть и меню и установка порогов температуры, и управление исполнительными механизмами. Последнее, правда сырое, остальное - более менее работает.

Между прочим, навигация по меню и установка параметров у меня производится одной единственной кнопкой. А зачем больше, когда одной достаточно?

#include "DHT.h"           //библиотека для датчика DHT22
#include <LiquidCrystal.h> //библиотека для дисплея LCD1602
#include <OneWire.h>       //библиотека для датчика DS18B20
#include <DS1307.h>
DS1307 rtc(A4, A5);
byte l_kr[8] = {B00011, B00101, B00101, B01001, B01001, B01001, B10001};
byte p_kr[8] = {B11111, B10001, B10001, B10001, B10001, B10001, B10001};
byte u_kr[8] = {B10001, B10001, B10001, B01111, B00001, B10001, B01110};
byte d_kr[8] = {B00011, B00101, B00101, B101001, B01001, B11111, B10001};
byte grad_kr[8]={B00110, B01001, B01001, B00110, B00000, B00000, B00000};
OneWire ds(A1);           //Датчик t DS18B20 на улице подключен к A3
#define DHTPIN A2         //Датчик t/w DHT22 в теплице подключен к А4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE); //Создаём объект dht
LiquidCrystal lcd(8, 9, 10, 11, 12, 13); //Подключили LCD к пинам контроллера
long previousMillis=0;    //Начальная точка отсчёта времени для DHT22
long previousMillis1=0;   //Начальная точка отсчёта времени для работы ИМ
long previousMillis2=0;   //Начальная точка отсчёта времени для гистерезиса ИМ
long interval=2000;       //Задержка для обработки данных датчиком DHT22
long interval1=400;       //Задержка 0,4 сек для отображения Меню №2 и №3
long time1, time2;//Время отработки и задержки после отработки исп.механизмами
float t, h, T, TReading, TempLSB, TempMSB2;
byte i;
byte present = 0, byte_status=0;
byte data[12];            // массив для хранения информации с датчиков
byte addr[8];             // массив для хранения адреса датчиков
int TempMSB, knopka;
byte t_heat=18, t_close=22, t_open=26, t_cool=28; //пороговые значения температур

void setup(){
  rtc.halt(false);    //Установить часы чтобы запустить режим
  //Записать тек. время и дату, закомментировать и перезапустить DS3231
  rtc.setDOW(SUNDAY);         //Установлен день недели - воскресенье
  rtc.setTime(17, 8, 0);      //Уст. времени в 24ч формате
  rtc.setDate(8, 12, 2015);   //Дата
  rtc.setSQWRate(SQW_RATE_1); //Установите SQW/Выход ставку до 1 Гц, 
  rtc.enableSQW(true);        //а также включить SQW 
lcd.createChar(1,l_kr);       //Буквы: л
lcd.createChar(2,p_kr);       //п
lcd.createChar(4,u_kr);       //у
lcd.createChar(5,d_kr);       //д
lcd.createChar(3,grad_kr);    //знак градуса
lcd.begin(16, 2);             //Инициализация LCD1602 
dht.begin();                  //Инициализация DHT22
DDRD = B11111100;  
}

void loop() {  //Меню №1-----------------------------------------------------------
//1-я строка основного меню. Температура и влажность в теплице (Датчик DHT22)
  lcd.setCursor(0, 0);
  lcd.print("TE\2\1=");
  lcd.print(t, 0);            //Отображение температуры в теплице
  lcd.print("\3C W=");
  lcd.print(h, 0);            //Отображение влажности в теплице
  lcd.print("%");
  unsigned long currentMillis = millis();       //Текущее значение t0
  if(currentMillis-previousMillis>interval) {   //Если интервал закончился - 
    previousMillis=currentMillis;               //установить новую точку отсчёта  
    h = dht.readHumidity();                     //текущее значение h
    t = dht.readTemperature();                  //текущее значение t
    if (isnan(t) || isnan(h)) {                 //Не удалось считать? -
    lcd.setCursor(0, 0); 
    lcd.print("Failed read DHT");               //- вывести на LCD "Ошибка чтения"
    }
   }
//2-я строка основного меню. Температура на улице и время(Датчики DS18B20 и DS3231)
    if (!ds.search(addr)) {    //Если адрес DS18B20 не найден - возврат
    ds.reset_search();
    return;
    }
    ds.reset();
    ds.select(addr);           //селекция датчика и
    ds.write(0x44);            //конвертация
    present = ds.reset();
    ds.select(addr);           //селекция и 
    ds.write(0xBE);            //считывание данных
    for ( i = 0; i < 9; i++) { //запись 9 байт полученных с ОЗУ датчика
      data[i] = ds.read();
    }
    TempLSB = data[0];         //переформат температуры
    TempMSB = data[1];
    TempMSB2 = TempMSB << 4 ;
    if (TempMSB2 > 1000) {
      TempMSB2 = TempMSB2 - 3968;
      TReading = TempMSB2 + TempLSB/16 - 128;
      } else 
       {
        TReading = (TempMSB << 4) + TempLSB/16;
       }
     lcd.setCursor(0, 1);      //Отображение после преобразования
     lcd.print("HA\4\1=");
     lcd.print(TReading, 0);   //температуры на улице
     lcd.print("\3C      "); 
     lcd.setCursor(11, 1);
     lcd.print(rtc.getTimeStr());//Отображение времени

//Управление исполнительными механизмами----------------------------------------------       
   //управление нагревом
     if(t<t_heat){             //t<18 -
       PORTD=PORTD|0x04;       //включить нагрев
     }
     if (t>t_heat+2){          //t>t_head+2 -
       PORTD=PORTD&B11111011;  //отключить нагрев
     }
     //управление окнами и охлаждением
    if(PORTD&&0xf8==0){        //Если ничего, кроме нагрева, не включено, начать проверку t     
      if(t<t_close&&t>t_open){ //Если t не в норме, включить ИМ
        if(t<t_close){         //Если t<22 -
         PORTD=PORTD|0x08;     //включить ИМ "закрыть окно"
         time1=1000;           //Длительность работы
         time2=2000;           //Длительность паузы
        }
        if (t>t_open){         //Если t>26 -
          PORTD=PORTD|0x10;    //включить ИМ "открыть окно"
          time1=1000;  
          time2=2000; 
        }
        if (t>t_cool){         //Если t>28 -
         PORTD=PORTD|0x20;     //включить ИМ "охлаждение"
         time1=1;
         time2=10;         
        }
      previousMillis1=currentMillis; //Задать начало интервала работы ИМ
      previousMillis2=currentMillis; //Задать начало интервала паузы ИМ
      }
    } 
    else             //Если есть включенный ИМ, отследить интервалы и выключить
      {
      unsigned long currentMillis=millis();    
      if(currentMillis-previousMillis1<=time1){   //ИМ закончил работу?
        return;                                   //Нет - ничего не делать
      }
      else
      { 
        PORTD=0x40;                //закончил - выключить ИМ, уст. признак паузы
        if(currentMillis-previousMillis2>=time2){ //Пауза закончилась?
          return;                                 //Нет - ничего не делать
        }
        else
        { 
          PORTD=0x00;       //Да - отключить все ИМ
        }
      }
    } //Конец процедуры отработки ИМ     

  if(analogRead(A3)>>2<40){   //Опрос кнопки навигации
  Menu2(); //вызов Menu2
}
} //End Loop

//Меню №2 Установка t вкл/выкл тепловой пушки и туманообразователей
void Menu2() {
delay (200);                 //Задержка на отпускание кнопки
lcd.clear();
while(analogRead(A3)>>2>40){ //Циклическое изменение пока не нажата кнопка
  lcd.setCursor(0, 0);
  lcd.print("T\3 BK\1 TE\2\1O  ");
  unsigned long currentMillis1 = millis();
  if(currentMillis1-previousMillis > interval1) { 
    previousMillis=currentMillis1; 
    t_heat++;
    if (t_heat>20) {
     t_heat=12;
    }
  }
  lcd.print(t_heat);         //Температура включения нагрева
 }
delay (200);                 //Задержка на отпускание кнопки
while(analogRead(A3)>>2>40){ //Циклическое изменение пока не нажата кнопка
  lcd.setCursor(0, 1);
  lcd.print("T\3 BK\1 XO\1O\5  ");
  unsigned long currentMillis1 = millis();
   if(currentMillis1-previousMillis > interval1) { 
     previousMillis=currentMillis1;
     t_cool++;
     if (t_cool>30) {
      t_cool=28;
     }
  }
  lcd.print(t_cool);        //Температура включения охлаждения
 }
}

Теперь вопрос стоит: А как бы всё это оптимизировать чтобы было компактнее и понятнее?

itjunky
Offline
Зарегистрирован: 15.09.2014

Следующий шаг обдумывался?

Мне он видится как система мониторинга и анализа данных. То есть, как минимум имеет смысл видеть суточные графики температуры и влажности, с наложением например на график недельной и месячной давности, в этом случае есть представление и о суточной и о более длительной динамике на одном экране, правда это уже будет экран компа или телефона, по всей видимости.

Я сейчас работаю какраз над тем что бы сделать стабильный микросервис сбора данных с удалённых сенсоров, которые просто по сети шлют данные и свой ID, а сервер уже агрегирует это всё и выводить на сайте графики. Реализовать это не особо сложно, единственное, что нужно это добавить сеть к контроллеру и арендовать VPSку самоую дешёвую. Ну и немножко питона и Flask или PHP и чего-нить тамошнего в качестве фрэймворка.

Как только реализую чоткий сборщик данных, опубликую свои наработки, в том числе и тут, если интересно.

cofessor
Offline
Зарегистрирован: 17.11.2015

Вот здесь посмотрите: 

Arduino Mega. Контроллер теплицы. Хроники

Может как раз то что Вам нужно.

itjunky
Offline
Зарегистрирован: 15.09.2014

Занятный топик, челик там с грандиозными планами,  и мне есть что ему сказать, но тамошний идиотский форум зачем-то требует подтверждения не только мыла, но и... что бы вы думали нужно форуму? НОМЕР ТЕЛЕФОНА!!! А у меня какраз сдох экран на трубке и я не могу прочесть смс...

cofessor
Offline
Зарегистрирован: 17.11.2015

Да нет, для него это не грандиозные планы, а просто приложение своим знаниям. Думаю, большая проблема для него - алгоритм, поскольку для этого нужно агротехнику выращивания знать. Он сейчас только именно эту проблему и поднял. Если совместит свои знания с разумным оптимальным алгоритмом для микротеплиц - то да, может создать нечто стоящее, если напористости хватит.

terminal
Offline
Зарегистрирован: 02.09.2015

Здравствуйте ! Уже давно усовершенствую свой универсальный таймер. Все началось с автоматизации гидропоники. Сейчас делаю систему на Atmega 128. Теперь свои пять копеек в копилку. Делая автоматизацию гидропоники я понял что для всего этого нужен универсальный таймер и реагирование на события. События идут от датчиков. Но главной моей целью сейчас стоит именно универсальность устройства. Что у меня сейчас. Процессор Atmega128, внешняя память AT241024 в которой я храню 1024 будильника по 128 байт, связь с компьютером FT232, два датчика температуры, датчик влажности, часы реального времени DS1307,флеш карта,выход RS485,дисплей 2004, крректировка данных энкодер. Программа прогрузки будильников https://cloud.mail.ru/public/L2i7/pEtxEGuiS если кому интересно. Как все работает, в будильнике записано сколько секунд будет включен канал. Есть еще команда повтора. К примеру нам нужно каждые 20 секунд включать вывод на 5 секунд. Значит команда будет 5 сек повтор 20 сек. Но бывает что еще нужно чтоб сигналы отстовали друг от друга на определенный промежуток времени для этого сделан канал задержки. К примеру мне нужно чтоб устроство двигалось то в одну сторону то в другую то я ставлю задержку на половину времени и две одинаковые команды, думаю что сложно для понимания но это работает.

Теперь к самому главному. Предлогаю построить систему где все устройства будут распределены и общение между устройствами будет проходить по определенному протоколу. Почему так. Ну вот я тоже вначале пытался засунуть все в одну микросхему. Потом пришел методом проб и ошибок что это тупиковый вариант. Система должна быть построена на базе центрального блока, блоков датчиков и блоков исполнительных устройств. Пример: нам нужно чтоб на устройсве "А" была мощность 50 % то мы прото кидаем в линию (rs485) значение 50 для устройства "А" а там уже стоит отдельный контроллер которвый режет синус и выдает мощность на розетке в 50%. То же самое с датчиками, центьральный блок опрашивает не датчики а блок с датчиком который посылает ему данные датчика в удобном виде для быстрой обработки. Соответственно датчик может быть любой но данные получатся стандартные, вот к примеру для датчика влажности это будет влажность в процетах, для температуры температура в градусах и.т.д.

Если получится договориться то каждый может взять отдельную задачу и делать ее отдельно, потом или обмен или продажа это уже как кому хочется. Если кто хочет то может выкладывать свои блоки в открытый доступ. Самое главное создать протокол обмена который будет устраивать всех.

cofessor
Offline
Зарегистрирован: 17.11.2015

А что значит 1024 будильника по 128 байт? Каждый будильник занимет объём памяти 128 байт? Тогда их всего 8!? Вы что же, храните там секунды, минуты, часы, дни, месяцы и годы в каждом будильнике? Вообще то в микроконтроллере есть таймеры, даже целых три, которые и так хранят текущее время, а если Вам нужны месяцы (годы уж думаю никому не нужны), проще добавить м/сх RTC. С помощью их Вы легко реализуете неограниченное количество временных интервалов безо всяких будильников. Зачем процессор превращать в БОЛЬШОЙ ТАЙМЕР?

itjunky
Offline
Зарегистрирован: 15.09.2014

terminal Кофессоры выше дал линк, где чел так же пришёл к идее модульности и даже реализовал некое подобие протокола на начальном уровне, судя по описанию.

Я и сам пришёл к чему-то подобному, но центральный блок у меня выполняет скорее роль веб-сервера и для этой задачи уже не достаточно одного МК, нужна более сложная система и по цене/функционалу тут больше всего подходит распберри(у меня в этой роли старенький нетбук с убунтой). Блок с сенсорами внтури теплицы снимает атмосферные данные, до данных по почве не дошёл, поскольку там то же идут постоянные модификации в поиске наиболее продуктивного варианта, в чём и помогает анализ некоторых данных.

Так же к центральному блоку подключена веб-камера и когда там день, я могу наблюдать всё ли в порядке. На странице кроме камеры  выводятся графики по получаемым данным, можно выбрать различные промежутки на шкале времени.

Касаемо совместной работы это очень хорошее предложение! Я готов поучаствовать и со своей сисадминской стороны готов взяться какраз за сетевые фишки и вебморду.

terminal
Offline
Зарегистрирован: 02.09.2015

itjunky пишет:

Касаемо совместной работы это очень хорошее предложение! Я готов поучаствовать и со своей сисадминской стороны готов взяться какраз за сетевые фишки и вебморду.

Как на счет RS485?  Я только из-за дешивизны и простоты реализации. Хотя можно и на сетке сделать, все зависит от того сколько сейчас стоят преобразователи. Для 485 микросхема стоит 50 руб. К компу можно подключить FT232-485. Скорость 250К.

terminal
Offline
Зарегистрирован: 02.09.2015

cofessor пишет:

А что значит 1024 будильника по 128 байт? Каждый будильник занимет объём памяти 128 байт? Тогда их всего 8!? Вы что же, храните там секунды, минуты, часы, дни, месяцы и годы в каждом будильнике? Вообще то в микроконтроллере есть таймеры, даже целых три, которые и так хранят текущее время, а если Вам нужны месяцы (годы уж думаю никому не нужны), проще добавить м/сх RTC. С помощью их Вы легко реализуете неограниченное количество временных интервалов безо всяких будильников. Зачем процессор превращать в БОЛЬШОЙ ТАЙМЕР?

Прежде чем что-то сказать, почитайте даташиты на микросхемы и хотя бы загрузите программу для будильников. Таймер охватывает большой промежуток времени, еще хочу сделать чтоб была функция пропуска даты года месяца и дня недели. Это даст возможность создавать месячные недельные и годовые циклы. По поводу будильников, в будильнике идут кроме даты значение температуры, влажности, мощности 4 цифровых каналов, и секунды включения для аналоговых каналов. При чем, один будильник может нести информацию о повторе включения и задержки включения(я уже писал что это сложно для понимания но данная функция была получена методом проб и ошибок). Таким образом получается устройство которое не просто поддерживает температуру и влажность но еще может менять все параметры в зависимости от будильников.

cofessor
Offline
Зарегистрирован: 17.11.2015

Тогда уж пишите: Прежде чем спрашивать...

Видимо лучше не спрашивать.

terminal
Offline
Зарегистрирован: 02.09.2015

cofessor пишет:

Тогда уж пишите: Прежде чем спрашивать...

Видимо лучше не спрашивать.

DS1307 Это что по Вашему ? Объем AT24С1024 равен 128 килобайт !

cofessor
Offline
Зарегистрирован: 17.11.2015

terminal пишет:

DS1307 Это что по Вашему ?

Мы о разных вещах говорим? Я хотел обратить Ваше внимание что у Вас всё как-то на время завязано. Вы же сами пишете: Уже давно усовершенствую свой универсальный таймер. Получается что процессорная система у Вас - просто универсальный таймер. Я тоже RTC подключил в систему, но пока вообще не придумал как его использовать кроме того что он будет показывать время, поскольку все основные переключения будут осуществляться вне зависимости от времени по событиям - сигналам от датчиков. У Вас всё будильниками называется. Такое ощущение что RTC командует процессором. С моей точки зрения - какой-то неудачный упор на тайминг, можете плевать на меня, но мне как-то слух режет.