СДЕЛАЙТЕ СВОИ УРОКИ ЕЩЁ ЭФФЕКТИВНЕЕ, А ЖИЗНЬ СВОБОДНЕЕ

Благодаря готовым учебным материалам для работы в классе и дистанционно

Скидки до 50 % на комплекты
только до

Готовые ключевые этапы урока всегда будут у вас под рукой

Организационный момент

Проверка знаний

Объяснение материала

Закрепление изученного

Итоги урока

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

Категория: Информатика

Нажмите, чтобы узнать подробности

Аннотация.

Тема исследования: «Умная» теплица на базе Arduino.

Проблема исследования: как увеличить производительность теплицы;

Объект исследования: автоматизированный комплекс поддержания микроклимата в теплице;

Предмет исследования: применение  систем управления в повседневной жизни;

Цель исследования: Создание умной теплицы для семьи и ее практическое применение.

Задачи исследования:

  1. Собрать на базе Arduino блок управления микроклиматом.
  2. Написать программу.
  3. Изучить, литературу и найти информацию об использовании систем управления.
  4. Выполнить монтаж и наладку. Провести тестирование моей установки.
  5. Проанализировать полученные результаты и выявить достоинства и недостатки моей системы;

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

Гипотеза исследования: если мы хотим повысить производительность труда, то нам необходимо использовать современные технологии.

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

Новизна: особенность моего проекта заключается в использовании микроконтроллера Arduino Mega, программируемого на языке С++.

Практическая значимость: минимизация участия человека в уходе за растениями в теплице, при сохранении высокого урожая.

Преимущества предлагаемого к реализации изобретения перед аналогами: более точная регулировка температуры, настройка полива. Соединил эти две системы в одну.

 

 

Просмотр содержимого документа
«Умная теплица на базе Arduino Mega 2560»

российская научно-социальная программа

для молодежи и школьников «Шаг в будущее»




VI школьный конкурс исследовательских работ обучающихся

«Молодые исследователи Югры»









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

















Васильев Алексей

МБОУ «Барсовская СОШ № 1»,

9 «А» класс



Научный руководитель:

Васильева Елена Анатольевна, учитель информатики, МБОУ «Барсовская СОШ № 1»,













Барсово

2018 год





Оглавление.

Аннотация………………………………………………………………..3

Введение………………………………………………………………….4-5

Практическая часть………...................................................................6-8

Заключение……………………………………………………………….9

Список литературы, используемых интернет-источников…………...10

Приложение 1……………………………………………………………..11

Приложение 2……………………………………………………………..12-27









































Аннотация.

Тема исследования: «Умная» теплица на базе Arduino.

Проблема исследования: как увеличить производительность теплицы;

Объект исследования: автоматизированный комплекс поддержания микроклимата в теплице;

Предмет исследования: применение систем управления в повседневной жизни;

Цель исследования: Создание умной теплицы для семьи и ее практическое применение.

Задачи исследования:

  1. Собрать на базе Arduino блок управления микроклиматом.

  2. Написать программу.

  3. Изучить, литературу и найти информацию об использовании систем управления.

  4. Выполнить монтаж и наладку. Провести тестирование моей установки.

  5. Проанализировать полученные результаты и выявить достоинства и недостатки моей системы;

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

Гипотеза исследования: если мы хотим повысить производительность труда, то нам необходимо использовать современные технологии.

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

Новизна: особенность моего проекта заключается в использовании микроконтроллера Arduino Mega, программируемого на языке С++.

Практическая значимость: минимизация участия человека в уходе за растениями в теплице, при сохранении высокого урожая.

Преимущества предлагаемого к реализации изобретения перед аналогами: более точная регулировка температуры, настройка полива. Соединил эти две системы в одну.









Введение.

Обычно «умными» называют саморегулирующиеся объекты и технические системы. Так «умный дом», используя высокие технологи, экономит ресурсы и обеспечивает своим обитателям комфорт и безопасность. В обиходе под «умными» вещами понимают бытовые устройства, автоматически включающие и выключающие свет, открывающие въездные или гаражные ворота и т.д. Точно так же и «умная теплица» сама поддерживает микроклимат (влажность и температуру), открывает форточки для проветривания при помощи электроприводов, осуществляет автополив по заданным параметрам. Зачем все это? В настоящее время у большинства людей очень мало свободного времени. Если постоянно не жить на даче, то получить хороший урожай почти невозможно, особенно за наше короткое северное лето. Давайте рассмотрим подробнее, что же происходит в конструкции, которая «не умная». То есть попросту которой не ведома автоматика для теплиц и контроль за ее микроклиматом ведется по возможности, хотя и фактически каждый день. Рано утром, как только первые солнечные лучи попадают в теплицу, температура в ней начинает достаточно быстро повышаться. Для растений это – хорошо. Вот только есть проблема: перепад температур в это время между почвой и воздухом достигает порой разницы в 30°С! Корни остаются еще холодными, тогда как верхушки растений уже разогрелись. И происходит вот что: более «холодная» подземная часть плохо снабжает более «теплую» верхнюю часть растений, что приводит к элементарному дефициту влаги. Что на самом деле для растений плохо. Еще больший стресс растения испытывают в жару в такой теплице. Ведь обычно хозяева идут собственноручно открывать форточки и двери уже тогда, когда температура внутри достигает 40°С. Влажность воздуха при этом резко падает, растения начинают испытывать засуху. И что происходит дальше? Еще хуже – двери и форточки резко открывают, и образовавшийся сквозняк уносит остатки и так не достающей влаги. Просто-таки как в пустыне! Молодые побеги от этого теряют тургор – давление внутри клеток, вянут, а цветы и завязи и вовсе отпадают. А вот вредители, особенно паутинный клещ, от жары и сухости начинают чувствовать себя как раз хорошо. Вечером растения, конечно же, начнут приходить в себя. Но в итоге, собирая урожай, вы не сможете не отметить, насколько он меньше и хуже того, что у соседа с частично или полностью автоматической теплицей. То есть задача «умной» теплицы – это максимально поддерживать комфортный климатический режим для растений в теплице: влажность, температуру, насыщенность кислородом и влагой.



У нас очень короткое лето и изменчивая погода. Чтобы вырастить на даче огурцы, помидоры, перец необходима теплица. Но в теплице, если на улице тепло нужно открыть форточки, если холодно – закрыть. Определенные промежутки между поливами. Для тех людей, которые могут приехать на дачу только на выходных, мой проект значительно облегчит жизнь и поможет собрать хороший урожай.

В моем проекте я написал скетч на языке программирования C++ для автоматизации теплице на базе Arduino Mega. Теплица управляется с дисплея всего четырьмя кнопками: «ввод», «вверх», «вниз», «выход». И плюс три кнопки управления

  1. подсветка экрана

  2. набор воды

  3. полив

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

  1. полив

  2. подогрев почвы

  3. управление форточками.


























Практическая часть.


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


Платформа состоит из двух частей: аппаратной и программной.



Аппаратная часть

1)Микроконтроллер Arduino Mega 2560.

2) Датчик температуры почвы DS18B20.

3) Датчик температуры и влажности воздуха.

4) Датчик открывания и закрывания форточек и дверей.

5) Датчик влажности почвы .

6) Исполнительное устройство- приводы открывания/закрывания дверей, электромагнитные клапаны и насос подачи воды.

7)Источники питания.

8)Дисплей для отображения информации.

9) Другое (корпус электрич щитка, светодиоды, резисторы и т.п.).



Программная часть

Программная часть Arduino состоит из бесплатной программной оболочки для написания программ, их компиляции и программирования аппаратуры.

Для программирования используется язык С++ с дополнительными библиотеками. Язык программирования С++ я изучал прошлым летом в Югорском Физико-Математическом Лицее. Этот язык широко используется в профессиональных автоматизированных системах управления производственным процессом. Например, на работе у моего отца для автоматизированного процесса слива/налива газового конденсата.

Программа, написанная на языке С++ загружается с компьютера в память контроллера через USB порт.

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







Принцип работы прибора.

На дисплее отображается в 1 окне - показания датчиков, а также режимы полива, подогрева, открывания-закрывания форточек.

В 2 окне происходит установка следующих значений:

1. Время полива.

2. Время второго полива (если включен режим полива 2 раза в день).

3. Время набора воды.

4. Температура открытия/закрытия форточек.

5. Температура включения/ отключения обогрева почвы.

6. Температура включения/ отключения обогрева воздуха.

7. Температура обогрева воздуха.

8. Предельное время работы мотора открывания окна 1.

9. Предельное время работы мотора открывания окна 2.

10. Предельное время работы мотора закрывания окна 1.

11. Предельное время работы мотора закрывания окна 2.

12. Предельное время работы насоса.

15. Время работы насоса для запуска полива.

Прибор снимает показания температуры воздуха и почвы с соответствующих датчиков.

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

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

5.Подогрев почвы и воздуха 593-643

Процедура набора воды 662-692

получения данных с датчика температуры и влажности воздуха 694-798



При превышении установленной температуры почвы происходит отключение подогрева почвы.

  • При понижении установленной температура почвы происходит включение подогрева почвы.

Прибор снимает показания с датчика влажности почвы.

  • В установленном времени полива и при понижении влажности почвы ниже установленного значения - происходит полив растений

Для полива установлено два таймера-основной и дополнительный.

Например, основной запрограммирован на 19-00, дополнительный на 21-00,

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

Программа полива и набора воды находится на строках кода 406-516



Для сборки данного проекта необходимо:


  1. Схема подключения датчиков Приложение 1;

  2. Программа для управления микроконтроллером Arduino Mega 2560 Приложение 2;


Заключение.

Мой проект на Arduino имеет следующие преимущества:

  1. В отличии от пневмоподъемников, которые быстро изнашиваются, я использую автомобильные стеклоподъемники, которые дешевле и надежнее.

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

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

  4. Все эти системы раздельно. Преимущество моего проекта в том, что я собрал все эти устройства в одно и улучшил их работу.

  5. В ближайшем будущем я также планирую создать сайт, с которого будет возможность наблюдения и изменения параметров

Стоимость моего проекта составляет 5000рублей, что гораздо дешевле других систем.

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



























Список использованной литературы.

  1. Интернет-гипермаркет Aliеxpress.

  2. Сайт Arduino.ru

  3. Виктор Петин, Александр Биняковский Практическая энциклопедия Arduino- ДМК Пресс, 2017

  4. Джереми Блум. Изучаем Arduino- БХВ-Петербург, 2015

  5. Уилли Соммер. Программирование Микроконтроллерных плат Arduino/Freeduino, 2012

  6. Виктор Петин. Проекты с использованием контроллера Arduino, 2-е издание-  БХВ-Петербург, 2015

  7. ARDUINO Быстрый старт. Первые шаги по освоению Arduino, 2015


П риложение 1



Приложение 2

  1. #include // Библиотека шины

  2. #include // Библиотека дисплея

  3. #include // Библиотека датчика температуры и влажности воздуха

  4. #include // Библиотека датчика температуры почвы

  5. #include "DS1307RTC.h" // Библиотека часов реального времени

  6. #include

  7. #include // Библиотека памяти

  8. LiquidCrystal_I2C lcd(0x3f,20,4); // Установка адреса и размерности дисплея

  9. float VlazhnVozd; //ser int на float // Переменная влажности воздуха

  10. float TempVozd; //ser int на float // Переменная температуры воздуха

  11. int VlazhPoch = 0; // влажность почвы

  12. //dht11 DHT; // переменная типа DHT для датчика температуры и влажности воздуха

  13. int chk; // Переменная проверки датчика температуры и влажности воздуха

  14. byte i; // для датчика температуры почвы

  15. byte DataVozd[12]; // Данные для датчика температуры почвы

  16. //byte AddrVozd[8] = {0x28, 0xFF, 0x63, 0xC1, 0x74, 0x16, 0x4, 0xF7}; // Адрес для датчика температуры почвы

  17. //byte AddrVozd[8] = {0x28, 0xFF, 0x32, 0xD1, 0x64, 0x15, 0x1, 0xB7}; // Адрес для датчика температуры почвы

  18. int TempPochv; // Переменная температуры почвы

  19. char weekDay[][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

  20. int FlagNaborVoda = 0; // Флажок, определяющий, что вода в этот час уже набиралась

  21. int FlagPoliva = 0; // Флажок, определяющий, что полив в этот час уже был

  22. unsigned long Vremya = 0; // Переменная для определения времени подсветки дисплея

  23. int MotorTest = 0; // Переменная для включения теста моторов

  24. int Konts; // переменная для определения концевика

  25. int Sett = 0; // Включаем нумерацию настроечных параметров

  26. int nz = 0; // Переменная отсчета задержек для меню.

  27. int memread = 0; // Ключ для чтения данных из EEPROM

  28. int KluchPauza = 0; // Ключ для паузы

  29. int NParam; // Переменная для выбора параметра по времени работы моторов

  30. double izmer [20]; // массив для получения данных с аналогового датчика температуры воздуха

  31. double temp; // Временная переменная для сортировки данных с аналогового датчика температуры воздуха

  32. double temperatura; // Значение температуры с аналогового датчика температуры воздуха

  33. int temperatura_out; // округленное значение температуры аналогового датчика температуры воздуха

  34. double Volt; // Напряжение на выходе (для настройки) с аналогового датчика температуры воздуха

  35. const int KolNactr = 15; // Количество элементов массивов настроек

      1. // (количество настраиваемых параметров)

  36. int Parametr[KolNactr]; // Массив для значений параметров настроек

  37. /*

  38. """Настройки"""

    1. длительность набора воды в поливочный бак (сек.)

    2. час, в который надо включить набор воды (часов)

    3. длительность набора воды в поливочный бак, достаточное, чтобы вода перелилась и начался полив (сек.)

    4. час, в который надо поливать (часов)

    5. час, в который надо поливать второй раз (часов) - не менее, чем через 2 часа после первого полива!

    6. время открытия окна по тылу (секунд)

    7. время закрытия окна по тылу (секунд)

    8. время открытия окна по фасаду (секунд)

    9. время закрытия окна по фасаду (секунд)

    10. температура открытия окон (градусов)

  39. 10.температура закрытия окон (градусов)

  40. 11.температура включения подогрева почвы (градусов)

  41. 12.температура отключения подогрева почвы (градусов)

  42. 13.температура включения подогрева воздуха (градусов)

  43. 14.температура отключения подогрева воздуха (градусов)

  44. */

  45. // Массив названий параметров, названия можно писать свои в количестве, указанном выше,

  46. // длиной до 10 символов включительно. Язык английский.

  47. String NameParametr[KolNactr] =

  48. {

  49. "VremNabora",

  50. "ChasNabora",

  51. "VremPoliva",

  52. "ChasPoliva",

  53. "ChPoliva_2",

  54. "VrOtkrTyla",

  55. "VrZakrTyla",

  56. "VrOtkFasad",

  57. "VrZakFasad",

  58. "T_OtkrOkon",

  59. "T_ZakrOkon",

  60. "T_Pochv_on",

  61. "T_Poch_off",

  62. "T_Vozd_ on",

  63. "T_Vozd_off"

  64. };

  65. // Массив для настроек часов:

  66. String NameClockSet[] =

  67. {

  68. "year: ",

  69. "month: ",

  70. "date: ",

  71. "day of week:",

  72. "hour: ",

  73. "minute: "

  74. };

  75. // """Переменные для пинов"

  76. OneWire ds(2); // Устанока пина 2 для датчика температуры почвы

  77. #define DHT_PIN 3 // Установка пина 3 для датчика температуры и влажности воздуха

  78. #define DHTTYPE DHT22

  79. int const MotorTyl_1 = 4; // номер пина мотора открывания форточки тыла 1

  80. int const MotorTyl_2 = 5; // номер пина мотора открывания форточки тыла 2

  81. int const MotorFas_1 = 6; // номер пина мотора открывания форточки фасада 1

  82. int const MotorFas_2 = 7; // номер пина мотора открывания форточки фасада 2

  83. int const Left = 8; // Кнопка настроек влево

  84. int const Esc = 9; // Кнопка настроек выход

  85. int const Enter = 10; // Кнопка настроек ввод

  86. int const Right = 11; // Кнопка настроек вправо

  87. int const KontsTylOtkr = 22; // номер пина концевого выключателя открывания форточки тыла

  88. int const KontsTylZakr = 24; // номер пина концевого выключателя закрывания форточки тыла

  89. int const SensorVoda = 26; // номер пина сенсора уровня воды в поливочном баке

  90. int const KontsFasOtkr = 28; // номер пина концевого выключателя открывания форточки фасада

  91. int const KontsFasZakr = 30; // номер пина концевого выключателя закрывания форточки фасада

  92. int const OtklObogr = 32; // номер пина ручного выключателя автоматического обогрева (теплого пола и обогревателя воздуха)

  93. int const OtkrOkon = 34; // номер пина ручного выключателя ОТКРЫТИЯ окон и отключения автоматического управления окнами

  94. int const ZakrOkon = 36; // номер пина ручного выключателя ЗАКРЫТИЯ окон и отключения автоматического управления окнами

  95. int const KnopkaNabor = 38; // номер пина для кнопки ручного набора воды в поливочный бак

  96. int const KnopkaPoliv = 40; // номер пина кнопки включения полива

  97. int const Poliv_x2 = 42; // номер пина переключателя полива (1 или 2 раза)

  98. int const Podsvetka = 44; // номер пина кнопки включения подсветки дисплея

  99. int const Rele_1 = 46; // номер пина реле №1

  100. int const ReleNasos_2 = 48; // номер пина реле №2 включения насоса

  101. int const ReleTeplPol_3 = 50; // номер пина реле №3 включения теплого пола

  102. int const ReleObogr_4= 52; // номер пина реле №4 включения обогревателя воздуха

  103. int const VlazhPochPin = 14; // пин датчика влажности почвы

  104. int const Temper_A = 13; // Пин аналогового датчика температуры LM235Z //ser DS18b20

  105. int FuncOkon (int Motor) // Функция управления моторами

  106. {

  107. if (Motor==MotorTyl_1)

  108. {

  109. Konts=KontsTylOtkr; // Задаем какой концевик должен сработать

  110. NParam = Parametr[5]; // Время открытия окна тыла

  111. }

  112. if (Motor==MotorTyl_2)

  113. {

  114. Konts=KontsTylZakr;

  115. NParam = Parametr[6]; // Время закрытия окна тыла

  116. }

  117. if (Motor==MotorFas_1)

  118. {

  119. Konts=KontsFasOtkr;

  120. NParam = Parametr[7]; // Время открытия окна фасада

  121. }

  122. if (Motor==MotorFas_2)

  123. {

  124. Konts=KontsFasZakr;

  125. NParam = Parametr[7]; // Время закрытия окна фасада

  126. }

  127. digitalWrite(Motor,0);

  128. Serial.print("Motor ");

  129. Serial.println(Motor);

  130. int n = 0;

  131. while ( n

  132. {

  133. //Serial.println(Konts);

  134. delay (100);

  135. ++n;

  136. if (digitalRead (Konts) == 1) // Если концевик сработал

  137. {

  138. digitalWrite(Motor,1); // Останавливаем мотор

  139. break;

  140. }

  141. }

  142. digitalWrite(Motor,1); // Останавливаем мотор

  143. }

  144. DHT dht(DHT_PIN, DHTTYPE); //ser перенесено из setup

  145. void setup() {

  146. Wire.begin();

  147. //rtc.begin();

  148. Serial.begin(9600);

  149. dht.begin(); //ser добавлено

  150. // """НАЗНАЧЕНИЕ ПИНОВ"""

  151. pinMode (MotorTyl_1, OUTPUT); // пин мотора открывания форточки тыла 1 - выход

  152. pinMode (MotorTyl_2, OUTPUT); // пин мотора открывания форточки тыла 2 - выход

  153. pinMode (MotorFas_1, OUTPUT); // пин мотора открывания форточки фасада 1 - выход

  154. pinMode (MotorFas_2, OUTPUT); // пин мотора открывания форточки фасада 2 - выход

  155. pinMode (Left, INPUT); // Кнопка настроек влево

  156. pinMode (Esc, INPUT); // Кнопка настроек выход

  157. pinMode (Enter, INPUT); // Кнопка настроек ввод

  158. pinMode (Right, INPUT); // Кнопка настроек вправо

  159. pinMode (KontsTylOtkr, INPUT); // пин концевого выключателя открывания форточки тыла - вход

  160. pinMode (KontsTylZakr, INPUT); // пин концевого выключателя закрывания форточки тыла - вход

  161. pinMode (SensorVoda, INPUT); // пин сенсора уровня воды в поливочном баке - вход

  162. pinMode (KontsFasOtkr, INPUT); // пин концевого выключателя открывания форточки фасада - вход

  163. pinMode (KontsFasZakr, INPUT); // пин концевого выключателя закрывания форточки фасада - вход

  164. pinMode (OtklObogr, INPUT); // пин ручного выключателя автоматического обогрева (теплого пола и обогревателя воздуха) - вход

  165. pinMode (OtkrOkon, INPUT);// пин ручного выключателя ОТКРЫТИЯ окон и отключения автоматичес управления окнами - вход

  166. pinMode (ZakrOkon, INPUT); // пин ручного выключателя ЗАКРЫТИЯ окон и отключения автоматическ управления окнами - вход

  167. pinMode (KnopkaNabor, INPUT); // пин для кнопки ручного набора воды в поливочный бак - вход

  168. pinMode (KnopkaPoliv, INPUT); // пин кнопки включения полива - вход

  169. pinMode (Poliv_x2, INPUT); // пин переключателя полива (1 или 2 раза) - вход

  170. pinMode (Podsvetka, INPUT); // пин кнопки включения подсветки дисплея - вход

  171. pinMode (Rele_1, OUTPUT); // пин реле №1 - выход

  172. pinMode (ReleNasos_2, OUTPUT); // пин реле №2 включения насоса - выход

  173. pinMode (ReleTeplPol_3, OUTPUT); // пин реле №3 включения теплого пола - выход

  174. pinMode (ReleObogr_4, OUTPUT); // пин реле №4 включения обогревателя воздуха - выход

  175. digitalWrite (Rele_1,1); // Резервное реле отключено

  176. digitalWrite (ReleNasos_2,1); // Насос отключен

  177. digitalWrite (ReleTeplPol_3,1); // Подогрев почвы отключен

  178. digitalWrite (ReleObogr_4,1); // Обогреватель воздуха отключен

  179. digitalWrite (MotorTyl_1, 1); // Пины управления моторами отключены

  180. digitalWrite (MotorTyl_2, 1);

  181. digitalWrite (MotorFas_1, 1);

  182. digitalWrite (MotorFas_2, 1);

  183. // """ДИСПЛЕЙ"""

  184. lcd.begin();

  185. //удалил lcd.init(); //ser // Инициализация дисплея

  186. lcd.backlight(); // Подсветка дисплея

  187. // данные самодельных символов для дисплея:

  188. byte lcd_ch[8] = {0x00,0x00,0x11,0x11,0x0F,0x01,0x01,0x00};

  189. byte lcd_z[8] = {0x00,0x00,0x0E,0x11,0x06,0x11,0x0E,0x00};

  190. byte lcd_d[8] = {0x00,0x00,0x06,0x0A,0x0A,0x0A,0x1F,0x00};

  191. byte lcd_v[8] = {0x00,0x00,0x1E,0x11,0x1E,0x11,0x1E,0x00};

  192. byte lcd_gradus[8] = {0x00,0x10,0x06,0x09,0x08,0x09,0x06,0x00};

  193. byte lcd_l[8] = {0x00,0x00,0x07,0x09,0x09,0x09,0x19,0x00};

  194. byte lcd_g[8] = {0x00,0x00,0x15,0x15,0x0E,0x15,0x15,0x00};

  195. byte lcd_p[8] = {0x1F,0x11,0x11,0x11,0x11,0x11,0x11,0x00};

  196. // Создание самодельных символов для дисплея

  197. lcd.createChar(0, lcd_ch); // буква ч

  198. lcd.createChar(1, lcd_z); // буква з

  199. lcd.createChar(2, lcd_d); // буква д

  200. lcd.createChar(3, lcd_v); // буква в

  201. lcd.createChar(4, lcd_gradus); // градус

  202. lcd.createChar(5, lcd_l); // буква л

  203. lcd.createChar(6, lcd_g); // буква ж

  204. lcd.createChar(7, lcd_p); // буква п

  205. }

  206. void loop()

  207. {

  208. if (KluchPauza == 0) // Пауза перед запуском программы

  209. {

  210. Serial.println("pause");

  211. delay (3000);

  212. KluchPauza = 1;

  213. }

  214. /* //ser не читаем данные из памяти

  215. if (memread == 0) // Один раз считываем данные настроек из памяти и выводим неизменяемые символы на дисплей

  216. {

  217. Serial.println("memread");

  218. for (int i = 0; i Цикл считывания данных из EEPROM

  219. {

  220. Parametr[i] = EEPROM.read(i);

  221. }

  222. memread = 1;

  223. */

  224. /*

  225. // Выводим на дисплей неизменяемые символы.

  226. lcd.setCursor(0, 0);

  227. lcd.print("Bo");

  228. lcd.write(byte(1));

  229. lcd.write(byte(2));

  230. lcd.print("yx:");

  231. lcd.setCursor(0, 1);

  232. lcd.print("t=");

  233. lcd.setCursor(4, 1);

  234. lcd.write(byte(4));

  235. lcd.setCursor(6, 1);

  236. lcd.write(byte(3));

  237. lcd.write(byte(5));

  238. lcd.print("a");

  239. lcd.write(byte(6));

  240. lcd.print(".=");

  241. lcd.setCursor(15, 1);

  242. lcd.print("%");

  243. lcd.setCursor(0, 2);

  244. lcd.write(byte(7));

  245. lcd.print("o");

  246. lcd.write(byte(0));

  247. lcd.write(byte(3));

  248. lcd.print("a:");

  249. lcd.setCursor(13, 2);

  250. lcd.write(byte(7));

  251. lcd.print("o");

  252. lcd.write(byte(2));

  253. lcd.print(":");

  254. lcd.setCursor(0, 3);

  255. lcd.print("t=");

  256. lcd.setCursor(4, 3);

  257. lcd.write(byte(4));

  258. lcd.setCursor(6, 3);

  259. lcd.write(byte(3));

  260. lcd.write(byte(5));

  261. lcd.print("a");

  262. lcd.write(byte(6));

  263. lcd.print(".=");

  264. lcd.setCursor(15, 3);

  265. lcd.print("%");

  266. }

  267. */

  268. if (digitalRead(Enter) == 1) // Если кнопка ввода нажата

  269. {

  270. Nastroyka(); // Переходим в меню настройки

  271. }

  272. DatchikVozd (); // Работаем с цифровым датчиком температуры и влажности воздуха

  273. //ser нет такого датчика DatchikVozdAnalog(); // Работаем с аналоговым датчиком температуры и влажности воздуха

  274. /* //ser переключение между аналог.ицифр датчиками пока не нужны

  275. if (TempVozd==99) // Если цифровой датчик температуры завис, используем данные с резервного аналогового

  276. {

  277. lcd.setCursor(2, 1); // Выводим на дисплей, что работаем на резервном аналоговом датчике

  278. lcd.print("!!");

  279. TempVozd = temperatura_out;

  280. lcd.setCursor(17, 1); // Выводим на дисплей, что работаем на резервном аналоговом датчике

  281. lcd.print("A");

  282. }

  283. else

  284. {

  285. lcd.setCursor(2,1);

  286. lcd.print(TempVozd);

  287. lcd.setCursor(17, 1); // Выводим на дисплей, что работаем на цифровом датчике

  288. lcd.print("D");

  289. }

  290. */

  291. DatchikPoch (); // Работаем с датчиками температуры и влажности почвы

  292. tmElements_t tm;

  293. RTC.read(tm); //ser точка с запятой

  294. //DateTime now = rtc.now(); // получение даты - времени

  295. int timehour = tm.Hour; // Переменная для считывания времени (часы)

  296. int timemin = tm.Minute; // Переменная для считывания времени (минуты)

  297. lcd.setCursor(14,0); // Начинаем выводить данные на дисплей

  298. if (timehour

  299. {

  300. lcd.print("0");

  301. lcd.print(timehour);

  302. Serial.print("0"); //ser

  303. Serial.print(timehour); //ser

  304. }

  305. else

  306. {

  307. lcd.print(timehour);

  308. Serial.print(timehour); //ser

  309. }

  310. lcd.print(":");

  311. Serial.print(":"); //ser

  312. lcd.setCursor(17,0);

  313. if (timemin

  314. {

  315. lcd.print("0");

  316. Serial.print("0"); //ser

  317. lcd.print(timemin);

  318. Serial.println(timemin); //ser

  319. }

  320. else

  321. {

  322. lcd.print(timemin);

  323. Serial.println(timemin); //ser

  324. }

  325. lcd.setCursor(1,0);

  326. lcd.print("Pochva:");

  327. lcd.setCursor(1,1);

  328. lcd.print("t="+String(TempPochv)+"C");

  329. lcd.setCursor(10,1);

  330. lcd.print("vl="+String(VlazhPoch));

  331. lcd.setCursor(1,2);

  332. lcd.print("Vozduh:");

  333. lcd.setCursor(1,3);

  334. lcd.print("t="+String(TempVozd)+"C");

  335. lcd.setCursor(10,3);

  336. lcd.print("vl="+String(VlazhnVozd));

  337. // lcd.setCursor(18,1);

  338. // lcd.print(temperatura_out); //Вывели данные на дисплей

  339. // ***Управление насосом:***

  340. // 1. Набор воды (возможен только при неполном баке):

  341. // 1.1 Вручную:

  342. // 1.1.1 Набор воды вручную:

  343. // Serial.println("1.1.1");

  344. if (digitalRead(SensorVoda)==0 && digitalRead(KnopkaNabor)==1) // Если бак неполон и кнопка набора воды нажата

  345. {

  346. Serial.println("Nabor voda ruchn");

  347. NaborVoda (); // Процедура набора воды

  348. }

  349. // 1.2 Автоматически (по времени):

  350. // Serial.println("1.2");

  351. if (FlagNaborVoda == 0 && digitalRead (SensorVoda) == 0)

  352. {

  353. if (timehour == Parametr[1])

  354. {

  355. Serial.println("Nabor voda auto");

  356. NaborVoda (); // Процедура набора воды

  357. FlagNaborVoda = 1; // Ставим флажок, что воду больше пока набирать не надо

  358. }

  359. }

  360. if (timehour == (Parametr[1] + 1))

  361. {

  362. FlagNaborVoda = 0; // Прошло время, можно набирать снова

  363. }

  364. Serial.print("Flag nabor Voda ");

  365. Serial.println(FlagNaborVoda);

  366. // 2.Полив

  367. // Serial.println("2");

  368. if (timehour == Parametr[3] && FlagPoliva == 0)

  369. {

  370. Poliv (); // Процедура полива

  371. FlagPoliva = 1; // Установим флажок, что больше пока поливать не надо

  372. }

  373. // 2.1 Полив вручную:

  374. // Serial.println("2.1");

  375. if (digitalRead (SensorVoda) == 1 && digitalRead (KnopkaPoliv) == 1) // Если бак полон и кнопка полива нажата

  376. {

  377. //Serial.println (digitalRead(SensorVoda));

  378. //Serial.println (digitalRead(KnopkaPoliv));

  379. Poliv (); // Процедура полива

  380. }

  381. if (timehour == (Parametr[3] + 1))

  382. {

  383. FlagPoliva = 0; // Можно опять поливать

  384. }

  385. // 3. Двойной полив:

  386. // Serial.println("3");

  387. // 3.1 Набираем воду:

  388. // Serial.println("3.1");

  389. if (digitalRead (Poliv_x2) == 1 && timehour == (Parametr[3] + 1))

  390. {

  391. if (FlagNaborVoda == 0 && digitalRead (SensorVoda) == 0)

  392. {

  393. NaborVoda (); // Процедура набора воды

  394. FlagNaborVoda = 1; // Ставим флажок, что воду больше пока набирать не надо

  395. }

  396. }

  397. if (timehour == (Parametr[3] + 2))

  398. {

  399. FlagNaborVoda = 0; // Прошло время, можно набирать снова

  400. }

  401. // 3.2 Поливаем:

  402. // Serial.println("3.2");

  403. if (timehour == Parametr[4] && FlagPoliva == 0)

  404. {

  405. Poliv (); // Процедура полива

  406. FlagPoliva = 1; // Установим флажок, что больше пока поливать не надо

  407. }

  408. if (timehour == (Parametr[4] + 1))

  409. {

  410. FlagPoliva = 0; // Можно опять поливать

  411. }

  412. // 4. Форточки:

  413. // 4.1 Автоматическое открытие - закрытие:

  414. // Serial.println("4.1");

  415. if (digitalRead(OtkrOkon) == 0 && digitalRead(ZakrOkon) == 0) // Если отключено ручное открытие-закрытие окон

  416. {

  417. lcd.setCursor(10,0); // установка курсора

  418. lcd.print("A");

  419. if (TempVozd = Parametr[9] && digitalRead(KontsTylOtkr) == 0)

  420. {

  421. FuncOkon(MotorTyl_1);

  422. }

  423. if (TempVozd = Parametr[9] && digitalRead(KontsFasOtkr) == 0)

  424. {

  425. FuncOkon(MotorFas_1);

  426. }

  427. if (TempVozd

  428. {

  429. FuncOkon(MotorTyl_2);

  430. }

  431. if (TempVozd

  432. {

  433. FuncOkon(MotorFas_2);

  434. }

  435. }

  436. // 4.2 Ручное открытие окон и отключение автоматического открытия-закрытия:

  437. // Serial.println("4.2");

  438. if (digitalRead(OtkrOkon) == 1) // Если включено ручное открытие окон

  439. {

  440. lcd.setCursor(10,0); // установка курсора

  441. lcd.print("P");

  442. if (digitalRead(KontsTylOtkr) == 0)

  443. {

  444. FuncOkon(MotorTyl_1);

  445. }

  446. if (digitalRead(KontsFasOtkr) == 0)

  447. {

  448. FuncOkon(MotorFas_1);

  449. }

  450. }

  451. if (digitalRead(ZakrOkon) == 1) // Если включено ручное закрытие окон

  452. {

  453. lcd.setCursor(10,0); // установка курсора

  454. lcd.print("P");

  455. if (digitalRead(KontsTylZakr) == 0)

  456. {

  457. FuncOkon(MotorTyl_2);

  458. }

  459. if (digitalRead(KontsFasZakr) == 0)

  460. {

  461. FuncOkon(MotorFas_2);

  462. }

  463. }

  464. // 5.Подогрев почвы и воздуха:

  465. // Serial.println("5");

  466. if ( digitalRead (OtklObogr) == 1 ) // Если автоматика отключена

  467. {

  468. digitalWrite (ReleTeplPol_3, 1); // Выключаем реле теплого пола

  469. digitalWrite (ReleObogr_4, 1); // Выключаем реле обогревателя воздуха

  470. lcd.setCursor(10,2); // Отображаем Р на дисплее, символизируещее ручное управление, отключение автоматики

  471. lcd.print("P");

  472. lcd.setCursor(17,2); // Отображаем на дисплее отключение подогрева пола

  473. lcd.print("OFF");

  474. }

  475. else // Если автоматика не отключена

  476. {

  477. lcd.setCursor(10,2); // Отображаем А на дисплее

  478. lcd.print("A");

  479. if ( TempPochv

  480. {

  481. digitalWrite (ReleTeplPol_3, 0); // Включаем реле теплого пола

  482. lcd.setCursor(17,2); // Отображаем это на дисплее

  483. lcd.print("ON ");

  484. }

  485. if ( TempPochv = Parametr[12] ) // Если температура почвы больше заданной

  486. {

  487. digitalWrite (ReleTeplPol_3, 1); // Выключаем реле теплого пола

  488. lcd.setCursor(17,2); // Отображаем это на дисплее

  489. lcd.print("OFF");

  490. }

  491. if ( TempVozd

  492. {

  493. digitalWrite (ReleObogr_4, 0); // Включаем реле обогревателя воздуха

  494. }

  495. if ( TempVozd = Parametr[14] ) // Если температура почвы больше заданной

  496. {

  497. digitalWrite (ReleObogr_4, 1); // Выключаем реле обогревателя воздуха

  498. }

  499. }

  500. // Кнопка включения подсветки дисплея

  501. if ( (millis() - Vremya) 15000 || millis()

  502. {

  503. lcd.noBacklight(); // Подсветка дисплея отключается

  504. }

  505. if ( digitalRead(Podsvetka) == 1)

  506. {

  507. lcd.backlight(); // Подсветка дисплея

  508. Vremya = millis();

  509. }

  510. }

  511. void NaborVoda () // Процедура набора воды

  512. {

  513. Serial.println("void NaborVoda");

  514. digitalWrite (ReleNasos_2,0); // Включаем насос

  515. int n = 0;

  516. while ( n

  517. {

  518. delay (1000);

  519. ++n;

  520. if (digitalRead (SensorVoda) == 1) // Если датчик уровня воды сработал

  521. {

  522. break;

  523. }

  524. }

  525. digitalWrite (ReleNasos_2,1); // Насос отключить

  526. }

  527. void Poliv () // Процедура полива

  528. {

  529. Serial.println("void Poliv");

  530. digitalWrite (ReleNasos_2,0); // Включаем насос

  531. delay (Parametr[2]*1000);

  532. digitalWrite (ReleNasos_2,1); // Насос отключить

  533. }

  534. void DatchikVozd () // Функция получения данных с датчика температуры и влажности воздуха

  535. {

  536. Serial.println("void DatchikVozd");

  537. // chk = DHT.read(DHT11_PIN); //ser // Считываем данные с датчика температуры и влажности воздуха


  1. // switch (chk) //ser // Проверка данных на ошибки. Если они есть, присваиваем значения 99.

  2. // {

  3. // case DHTLIB_OK: //ser

  4. // break; //ser

  5. // default: TempVozd = 99;

  6. // VlazhnVozd = 99;

  7. // break;

  8. // }

  9. // if (TempVozd != 99) //ser // Если с данными все в порядке, присваиваем переменным значения.

  10. // {

  11. //VlazhnVozd = DHT.humidity,1; //ser

  12. VlazhnVozd = dht.readHumidity();

  13. TempVozd = dht.readTemperature();

  14. //TempVozd = DHT.temperature,1; //ser

  15. Serial.println("VlazhnVozd = "+String(VlazhnVozd,1));

  16. //Serial.println(" void DatchikVozd ");

  17. Serial.println("TempVozd = "+String(TempVozd,1));

  18. Serial.println();

  19. // }

  20. if (TempVozd

  21. {

  22. digitalWrite (ReleTeplPol_3,0); // Подогрев почвы включен

  23. Serial.println("--Vkl podogrev--");

  24. // включение подогрева почвы

  25. }

  26. else

  27. {

  28. digitalWrite (ReleTeplPol_3,1); // Подогрев почвы отключен

  29. Serial.println("--Vikl podogrev--");

  30. }

  31. }

  32. /* //ser нет аналогового датчика температуры

  33. void DatchikVozdAnalog() // Функция получения даных с аналогового датчика температуры

  34. {

  35. for (int i=0; i

  36. {

  37. izmer[i]=analogRead(Temper_A);

  38. delay(100);

  39. }

  40. for (int j=19; j=0; j=j-1)

  41. {

  42. for (int i=0; i

  43. {

  44. if(izmer[i]izmer[i+1])

  45. {

  46. temp=izmer[i];

  47. izmer[i]=izmer[i+1];

  48. izmer[i+1]=temp;

  49. }

  50. }

  51. }

  52. temp=0;

  53. for (int i=2; i

  54. {

  55. temp=temp+izmer[i];

  56. }

  57. Serial.println(izmer[5]);

  58. temp=temp/16;

  59. Serial.println(temp);

  60. Volt=temp*5.2/1024; // Здесь 5,2 - опорное напряжение. Нужно реальное писать, тогда датик покажет правильно

  61. // Volt должно при 25 градусов быть около 2.98-3.00 вольта

  62. Serial.println(Volt);

  63. temperatura=Volt*100-273.15;

  64. temperatura_out=int(temperatura);

  65. if((temperatura-temperatura_out) = 0.5)

  66. {

  67. temperatura_out=temperatura_out+1;

  68. }

  69. Serial.print("T=");

  70. Serial.print(temperatura);

  71. Serial.print(" T_d=");

  72. Serial.println(temperatura_out);

  73. }*/

  74. void DatchikPoch () // Функция получения данных с датчика температуры почвы

  75. {

  76. Serial.print("void DatchikPoch = ");

  77. byte data[2];

  78. ds.reset();

  79. ds.write(0xCC);

  80. ds.write(0x44);

  81. delay(750);

  82. ds.reset();

  83. ds.write(0xCC);

  84. ds.write(0xBE);

  85. data[0] = ds.read();

  86. data[1] = ds.read();

  87. int Temp = (data[1]

  88. Temp = Temp4;

  89. TempPochv = Temp;

  90. Serial.println(TempPochv);

  91. //ser используется алгоритм выше

  92. /*

  93. byte present = 0;

  94. ds.reset(); // Очищаем датчик почвы

  95. ds.select(AddrVozd);

  96. ds.write(0x44, 1); // start conversion, with parasite power on at the end

  97. delay(1000); // maybe 750ms is enough, maybe not

  98. // we might do a ds.depower() here, but the reset will take care of it.

  99. present = ds.reset();

  100. ds.select(AddrVozd); // выбираем датчик почвы

  101. ds.write(0xBE); // Считываем данные с датчика почвы

  102. for ( i = 0; i

  103. {

  104. DataVozd[i] = ds.read();

  105. }

  106. int16_t raw = (DataVozd[1]

  107. raw = raw & ~7; // Определяем точность для температуры почвы 0,5 градусов

  108. Serial.println(raw);

  109. TempPochv = (int)raw / 16.0; // Пересчитываем в градусы Цельсия

  110. Serial.println(TempPochv);

  111. VlazhPoch = analogRead(VlazhPochPin); // считывание данных с датчика влажности почвы

  112. VlazhPoch = (1000-VlazhPoch)/8; // вычисление влажности почвы

  113. */

  114. }

  115. void Nastroyka() // Функция выбора меню на дисплее

  116. {

  117. lcd.backlight(); // Подсветка дисплея

  118. lcd.clear(); // Очистка дисплея

  119. while (nz

  120. {

  121. delay (200);

  122. ++nz;

  123. }

  124. int Kluch_5 = 1;

  125. int menu = 0;

  126. while (Kluch_5 = 1)

  127. {

  128. lcd.setCursor(0, 0);

  129. lcd.print("Set parametr");

  130. lcd.setCursor(0, 1);

  131. lcd.print("Set clock");

  132. lcd.setCursor(0, 3);

  133. lcd.print("Testmot.-butt.on top");

  134. delay (100);

  135. if (digitalRead(Esc) == 1) // Если нажата кнопка выхода из режима выбора настроек

  136. {

  137. lcd.clear(); // Очистка дисплея

  138. Kluch_5 = 0;

  139. nz = 0;

  140. memread = 0;

  141. break;

  142. }

  143. if (menu == 0)

  144. {

  145. lcd.setCursor(15, 0);

  146. lcd.print("

  147. lcd.setCursor(15, 1);

  148. lcd.print(" ");

  149. }

  150. else

  151. {

  152. lcd.setCursor(15, 1);

  153. lcd.print("

  154. lcd.setCursor(15, 0);

  155. lcd.print(" ");

  156. }

  157. if (digitalRead(Right) == 1) // Если кнопка вправо нажата

  158. {

  159. menu = 1;

  160. }

  161. if (digitalRead(Left) == 1) // Если кнопка влево нажата

  162. {

  163. menu = 0;

  164. }

  165. // ser

  166. /* if (digitalRead(Enter) == 1) // Если кнопка ввода нажата

  167. {

  168. if (menu == 1) // ser

  169. {

  170. Timeset ();

  171. }

  172. else

  173. {

  174. Nastr_Parametr ();

  175. }

  176. } */

  177. if (digitalRead(Podsvetka) == 1)

  178. {

  179. TestMotor();

  180. }

  181. }

  182. }

  183. /* // ser установка времени

  184. void Timeset () // Функция настройки часов

  185. {

  186. DateTime now = rtc.now(); //получение даты - времени

  187. int Setyear = now.year();

  188. int Setmonth = now.month();

  189. int Setdate = now.date();

  190. int SetdayOfWeek = now.dayOfWeek();

  191. int Sethour = now.hour();

  192. int Setmin = now.minute();

  193. lcd.clear(); // Очистка дисплея

  194. int Kluch_3 = 1; // Задаем значение, не позволяющее покинуть функцию без команды

  195. while (Kluch_3 == 1) // Цикл выбора параметра

  196. {

  197. lcd.setCursor(0, 0);

  198. lcd.print("Clock setting:");

  199. while (nz

  200. {

  201. delay (100);

  202. ++nz;

  203. }

  204. delay (100); // Ожидание - выполняется каждый раз

  205. if (digitalRead(Right) == 1) // Изменяем значение номера выбираемого параметра:

  206. {

  207. ++Sett; // увеличиваем

  208. }

  209. if (digitalRead(Left) == 1)

  210. {

  211. --Sett; // уменьшаем

  212. }

  213. if (Sett

  214. {

  215. Sett = 5;

  216. }

  217. if (Sett 5)

  218. {

  219. Sett = 0;

  220. }

  221. lcd.setCursor(0, 1); // Вывод на экран названия настройки

  222. lcd.print(NameClockSet[Sett]); // в соответствии с ее номером в массиве названий

  223. if (digitalRead(Esc) == 1) // Если нажата кнопка выхода из режима выбора настроек

  224. {

  225. lcd.clear(); // Очистка дисплея

  226. Kluch_3 = 0;

  227. memread = 0;

  228. break;

  229. }

  230. if (digitalRead(Enter) == 1) // Если нажата кнопка выбора настроечного параметра

  231. {

  232. int Kluch_4 = 1; // Задаем значение, не позволяющее покинуть цикл без команды

  233. nz = 0; // Обнуляем счетчик цикла ожидания

  234. while (Kluch_4 == 1) // Цикл выбора значения параметра

  235. {

  236. lcd.setCursor(12, 1);

  237. delay (100); // Ожидание, отвечает за скорость смены значений

  238. if (Sett == 0)

  239. {

  240. lcd.print(Setyear);

  241. if (digitalRead(Right) == 1) // Если кнопка вправо нажата, увеличиваем значение параметра

  242. {

  243. ++Setyear;

  244. if (Setyear 2030)

  245. {

  246. Setyear = 2016;

  247. }

  248. }

  249. if (digitalRead(Left) == 1) // То же для кнопки влево

  250. {

  251. --Setyear;

  252. if (Setyear

  253. {

  254. Setyear = 2030;

  255. }

  256. }

  257. }

  258. if (Sett == 1)

  259. {

  260. lcd.print(" ");

  261. if (Setmonth

  262. {

  263. lcd.print("0");

  264. }

  265. lcd.print(Setmonth);

  266. if (digitalRead(Right) == 1) // Если кнопка вправо нажата, увеличиваем значение параметра

  267. {

  268. ++Setmonth;

  269. if (Setmonth 12)

  270. {

  271. Setmonth = 1;

  272. }

  273. }

  274. if (digitalRead(Left) == 1) // То же для кнопки влево

  275. {

  276. --Setmonth;

  277. if (Setmonth

  278. {

  279. Setmonth = 12;

  280. }

  281. }

  282. }

  283. if (Sett == 2)

  284. {

  285. lcd.print(" ");

  286. if (Setdate

  287. {

  288. lcd.print("0");

  289. }

  290. lcd.print(Setdate);

  291. if (digitalRead(Right) == 1) // Если кнопка вправо нажата, увеличиваем значение параметра

  292. {

  293. ++Setdate;

  294. if (Setdate 31)

  295. {

  296. Setdate = 1;

  297. }

  298. }

  299. if (digitalRead(Left) == 1) // То же для кнопки влево

  300. {

  301. --Setdate;

  302. if (Setdate

  303. {

  304. Setdate = 31;

  305. }

  306. }

  307. }

  308. if (Sett == 3)

  309. {

  310. lcd.print(" ");

  311. lcd.print(weekDay[SetdayOfWeek]);

  312. if (digitalRead(Right) == 1) // Если кнопка вправо нажата, увеличиваем значение параметра

  313. {

  314. ++SetdayOfWeek;

  315. if (SetdayOfWeek 6)

  316. {

  317. SetdayOfWeek = 0;

  318. }

  319. }

  320. if (digitalRead(Left) == 1) // То же для кнопки влево

  321. {

  322. --SetdayOfWeek;

  323. if (SetdayOfWeek

  324. {

  325. SetdayOfWeek = 6;

  326. }

  327. }

  328. }

  329. if (Sett == 4)

  330. {

  331. lcd.print(" ");

  332. if (Sethour

  333. {

  334. lcd.print("0");

  335. }

  336. lcd.print(Sethour);

  337. if (digitalRead(Right) == 1) // Если кнопка вправо нажата, увеличиваем значение параметра

  338. {

  339. ++Sethour;

  340. if (Sethour 23)

  341. {

  342. Sethour = 0;

  343. }

  344. }

  345. if (digitalRead(Left) == 1) // То же для кнопки влево

  346. {

  347. --Sethour;

  348. if (Sethour

  349. {

  350. Sethour = 23;

  351. }

  352. }

  353. }

  354. if (Sett == 5)

  355. {

  356. lcd.print(" ");

  357. if (Setmin

  358. {

  359. lcd.print("0");

  360. }

  361. lcd.print(Setmin);

  362. if (digitalRead(Right) == 1) // Если кнопка вправо нажата, увеличиваем значение параметра

  363. {

  364. ++Setmin;

  365. if (Setmin 59)

  366. {

  367. Setmin = 0;

  368. }

  369. }

  370. if (digitalRead(Left) == 1) // То же для кнопки влево

  371. {

  372. --Setmin;

  373. if (Setmin

  374. {

  375. Setmin = 59;

  376. }

  377. }

  378. }

  379. while (nz

  380. {

  381. delay (100);

  382. ++nz;

  383. }

  384. delay (100); // Ожидание, отвечает за скорость смены значений

  385. if (digitalRead(Enter) == 1) // Если в этом режиме нажата кнопка Ввод,

  386. { // Производим установку часов

  387. DateTime dt(Setyear, Setmonth, Setdate, Sethour, Setmin, 0, SetdayOfWeek);

  388. rtc.setDateTime(dt);

  389. lcd.setCursor(11, 1);

  390. lcd.print("+"); // и выводим значок +, подтверждение сохранения

  391. }

  392. if (digitalRead(Esc) == 1) // Если нажата кнопка выхода, выходим в предыдущее меню

  393. { // выбора номера параметра,

  394. lcd.setCursor(12, 1);

  395. lcd.print(" "); // попутно стирая на дисплее значение.

  396. Kluch_4 = 0;

  397. nz = 0;

  398. continue;

  399. }

  400. }

  401. }

  402. delay (200);

  403. }

  404. }

  405. */ // ser установка времени

  406. void Nastr_Parametr () // Функция настройки параметров с кнопок и сохранения их в EEPROM

  407. {

  408. lcd.clear(); // Очистка дисплея

  409. int Kluch = 1; // Задаем значение, не позволяющее покинуть функцию без команды

  410. int nastr = 0; // Включаем нумерацию настроечных параметров

  411. int nastr_d = nastr+1;

  412. int nz = 0; // Счетчик для циклов ожидания, выполняющихся 1 раз

  413. while (Kluch = 1) // Цикл выбора параметра

  414. {

  415. while (nz

  416. {

  417. delay (100);

  418. ++nz;

  419. }

  420. delay (100); // Ожидание - выполняется каждый раз

  421. if (digitalRead(Right) == 1) // Изменяем значение номера выбираемого параметра:

  422. {

  423. ++nastr; // увеличиваем

  424. }

  425. if (digitalRead(Left) == 1)

  426. {

  427. --nastr; // уменьшаем

  428. }

  429. if (nastr

  430. {

  431. nastr = KolNactr - 1;

  432. }

  433. if (nastr KolNactr - 1)

  434. {

  435. nastr = 0;

  436. }

  437. nastr_d = nastr+1;

  438. if (nastr == KolNactr - 1)

  439. {

  440. nastr_d = 0;

  441. }

  442. lcd.setCursor(0, 0); // Вывод на экран названия настройки

  443. lcd.print(NameParametr[nastr]); // в соответствии с ее номером в массиве названий

  444. lcd.setCursor(10, 0);

  445. lcd.print("

  446. lcd.setCursor(0, 1);

  447. lcd.print(NameParametr[nastr_d]);

  448. lcd.setCursor(12, 0);

  449. if (Parametr[nastr]

  450. {

  451. lcd.print(" ");

  452. }

  453. if (Parametr[nastr] = 10 && Parametr[nastr]

  454. {

  455. lcd.print(" ");

  456. }

  457. lcd.print(Parametr[nastr]); // выводим значение сохраненного параметра

  458. lcd.setCursor(12, 1);

  459. if (Parametr[nastr_d]

  460. {

  461. lcd.print(" ");

  462. }

  463. if (Parametr[nastr_d] = 10 && Parametr[nastr_d]

  464. {

  465. lcd.print(" ");

  466. }

  467. lcd.print(Parametr[nastr_d]);

  468. if (digitalRead(Esc) == 1) // Если нажата кнопка выхода из режима выбора настроек

  469. {

  470. lcd.clear(); // Очистка дисплея

  471. Kluch = 0;

  472. nz = 0;

  473. break;

  474. }

  475. if (digitalRead(Enter) == 1) // Если нажата кнопка выбора настроечного параметра

  476. {

  477. int Kluch_2 = 1; // Задаем значение, не позволяющее покинуть цикл без команды

  478. nz = 0; // Обнуляем счетчик цикла ожидания

  479. lcd.setCursor(10, 0);

  480. lcd.print(" ");

  481. lcd.setCursor(15, 0);

  482. lcd.print("

  483. while (Kluch_2 == 1) // Цикл выбора значения параметра

  484. {

  485. lcd.setCursor(12, 0);

  486. if (Parametr[nastr]

  487. {

  488. lcd.print(" ");

  489. }

  490. if (Parametr[nastr] = 10 && Parametr[nastr]

  491. {

  492. lcd.print(" ");

  493. }

  494. lcd.print(Parametr[nastr]); // выводим значение сохраненного параметра

  495. while (nz

  496. {

  497. delay (100);

  498. ++nz;

  499. }

  500. delay (100); // Ожидание, отвечает за скорость смены значений

  501. if (digitalRead(Right) == 1) // Если кнопка вправо нажата, увеличиваем значение параметра

  502. {

  503. ++Parametr[nastr];

  504. }

  505. if (digitalRead(Left) == 1) // То же для кнопки влево

  506. {

  507. --Parametr[nastr];

  508. }

  509. if (Parametr[nastr]

  510. { // обусловленные возможностями ячейки памяти (256)

  511. Parametr[nastr] = 250;

  512. }

  513. if (Parametr[nastr] 250)

  514. {

  515. Parametr[nastr] = 1;

  516. }

  517. if (digitalRead(Enter) == 1) // Если в этом режиме нажата кнопка Ввод,

  518. { // сохраняем значение параметра в EEPROM

  519. EEPROM.write(nastr, Parametr[nastr]);

  520. lcd.setCursor(15, 0);

  521. lcd.print("+");

  522. delay (500);

  523. lcd.setCursor(15, 0);

  524. lcd.print(" "); // Стираем значок

  525. Kluch_2 = 0;

  526. nz = 0;

  527. memread = 0;

  528. continue;

  529. }

  530. if (digitalRead(Esc) == 1) // Если нажата кнопка выхода, выходим в предыдущее меню

  531. { // выбора номера параметра,

  532. lcd.setCursor(15, 0);

  533. lcd.print(" "); // попутно стирая на дисплее значок

  534. Kluch_2 = 0;

  535. nz = 0;

  536. continue;

  537. }

  538. }

  539. }

  540. delay (200);

  541. }

  542. }

  543. void Kontsevik () // Для отображения положения концевиков

  544. {

  545. lcd.setCursor(3, 3);

  546. lcd.print(digitalRead(KontsTylOtkr));

  547. lcd.setCursor(8, 3);

  548. lcd.print(digitalRead(KontsTylZakr));

  549. lcd.setCursor(13, 3);

  550. lcd.print(digitalRead(KontsFasOtkr));

  551. lcd.setCursor(18, 3);

  552. lcd.print(digitalRead(KontsFasZakr));

  553. }

  554. void TestMotor() // Тестовая программа для проверки и настройки моторов открывания окон

  555. {

  556. MotorTest = 1;

  557. lcd.clear(); // Очистка дисплея

  558. lcd.backlight(); // Подсветка дисплея

  559. lcd.setCursor(0, 0); // Вывод на дисплей неизменяемых символов:

  560. lcd.print("Motors test");

  561. lcd.setCursor(0, 1);

  562. lcd.print("Motors select:");

  563. lcd.setCursor(0, 2);

  564. lcd.print("Motors status:");

  565. lcd.setCursor(0, 3);

  566. lcd.print("TO:");

  567. lcd.setCursor(5, 3);

  568. lcd.print("TC:");

  569. lcd.setCursor(10, 3);

  570. lcd.print("FO:");

  571. lcd.setCursor(15, 3);

  572. lcd.print("FC:");

  573. delay(500);

  574. while ( MotorTest == 1)

  575. {

  576. lcd.setCursor(15, 1);

  577. lcd.print("OFF ");

  578. lcd.setCursor(15, 2);

  579. lcd.print("STOP ");

  580. Kontsevik ();

  581. if ((digitalRead(Left) == 1) && (digitalRead(KontsTylOtkr) == 0)) // Нажата кнопка 1 и концевик открыт

  582. {

  583. lcd.setCursor(15, 1);

  584. lcd.print("Tyl ");

  585. lcd.setCursor(15, 2);

  586. lcd.print("Open ");

  587. Kontsevik ();

  588. digitalWrite (MotorTyl_1, 0);

  589. while ((digitalRead(Left) == 1) && (digitalRead(KontsTylOtkr) == 0))

  590. {

  591. Kontsevik ();

  592. delay (100);

  593. }

  594. digitalWrite (MotorTyl_1, 1);

  595. }

  596. if ((digitalRead(Esc) == 1) && (digitalRead(KontsTylZakr) == 0)) // Нажата кнопка 2 и концевик открыт

  597. {

  598. lcd.setCursor(15, 1);

  599. lcd.print("Tyl ");

  600. lcd.setCursor(15, 2);

  601. lcd.print("Close");

  602. Kontsevik ();

  603. digitalWrite (MotorTyl_2, 0);

  604. while ((digitalRead(Esc) == 1) && (digitalRead(KontsTylZakr) == 0))

  605. {

  606. Kontsevik ();

  607. delay (100);

  608. }

  609. digitalWrite (MotorTyl_2, 1);

  610. }

  611. if ((digitalRead(Enter) == 1) && (digitalRead(KontsFasOtkr) == 0)) // Нажата кнопка 3 и концевик открыт

  612. {

  613. lcd.setCursor(15, 1);

  614. lcd.print("Fasad");

  615. lcd.setCursor(15, 2);

  616. lcd.print("Open ");

  617. Kontsevik ();

  618. digitalWrite (MotorFas_1, 0);

  619. while ((digitalRead(Enter) == 1) && (digitalRead(KontsFasOtkr) == 0))

  620. {

  621. Kontsevik ();

  622. delay (100);

  623. }

  624. digitalWrite (MotorFas_1, 1);

  625. }

  626. if ((digitalRead(Right) == 1) && (digitalRead(KontsFasZakr) == 0)) // Нажата кнопка 4 и концевик открыт

  627. {

  628. lcd.setCursor(15, 1);

  629. lcd.print("Fasad");

  630. lcd.setCursor(15, 2);

  631. lcd.print("Close");

  632. Kontsevik ();

  633. digitalWrite (MotorFas_2, 0);

  634. while ((digitalRead(Right) == 1) && (digitalRead(KontsFasZakr) == 0))

  635. {

  636. Kontsevik ();

  637. delay (100);

  638. }

  639. digitalWrite (MotorFas_2, 1);

  640. }

  641. if (digitalRead(Podsvetka) == 1) // Нажата кнопка подсветки

  642. {

  643. delay (2000);

  644. if (digitalRead(Podsvetka) == 1) // Все еще нажата кнопка подсветки

  645. {

  646. MotorTest = 0;

  647. lcd.clear(); // Очистка дисплея

  648. delay(1000);

  649. break;

  650. }

  651. break;

  652. }

  653. }

  654. delay (500);

  655. }
























Скачать

Рекомендуем курсы ПК и ППК для учителей

Вебинар для учителей

Свидетельство об участии БЕСПЛАТНО!