Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Раствор для полива городских растений

Компоненты и расходные материалы

Датчик влажности почвы
Можно использовать любой датчик влажности почвы с аналоговым выходом. Также можно использовать два электрода и делитель напряжения. ЭТО НЕОБЯЗАТЕЛЬНО.
× 2
Датчик дождя
× 1
кувшин для молока
Подойдет любой контейнер, который может удерживать воду, разрезаться и прикрепляться к поверхности. быть установлен на возвышении.
× 1
Мягкая пластиковая гибкая полая трубка
Подойдут трубки любого типа. Я использовал скакалку с обрезанными концами, так как она очень гибкая, а центр полый.
× 1
Перемычки (общие)
Более или менее.
× 37
SparkFun Inventor's Kit для Arduino 101
Я использовал Arduino 101, сервопривод, макет, потенциометр и ЖК-дисплей.
× 1
Глина для моделирования
× 1
Короткий пластиковый стержень
Или любой негибкий стержень. Он используется для поддержки выпускной трубы резервуара для воды.
× 1
Резистор 330 Ом
× 1

Необходимые инструменты и машины

Ножницы
крестовая отвертка
Изолента
, а также обычная лента.

Приложения и онлайн-сервисы

Nordic Semiconductor nRF Connect SDK
IDE Arduino

Об этом проекте

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

В его основе лежат следующие концепции:

Гравитация и давление

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

Кувшин наполняется в основном из бытовой воды (из-за того, что дождь не всегда бывает), но дополняется дождевой водой. Когда в кувшине присутствует вода, сила притяжения притягивает воду к Земле внутри кувшина. В основании кувшина вырезается отверстие, позволяющее вставить выходную трубу. Таким образом, сила тяжести тянет воду через эту выпускную трубу. Сервопривод регулирует, когда вода полностью выходит из трубы. В нормальных условиях сервомеханизм находится в вертикальном положении, что предотвращает вытекание воды из трубы. Однако при поливе растения рукава опускается на 135 градусов, позволяя воде вытекать из трубы и орошать растения. Когда это будет сделано, рука снова поднимется вверх.

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

Датчик температуры TMP36 и механизм сопоставления с образцом Intel-Кюри

Такое сочетание концепций помогает вести расчет, определяющий оптимальное время для полива растений. TMP36 - это датчик температуры, который работает как термометр, но с электронным аналоговым выходом. Этот выходной сигнал может быть прочитан устройством, например микроконтроллером, и преобразован в температуру. В этом проекте устройство пытается рассчитать оптимальное время полива растений, которое максимально приближено к 25 градусам Цельсия. Он делает 30 записей в час с интервалом в две минуты и в конце каждого периода вычисляет среднее значение из 29 записей (исключая первую, поскольку она обычно неточна). Здесь на помощь приходит механизм сопоставления с образцом.

Intel Curie PME, или механизм сопоставления с образцом, представляет собой искусственную нейронную сеть, встроенную в Arduino 101. Ее библиотеки доступны на GitHub. Состоящий из 128 нейронов, он может изучать и классифицировать данные, сохраненные в векторах, на основе существующих данных или векторы, классифицированные по категориям. Чем больше категорий доступно, тем больше возможностей для классификации может использовать PME.

Для этого проекта PME записывает данные о температуре в течение дня и пытается классифицировать среди этих данных оптимальное состояние, 25 градусов Цельсия. В результате наступает время полива растения на следующий день.

Данные записываются каждый час с 8 утра до 9 вечера. Когда это будет сделано в первый раз, данные будут сохранены на встроенной последовательной флэш-памяти . . Это позволит устройству загрузиться с набором данных, даже если оно было выключено. После получения набора данных он пытается классифицировать оптимальные условия. Если это возможно, то выбранная категория становится часом, используемым для следующего раунда. В противном случае устройство будет использовать ежемесячные постоянные или время суток каждого месяца с самыми высокими температурами. Следует отметить, что это не всегда лучшая температура для полива растений , поэтому я использовал PME.

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

Часы реального времени Intel Curie и Bluetooth с низким энергопотреблением

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

Bluetooth Low Energy - это новая версия Bluetooth, предназначенная для устройств с низким энергопотреблением. Он работает в центрально-периферийной системе, где центральная или входная система записывает на периферийные устройства или выходы. Это больше похоже на систему доски объявлений, где центральная часть помещает данные в сводку для чтения всеми периферийными устройствами. В этом случае я использовал nRF Connect от Nordic Semiconductor на моем мобильном устройстве в качестве центрального, а Arduino 101 - в качестве периферийного. Мобильное устройство имеет возможность подключаться к Arduino и отправлять на него данные. В этом случае мобильное устройство должно отправить данные четыре раза, по одному для каждого из обязательных полей ввода.

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

Как построить

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

Электрические компоненты

  • Arduino 101
  • 400 стяжных макетов с + - рельсами
  • Поворотный потенциометр
  • ЖК-экран 16x2
  • Резистор 330 Ом.
  • Датчик температуры TMP36
  • Сервопривод на 180 градусов, с сервоприводом
  • Датчик дождя и плата управления
  • Датчик влажности почвы и плата управления (опционально, оборудование входит в комплект для справки)
  • Большое количество перемычек; см. диаграмму Фритзинга.

Для работы от батарей (не может длиться слишком долго; я использовал настройку):

  • 2 батарейных блока 4xAA с выключателем и проводами.
  • 8 никель-металлгидридных аккумуляторных батарей AA 1,2 В

Для работы от USB-источника питания от настенной бородавки или ноутбука:

  • USB-штекер A - штекер B, длина которого зависит от ваших потребностей.

Неэлектрические компоненты оборудования

  • Кувшин для молока
  • Гибкая пластиковая трубка длиной около 20–30 см.
  • Пластилин, горячий клей или все, что можно использовать в качестве герметика.
  • Пластиковый стержень для поддержки рукава трубки.
  • Ремесленная корзина для устройства.
  • Поверхность, на которой можно разместить кувшин, например небольшую скамейку или стол.
  • Завод

Инструменты

  • Лента, обычная и электрическая.
  • Ножницы
  • Отвертка Phillips, чтобы прикрепить рог сервопривода к сервоприводу.

Шаги

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

2. (Перейдите к шагу 5, если используется питание от USB). Вставьте батареи в два батарейных отсека и свяжите положительный провод одного отсека и отрицательный провод другого.

3. Скрепите коробки вместе изолентой. Закрепите коробки так, чтобы крышки обоих были прикреплены, а коробки обоих были прикреплены, а крышка снималась как одно целое. Оставьте слоты открытыми для переключателей питания.

4. Приклейте двойную крышку батарейного отсека к нижней стороне Arduino 101 и макета. Это позволит легко заменить батареи, выдвинув их из-под платы.

5. Вставьте устройство в корзину для поделок и прорежьте две прорези на одной стороне устройства. Первый слот предназначен для программирования (или USB-питания, если вы решите это сделать), а второй будет выходом для датчиков и исполнительных механизмов, не расположенных на устройстве. Не стесняйтесь использовать изоленту, чтобы скрепить незакрепленные провода в этой розетке.

6. Возьмите кувшин для молока и отрежьте его верх так, чтобы в кувшине было достаточно большое отверстие для сбора воды и достаточно большая емкость, чтобы быть надежным. Я рекомендую разрезать где-нибудь близко к основанию ручки.

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

8. Используйте глину, чтобы запечатать верхнюю и нижнюю области вокруг трубы в отверстии. Убедитесь, что глина не попадает в трубу.

9. Используя глину и изоленту, прикрепите сервопривод как можно ниже к основанию молочника. Прикрепите лентой середину трубки и пластиковый стержень к рогу сервопривода. Убедитесь, что пластиковый стержень также прикреплен к верхнему концу трубки. Используйте изображение ниже в качестве справочного материала для шагов с 8 по 10.

10. Закрепите кувшин на возвышении. При необходимости используйте ленту.

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

Программирование

Запрограммируйте Arduino 101 с помощью прилагаемого кода. Загрузите с помощью Arduino IDE и Curie Core 2.0.2 или выше (если доступно). В код включено множество полезных комментариев.

Работа устройства

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

Перед вводом времени необходимо ввести и отправить идентификатор или любое число.

После ввода времени 101 будет ждать отключения мобильного устройства. После этого он будет ждать 8 часов утра текущего или следующего дня.

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

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

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

Надеюсь, этот проект сделает наш постоянно меняющийся мир немного лучше!

Код

  • Ирригационная система Arduino 101
Система орошения Arduino 101 Arduino
Код для работы ирригационной системы Arduino 101. Загрузите с помощью ядра Curie 2.0.2 и любой IDE версии 1.8.x или выше. CuriePME можно найти на GitHub.
 / * Это набросок решения для городского орошения. Он использует CuriePME для получения данных о температуре и определения оптимальных условий для полива растений по ним. Затем он поливает растение в это время и повторно изучает данные, циклически меняя их бесконечно. Обратите внимание, что этот скетч ДОЛЖЕН ЗАПУСТИТЬСЯ ДО 8 часов утра целевого дня, чтобы запустить устройство. Источники данных:WeatherSpark.com. Средняя погода в Ванкувере, Канада, круглый год - Weather Spark. N.p., n.d. Интернет. 4 июля 2017 г. . «Всего 4 производителя:глобальное сообщество садоводов». Только для производителей. N.p., n.d. Интернет. 10 июля 2017 г. . * /// Библиотеки для использования с этим кодом. Все они, кроме CuriePME, можно найти в ide. CuriePME можно загрузить из репозитория GitHub. # Include "CuriePME.h" #include  #include  #include  #include  #include  #include  // Код распиновки сервопривода. Servo waterPipe; // Код распиновки ЖК-дисплея. LiquidCrystal lcd (12, 11, 5, 4, 3, 2); // Глобальные константы / переменные. # определить термометр A3 #define rainSensor 1 # определить влажность1 A4 # определить влажность2 A1int tm1; int tm2; int tm3; int tm4; int tm5; int tm6; int tm7; int tm8; int tm9; int tm10; int tm11; int tm12; int tm13; int tm14; int tm15; int tm16; int tm17; int tm18; int tm19; int tm20; int tm21; int tm22; int tm23; int tm24; int tm25; int tm26; int tm27; int tm28; int tm29; int tm30; int average; int progav; float Voltage; float temperatureC; int tm; int hourTime =-1; int minuteTime =-1; int dayTime =-1; int monthTime =-1; int confirmTime =-1; // Сервис BLE data.BLEService plantService ("19B10000-E8F2-537E-4F6C-D104768A1214"); // характеристика BLE, доступная для чтения / записи из центра.BLEUnsignedCharCharacteristic timeCha racteristic ("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite); void setup () {// Это выполняется один раз. waterPipe.attach (9); waterPipe.write (0); pinMode (датчик дождя, ВХОД); lcd.begin (16, 2); // Запускаем и очищаем ЖК-дисплей. lcd.clear (); если (! SerialFlash.begin (ONBOARD_FLASH_SPI_PORT, ONBOARD_FLASH_CS_PIN)); lcd.setCursor (0, 0); lcd.print ("Время ввода:BLE"); // Инициализируем службу BLE с именем, службой, характеристикой и значением характеристики. BLE.begin (); BLE.setLocalName («Ардуино 101»); BLE.setAdvertisedService (plantService); plantService.addCharacteristic (timeCharacteristic); BLE.addService (plantService); timeCharacteristic.setValue (0); // 0, пока не будет записано центральным. BLE.advertise (); lcd.setCursor (0, 1); lcd.print («Ожидание»); // Готово к подключению. X:BLEDevice central =BLE.central (); if (central) {// Если устройство ссылается на доску. lcd.setCursor (8, 1); lcd.print («Готово»); задержка (3000); while (central.connected ()) {// Пока устройство подключено. if (timeCharacteristic.written ()) {// Код, который последовательно заполняет все слоты временных переменных после отправки каждого байта с устройства. Данные отправляются четыре раза, плюс один для подтверждения ссылки. если (confirmTime ==-1) {confirmTime =timeCharacteristic.value (); } иначе, если (hourTime ==-1) {hourTime =timeCharacteristic.value (); } иначе, если (minuteTime ==-1) {minuteTime =timeCharacteristic.value (); } иначе, если (dayTime ==-1) {dayTime =timeCharacteristic.value (); } иначе, если (monthTime ==-1) {monthTime =timeCharacteristic.value (); lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Время установлено."); lcd.setCursor (0, 1); lcd.print («Отключить устройство.»); }}}} еще {goto x; // Обратный цикл, если устройство еще не подключено. } // Устанавливаем время с помощью собранных переменных. Секунды и год не имеют значения для этой системы. setTime (hourTime, minuteTime, 00, dayTime, monthTime, 2017); // Инициализируем PME. lcd.clear (); CuriePME.begin (); lcd.setCursor (0, 0); lcd.print («Проверка сохранения.»); задержка (3000); const char * filename ="NeurData.dat"; если (check_if_exists (имя файла) ==true) {restoreNetworkKnowledge (); lcd.setCursor (0, 1); lcd.print («Нашел!»); задержка (3000); lcd.clear (); goto z; } еще {lcd.setCursor (0, 1); lcd.print («Не найдено!»); задержка (3000); lcd.clear (); } / * Оставшаяся часть настройки собирает данные о температуре в течение дня. Он выполняет 30 проверок в час с интервалом в 2 минуты, а в конце часа он берет среднее значение часовых данных, находя среднее арифметическое всех данных, кроме первого сканирования. Затем это среднее значение помещается в PME и изучается. Это повторяется с 8:00 до 21:00, после чего полный набор данных, полученный PME, сохраняется в памяти CurieFlash по умолчанию на случай, если и когда устройство теряет питание или его необходимо перезапустить. * / lcd.clear (); lcd.setCursor (0, 0); lcd.print («Обучение»); for (int i =8; i <22; i ++) // Повторите это 14 раз, каждый раз сохраняя в другой категории. {// Собираем 30 частей данных о температуре, сохраняемых как int, отображаемые между 0 и 255. Voltage =analogRead (thermometer) * 3.3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm1 =ограничение (tm, 0, 255); задержка (114000); // Компенсировать задержку проверки выше. напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm2 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm3 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm4 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm5 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm6 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm7 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm8 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm9 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm10 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm11 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm12 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm13 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm14 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm15 =ограничение (tm, 0, 255); // В течение первого периода обучения полив растений будет производиться при максимальных температурах этого месяца. если ((месяц () ==1 || месяц () ==2 || месяц () ==11 || месяц () ==12) &&час () ==12) {lcd.clear (); lcd.setCursor (0, 0); lcd.print («Выполняется ...»); // Поливайте растение, если нет дождя и достаточно низкой влажности почвы. int readRain =digitalRead (датчик дождя); если (readRain ==HIGH) {lcd.setCursor (0, 1); lcd.print («Прямо сейчас идет дождь.»); goto a2; } // Раскомментируйте использование датчиков влажности. // иначе if (analogRead (влажность1)> 400 || analogRead (влажность2)> 400) // Отрегулируйте их, чтобы они соответствовали вашей почве. // {//lcd.setCursor(0, 1); //lcd.print("Слишком влажная почва. "); // перейти к a2; //} else {waterPipe.write (135); задержка (7000); // Вода на 7 секунд. waterPipe.write (0); } lcd.setCursor (0, 1); lcd.print ("Готово"); a2:задержка (3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print («Обучение»); } else if ((месяц () ==3 || месяц () ==4 || месяц () ==10) &&час () ==14) {lcd.clear (); lcd.setCursor (0, 0); lcd.print («Выполняется ...»); lcd.clear (); lcd.setCursor (0, 0); lcd.print («Выполняется ...»); // Поливайте растение, если нет дождя и достаточно низкой влажности почвы. int readRain =digitalRead (датчик дождя); если (readRain ==HIGH) {lcd.setCursor (0, 1); lcd.print («Прямо сейчас идет дождь.»); goto a31; } // Раскомментируйте использование датчиков влажности. // иначе if (analogRead (влажность1)> 400 || analogRead (влажность2)> 400) // Отрегулируйте их, чтобы они соответствовали вашей почве. // {//lcd.setCursor(0, 1); //lcd.print("Слишком влажная почва. "); // перейти к a31; //} else {waterPipe.write (135); задержка (7000); // Вода на 7 секунд. waterPipe.write (0); } lcd.setCursor (0, 1); lcd.print («Готово»); a31:задержка (3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print («Обучение»); lcd.clear (); lcd.setCursor (0, 0); lcd.print («Обучение»); } else if ((месяц () ==5 || месяц () ==6 || месяц () ==9) &&час () ==15) {lcd.clear (); lcd.setCursor (0, 0); lcd.print («Выполняется ...»); lcd.clear (); lcd.setCursor (0, 0); lcd.print («Выполняется ...»); // Поливайте растение, если нет дождя и достаточно низкой влажности почвы. int readRain =digitalRead (датчик дождя); если (readRain ==HIGH) {lcd.setCursor (0, 1); lcd.print («Прямо сейчас идет дождь.»); goto a3; } // Раскомментируйте использование датчиков влажности. // иначе if (analogRead (влажность1)> 400 || analogRead (влажность2)> 400) // Отрегулируйте их, чтобы они соответствовали вашей почве. // {//lcd.setCursor(0, 1); //lcd.print("Слишком влажная почва. "); // перейти к a3; //} else {waterPipe.write (135); задержка (7000); // Вода на 7 секунд. waterPipe.write (0); } lcd.setCursor (0, 1); lcd.print ("Готово"); a3:задержка (3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print («Обучение»); } else if ((month () ==7 || month () ==8) &&hour () ==16) {lcd.clear (); lcd.setCursor (0, 0); lcd.print («Выполняется ...»); lcd.clear (); lcd.setCursor (0, 0); lcd.print («Выполняется ...»); // Поливайте растение, если нет дождя и достаточно низкой влажности почвы. int readRain =digitalRead (датчик дождя); если (readRain ==HIGH) {lcd.setCursor (0, 1); lcd.print («Прямо сейчас идет дождь.»); goto a4; } // Раскомментируйте использование датчиков влажности. // иначе if (analogRead (влажность1)> 400 || analogRead (влажность2)> 400) // Отрегулируйте их, чтобы они соответствовали вашей почве. // {//lcd.setCursor(0, 1); //lcd.print("Слишком влажная почва. "); // перейти к a4; //} else {waterPipe.write (135); задержка (7000); // Вода на 7 секунд. waterPipe.write (0); } lcd.setCursor (0, 1); lcd.print («Готово»); a4:задержка (3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print («Обучение»); } задержка (110000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm16 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm17 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm18 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm19 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm20 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm21 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm22 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm23 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm24 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm25 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm26 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm27 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm28 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm29 =ограничение (tm, 0, 255); задержка (120000); напряжение =analogRead (термометр) * 3,3; напряжение / =1024,0; температураС =(напряжение - 0,5) * 100; tm =map (температураC, -40, 125, 0, 255); tm30 =ограничение (tm, 0, 255); задержка (120000); // Преобразование данных в спецификации датчика температуры. tm1 =карта (tm1, 0, 255, -40, 125); tm1 =ограничение (tm1, -40, 125); tm2 =карта (tm2, 0, 255, -40, 125); tm2 =ограничение (tm2, -40, 125); tm3 =карта (tm3, 0, 255, -40, 125); tm3 =ограничение (tm3, -40, 125); tm4 =карта (tm4, 0, 255, -40, 125); tm4 =ограничение (tm4, -40, 125); tm5 =карта (tm5, 0, 255, -40, 125); tm5 =ограничение (tm5, -40, 125); tm6 =карта (tm6, 0, 255, -40, 125); tm6 =ограничение (tm6, -40, 125); tm7 =карта (tm7, 0, 255, -40, 125); tm7 =ограничение (tm7, -40, 125); tm8 =карта (tm8, 0, 255, -40, 125); tm8 =ограничение (tm8, -40, 125); tm9 =карта (tm9, 0, 255, -40, 125); tm9 =ограничение (tm9, -40, 125); tm10 =карта (tm10, 0, 255, -40, 125); tm10 =ограничение (tm10, -40, 125); tm11 =карта (tm11, 0, 255, -40, 125); tm11 =ограничение (tm11, -40, 125); tm12 =карта (tm12, 0, 255, -40, 125); tm12 =ограничение (tm12, -40, 125); tm13 =карта (tm13, 0, 255, -40, 125); tm13 =constrain(tm13, -40, 125); tm14 =map(tm14, 0, 255, -40, 125); tm14 =constrain(tm14, -40, 125); tm15 =map(tm15, 0, 255, -40, 125); tm15 =constrain(tm15, -40, 125); tm16 =map(tm16, 0, 255, -40, 125); tm16 =constrain(tm16, -40, 125); tm17 =map(tm17, 0, 255, -40, 125); tm17 =constrain(tm17, -40, 125); tm18 =map(tm18, 0, 255, -40, 125); tm18 =constrain(tm18, -40, 125); tm19 =map(tm19, 0, 255, -40, 125); tm19 =constrain(tm19, -40, 125); tm20 =map(tm20, 0, 255, -40, 125); tm20 =constrain(tm20, -40, 125); tm21 =map(tm21, 0, 255, -40, 125); tm21 =constrain(tm21, -40, 125); tm22 =map(tm22, 0, 255, -40, 125); tm22 =constrain(tm22, -40, 125); tm23 =map(tm23, 0, 255, -40, 125); tm23 =constrain(tm23, -40, 125); tm24 =map(tm24, 0, 255, -40, 125); tm24 =constrain(tm24, -40, 125); tm25 =map(tm25, 0, 255, -40, 125); tm25 =constrain(tm25, -40, 125); tm26 =map(tm26, 0, 255, -40, 125); tm26 =constrain(tm26, -40, 125); tm27 =map(tm27, 0, 255, -40, 125); tm27 =constrain(tm27, -40, 125); tm28 =map(tm28, 0, 255, -40, 125); tm28 =constrain(tm28, -40, 125); tm29 =map(tm29, 0, 255, -40, 125); tm29 =constrain(tm29, -40, 125); tm30 =map(tm30, 0, 255, -40, 125); tm30 =constrain(tm30, -40, 125); // Find the arithmetic mean and commit it to memory. average =(tm2 + tm3 + tm4 + tm5 + tm6 + tm7 + tm8 + tm9 + tm10 + tm11 + tm12 + tm13 + tm14 + tm15 + tm16 + tm17 + tm18 + tm19 + tm20 + tm21 + tm22 + tm23 + tm24 + tm25 + tm26 + tm27 + tm28 + tm29 + tm30) / 29; commitSample(i, average); } saveNetworkKnowledge(); // Save this new data to flash memory.z:delay(1);}void commitSample (int category, uint8_t s1){ // Commit to memory a single vector (the average), along with the category, which represents the hour of that data. uint8_t vector[1]; vector[0] =s1; CuriePME.learn(vector, 1, category);}void loop() { // Infinitely repeats. /* This code attempts to classify the optimum temperature for watering plants, 25 Celsius, among the data learned by the PME. If it can classify the data, the returned category becomes the hour at which the plant will be watered. The data is then erased and relearned, which infinitely repeats. IF IT CANNOT CLASSIFY THE DATA, it will take the monthly defaults from earlier in the sketch. */ uint8_t vector[1]; vector[0] =25; int answer =CuriePME.classify(vector, 1 ); if (answer ==CuriePME.noMatch) { lcd.clear(); lcd.setCursor (0, 0); lcd.print("NO MATCHES!"); if (month() ==1 || month() ==2 || month() ==11 || month() ==12) { answer =12; } else if (month() ==3 || month() ==4 || month() ==10) { answer =14; } else if (month() ==5 || month() ==6 || month() ==9) { answer =15; } else if (month() ==7 || month() ==8) { answer =16; } } else { lcd.clear(); lcd.setCursor (0, 0); lcd.print("Category:"); lcd.setCursor (0, 1); lcd.print(answer); } задержка (3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Optimization Done"); задержка (3000); CuriePME.forget(); // Erase and relearn. This does not erase the flash memory. lcd.clear (); lcd.setCursor (0, 0); lcd.print("Waiting"); while (hour() !=8); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Learning"); // Learn the data again. for (int i =8; i <22; i++) { voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm1 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm2 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm3 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm4 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm5 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm6 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm7 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm8 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm9 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm10 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm11 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm12 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm13 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm14 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm15 =constrain(tm, 0, 255); // The time in the day at which to water the plant, as determined by the PME. if (hour() ==answer) { lcd.clear(); lcd.setCursor (0, 0); lcd.print("Running..."); // Water the plant if it is not raining and soil moisture is low enough. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor(0, 1); lcd.print("Raining right now."); goto a5; } // Uncomment to use moisture sensors. //else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // Adjust these to match your soil. //{ // lcd.setCursor(0, 1); // lcd.print("Soil too moist."); // goto a5; //} else { waterPipe.write(135); delay(7000); // Water for 7 seconds. waterPipe.write(0); } lcd.setCursor(0, 1); lcd.print("Done");a5:delay(3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Learning"); } delay(110000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm16 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm17 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm18 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm19 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm20 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm21 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm22 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm23 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm24 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm25 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm26 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm27 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm28 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm29 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm30 =constrain(tm, 0, 255); delay(120000); tm1 =map(tm1, 0, 255, -40, 125); tm1 =constrain(tm1, -40, 125); tm2 =map(tm2, 0, 255, -40, 125); tm2 =constrain(tm2, -40, 125); tm3 =map(tm3, 0, 255, -40, 125); tm3 =constrain(tm3, -40, 125); tm4 =map(tm4, 0, 255, -40, 125); tm4 =constrain(tm4, -40, 125); tm5 =map(tm5, 0, 255, -40, 125); tm5 =constrain(tm5, -40, 125); tm6 =map(tm6, 0, 255, -40, 125); tm6 =constrain(tm6, -40, 125); tm7 =map(tm7, 0, 255, -40, 125); tm7 =constrain(tm7, -40, 125); tm8 =map(tm8, 0, 255, -40, 125); tm8 =constrain(tm8, -40, 125); tm9 =map(tm9, 0, 255, -40, 125); tm9 =constrain(tm9, -40, 125); tm10 =map(tm10, 0, 255, -40, 125); tm10 =constrain(tm10, -40, 125); tm11 =map(tm11, 0, 255, -40, 125); tm11 =constrain(tm11, -40, 125); tm12 =map(tm12, 0, 255, -40, 125); tm12 =constrain(tm12, -40, 125); tm13 =map(tm13, 0, 255, -40, 125); tm13 =constrain(tm13, -40, 125); tm14 =map(tm14, 0, 255, -40, 125); tm14 =constrain(tm14, -40, 125); tm15 =map(tm15, 0, 255, -40, 125); tm15 =constrain(tm15, -40, 125); tm16 =map(tm16, 0, 255, -40, 125); tm16 =constrain(tm16, -40, 125); tm17 =map(tm17, 0, 255, -40, 125); tm17 =constrain(tm17, -40, 125); tm18 =map(tm18, 0, 255, -40, 125); tm18 =constrain(tm18, -40, 125); tm19 =map(tm19, 0, 255, -40, 125); tm19 =constrain(tm19, -40, 125); tm20 =map(tm20, 0, 255, -40, 125); tm20 =constrain(tm20, -40, 125); tm21 =map(tm21, 0, 255, -40, 125); tm21 =constrain(tm21, -40, 125); tm22 =map(tm22, 0, 255, -40, 125); tm22 =constrain(tm22, -40, 125); tm23 =map(tm23, 0, 255, -40, 125); tm23 =constrain(tm23, -40, 125); tm24 =map(tm24, 0, 255, -40, 125); tm24 =constrain(tm24, -40, 125); tm25 =map(tm25, 0, 255, -40, 125); tm25 =constrain(tm25, -40, 125); tm26 =map(tm26, 0, 255, -40, 125); tm26 =constrain(tm26, -40, 125); tm27 =map(tm27, 0, 255, -40, 125); tm27 =constrain(tm27, -40, 125); tm28 =map(tm28, 0, 255, -40, 125); tm28 =constrain(tm28, -40, 125); tm29 =map(tm29, 0, 255, -40, 125); tm29 =constrain(tm29, -40, 125); tm30 =map(tm30, 0, 255, -40, 125); tm30 =constrain(tm30, -40, 125); average =(tm2 + tm3 + tm4 + tm5 + tm6 + tm7 + tm8 + tm9 + tm10 + tm11 + tm12 + tm13 + tm14 + tm15 + tm16 + tm17 + tm18 + tm19 + tm20 + tm21 + tm22 + tm23 + tm24 + tm25 + tm26 + tm27 + tm28 + tm29 + tm30) / 29; progav =(tm30 - tm2) / 2; commitSample(i, average); }}/* A quick note on the flash memory data:The data will only ever be saved once; that is, it cannot be changed with this code. As a result, if the device loses power, IT WILL DEFAULT TO THE SETTINGS OF THE FIRST TIME IT WAS USED WHEN IT IS REACTIVATED, even if the monthly averages have changed. Keeping the device on an extra day will allow it to software obtain new averages, but the flash memory will stay the same. To erase flash completely, upload "EraseEverything" from "CurieSerialFlash" in the IDE. Then reupload this sketch to save new averages to the flash memory.*/void saveNetworkKnowledge() // Code for saving to flash memory....This file has been truncated, please download it to see its full contents.

Схема

Fritzing diagram for the circuit. Note that batteries would be attached on the left. The soil moisture sensors are optional. rainpoweredsmartirrigationsystem_OHtd4bVfb3.fzz

Производственный процесс

  1. Титан
  2. Кастаньеты
  3. Приклейте
  4. Тема
  5. Ацетилен
  6. Асбест
  7. Игральные кости
  8. Олово
  9. Raspberry Pi Автоматический полив растений с веб-сайта
  10. Siemens, Bentley запускает решение для ускорения цифровизации предприятия