ESP8266:Примеры/Смарт-система для орошения растений на базе ESP8266

Материал из Онлайн справочника
Перейти к: навигация, поиск

Перевод: Максим Кузьмин (Cubewriter)
Перевел 1898 статей для сайта.

Контакты:

Проверка/Оформление/Редактирование: Мякишев Е.А.


Ambox content.png Черновик


Смарт-система для орошения растений на базе ESP8266[1]

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

Введение

Функции, которыми будет оснащена наша система орошения растений:

  • Удаленное управление водяной помпой
  • Автоматическое орошение, если влажность почвы понизится до определенного уровня
  • Автоматический/ручной режим
  • Отображение данных о влажности почвы и статусе водяной помпы
  • Запись логов о влажности почвы

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

[Видео – https://www.youtube.com/watch?v=NArYvZaukw8]

Пользовательский интерфейс EasyIoT Cloud:

ESP8266 smart plant irrigation system 1.png

Данные о влажности почвы:

ESP8266 smart plant irrigation system 2.png

Необходимые компоненты

  • Один модуль ESP8266
  • Одна водяная помпа
  • Один датчик влажности почвы
  • Один понижающий преобразователь напряжения на базе LM2596
  • Один 12-вольтовый источник питания
  • Один транзистор 2N2222 (типа NPN)
  • Одна макетная плата MB102
  • Один резистор на 5 кОм
ESP8266 smart plant irrigation system 3.jpg

Настройка EasyIoT Cloud

Зарегистрируйтесь в сервисе EasyIoT Cloud. Зайдя в сервис, создайте новый модуль для системы орошения. О том, как выставить новый тип модуля (в нашем случае – ZMT_IRRIGATOR), читайте в этом руководстве.

Программа

Программа написана в IDE Arduino. Она использует библиотеку «esp-mqtt» (это враппер-библиотека MQTT для ESP8266, позволяющая коммуницировать с сервисом EasyIoT Cloud и управлять его настройками). Программу можно скачать с GitHub.

В программе нужно поменять следующие строчки (они отвечают за SSID, пароль к SSID, а также за логин и пароль к EasyIoT Cloud):

#define AP_SSID "xxx"
#define AP_PASSWORD "xxx"
#define EIOTCLOUD_USERNAME "xxx"
#define EIOTCLOUD_PASSWORD "xxx"

Затем загрузите программу на плату NodeMCU. Вместо платы NodeMCU можно воспользоваться и другим модулем ESP8266, но в этом случае вам понадобятся дополнительное питание и адаптер USB-Serial от FTDI.

  1. #include <ESP8266WiFi.h>
  2. #include <MQTT.h>
  3. #include <EEPROM.h>
  4.  
  5. #define AP_SSID     "xxx"
  6. #define AP_PASSWORD "xxx"  
  7.  
  8. #define EIOTCLOUD_USERNAME "xxx"
  9. #define EIOTCLOUD_PASSWORD "xxx"
  10.  
  11. // создаем объект MQTT:
  12. #define EIOT_CLOUD_ADDRESS "cloud.iot-playground.com"
  13.  
  14.  
  15.  
  16. #define PIN_PUMP         BUILTIN_LED //D0  // для встроенного
  17.                                            // светодиода на NodeMCU
  18. #define PIN_BUTTON       D3  // для кнопки «Flash» на NodeMCU
  19. #define PIN_HUM_ANALOG   A0  // для измерения влажности
  20.  
  21.  
  22. #define MAX_ANALOG_VAL         956
  23. #define MIN_ANALOG_VAL         250
  24.  
  25. #define IRRIGATION_TIME        10   // время орошения (в секундах)
  26. #define IRRIGATION_PAUSE_TIME  300  // пауза между орошениями
  27.                                     // (в секундах); только для
  28.                                     // автоматического орошения
  29.  
  30. // значения для статуса оросителя:
  31. typedef enum {
  32.   s_idle             = 0,  // простой оросителя
  33.   s_irrigation_start = 1,  // запуск орошения
  34.   s_irrigation       = 2,  // орошение
  35.   s_irrigation_stop  = 3,  // остановка орошения
  36. } e_state;
  37.  
  38.  
  39. #define CONFIG_START 0
  40. #define CONFIG_VERSION "v01"
  41.  
  42. struct StoreStruct {
  43.   // это чтобы убедиться, что это ваши настройки:
  44.   char version[4];
  45.   // переменные для ваших настроек:
  46.   uint moduleId;  // ID модуля
  47. } storage = {
  48.   CONFIG_VERSION,
  49.   // дефолтный модуль «0»
  50.   0,
  51. };
  52.  
  53. #define PARAM_HUMIDITY_TRESHOLD   "/Sensor.Parameter1"
  54. #define PARAM_MANUAL_AUTO_MODE    "/Sensor.Parameter2"
  55. #define PARAM_PUMP_ON             "/Sensor.Parameter3"
  56. #define PARAM_HUMIDITY            "/Sensor.Parameter4"
  57.  
  58.  
  59. #define MS_IN_SEC  1000 // 1S  
  60.  
  61.  
  62. MQTT myMqtt("", EIOT_CLOUD_ADDRESS, 1883);
  63.  
  64. // переменные:
  65. int state;
  66. bool stepOk = false;
  67. int soilHumidityThreshold;
  68. bool autoMode;
  69. String valueStr("");
  70. String topic("");
  71. boolean result;
  72. int lastAnalogReading;
  73. bool autoModeOld;
  74. int soilHumidityThresholdOld;
  75. unsigned long startTime;
  76. int soilHum;
  77. int irrigatorCounter;
  78.  
  79. void setup() {
  80.   state = s_idle;
  81.   pinMode(PIN_PUMP, OUTPUT);
  82.   pinMode(PIN_BUTTON, INPUT);
  83.  
  84.   autoMode = false;
  85.   stepOk = false;
  86.   soilHumidityThresholdOld = -1;
  87.   startTime = millis();
  88.   soilHum = -1;
  89.  
  90.   Serial.begin(115200);
  91.  
  92.   WiFi.mode(WIFI_STA);  
  93.   WiFi.begin(AP_SSID, AP_PASSWORD);
  94.  
  95.   Serial.println();
  96.   Serial.println();
  97.   Serial.print("Connecting to ");  //  "Подключение к "
  98.   Serial.println(AP_SSID);
  99.    
  100.   while (WiFi.status() != WL_CONNECTED) {
  101.     delay(500);
  102.     Serial.print(".");
  103.   };
  104.  
  105.   Serial.println("WiFi connected");  //  "Подключились к WiFi"
  106.   Serial.println("Connecting to MQTT server");  
  107.              //  "Подключение к MQTT-серверу"
  108.  
  109.  
  110.   EEPROM.begin(512);
  111.   loadConfig();
  112.  
  113.  
  114.   // задаем ID клиента;
  115.   // генерируем название клиента на основе MAC-адреса
  116.   // и последних 8 бит счетчика микросекунд:
  117.   String clientName;
  118.   //clientName += "esp8266-";
  119.   uint8_t mac[6];
  120.   WiFi.macAddress(mac);
  121.   clientName += macToStr(mac);
  122.   clientName += "-";
  123.   clientName += String(micros() & 0xff, 16);
  124.   myMqtt.setClientId((char*) clientName.c_str());
  125.  
  126.   Serial.print("MQTT client id:");  //  "ID MQTT-клиента"
  127.   Serial.println(clientName);
  128.  
  129.   // функции обратного вызова:
  130.   myMqtt.onConnected(myConnectedCb);
  131.   myMqtt.onDisconnected(myDisconnectedCb);
  132.   myMqtt.onPublished(myPublishedCb);
  133.   myMqtt.onData(myDataCb);
  134.  
  135.   //////Serial.println("connect mqtt...");
  136.                    //  "Подключение к MQTT..."
  137.   myMqtt.setUserPwd(EIOTCLOUD_USERNAME, EIOTCLOUD_PASSWORD);  
  138.   myMqtt.connect();
  139.  
  140.   delay(500);
  141.  
  142.   Serial.print("ModuleId: ");
  143.   Serial.println(storage.moduleId);
  144.  
  145.  
  146.   // создаем модуль, если нужно:
  147.   if (storage.moduleId == 0)
  148.   {
  149.     // создаем модуль:
  150.     Serial.println("create module: /NewModule");
  151.                //  "Создание модуля: /NewModule"
  152.  
  153.     storage.moduleId = myMqtt.NewModule();
  154.  
  155.     if (storage.moduleId == 0)
  156.     {
  157.       Serial.println("Module NOT created. Check module limit");
  158.                  //  "Модуль не создан. Проверьте лимит модулей"
  159.  
  160.       while(1)
  161.         delay(100);
  162.     }
  163.  
  164.    // задаем тип модуля:
  165.     Serial.println("Set module type");  //  "Установка типа модуля"    
  166.     myMqtt.SetModuleType(storage.moduleId, "ZMT_IRRIGATOR");
  167.  
  168.     // создаем параметр Sensor.Parameter1;
  169.     // это пороговое значение для влажности почвы:
  170.     Serial.println("new parameter: /"+String(storage.moduleId)+ PARAM_HUMIDITY_TRESHOLD);    
  171.     myMqtt.NewModuleParameter(storage.moduleId, PARAM_HUMIDITY_TRESHOLD);
  172.  
  173.     // устанавливаем флаг «IsCommand»:
  174.     Serial.println("set isCommand: /"+String(storage.moduleId)+ PARAM_HUMIDITY_TRESHOLD);    
  175.     myMqtt.SetParameterIsCommand(storage.moduleId, PARAM_HUMIDITY_TRESHOLD, true);
  176.  
  177.  
  178.     // создаем параметр Sensor.Parameter2;
  179.     // «0» – ручной режим; «1» – автоматический режим:
  180.     Serial.println("new parameter: /"+String(storage.moduleId)+ PARAM_MANUAL_AUTO_MODE);    
  181.     myMqtt.NewModuleParameter(storage.moduleId, PARAM_MANUAL_AUTO_MODE);
  182.  
  183.     // устанавливаем флаг «IsCommand»:
  184.     Serial.println("set isCommand: /"+String(storage.moduleId)+ PARAM_MANUAL_AUTO_MODE);    
  185.     myMqtt.SetParameterIsCommand(storage.moduleId, PARAM_MANUAL_AUTO_MODE, true);
  186.  
  187.    
  188.     // создаем параметр Sensor.Parameter3;
  189.     // он отвечает за включение/выключение водяной помпы:
  190.     Serial.println("new parameter: /"+String(storage.moduleId)+ PARAM_PUMP_ON);    
  191.     myMqtt.NewModuleParameter(storage.moduleId, PARAM_PUMP_ON);
  192.  
  193.  
  194.     // устанавливаем флаг «IsCommand»:
  195.     Serial.println("set isCommand: /"+String(storage.moduleId)+ PARAM_PUMP_ON);    
  196.     myMqtt.SetParameterIsCommand(storage.moduleId, PARAM_PUMP_ON, true);
  197.  
  198.  
  199.     // создаем параметр Sensor.Parameter4;
  200.     // он отвечает за текущую влажность почвы:
  201.     Serial.println("new parameter: /"+String(storage.moduleId)+ PARAM_HUMIDITY);    
  202.     myMqtt.NewModuleParameter(storage.moduleId, PARAM_HUMIDITY);
  203.  
  204.  
  205.     // задаем описание:
  206.     Serial.println("set description: /"+String(storage.moduleId)+ PARAM_HUMIDITY);    
  207.     myMqtt.SetParameterDescription(storage.moduleId, PARAM_HUMIDITY, "Soil hum.");
  208.  
  209.     // задаем единицу измерения:
  210.     Serial.println("set Unit: /"+String(storage.moduleId)+ PARAM_HUMIDITY);    
  211.     myMqtt.SetParameterUnit(storage.moduleId, PARAM_HUMIDITY, "%");
  212.  
  213.     // устанавливаем флаг «dbLogging»;
  214.     // он отвечает за запись логов в базу данных:
  215.     Serial.println("set Unit: /"+String(storage.moduleId)+ PARAM_HUMIDITY);    
  216.     myMqtt.SetParameterDBLogging(storage.moduleId, PARAM_HUMIDITY, true);
  217.  
  218.     // сохраняем ID нового модуля:
  219.     saveConfig();
  220.   }
  221.  
  222.   subscribe();
  223.  
  224.   lastAnalogReading = analogRead(PIN_HUM_ANALOG);
  225.  
  226.   autoModeOld = !autoMode;
  227. }
  228.  
  229. void loop() {
  230.   while (WiFi.status() != WL_CONNECTED) {
  231.     delay(500);
  232. #ifdef DEBUG        
  233.     Serial.print(".");
  234. #endif
  235.   }
  236.  
  237.   int in = digitalRead(PIN_BUTTON);
  238.  
  239.   //Serial.println(in);
  240.   if (in == 0)
  241.   {
  242.     while(digitalRead(PIN_BUTTON) == 0)
  243.       delay(100);
  244.  
  245.     if (state == s_idle || state == s_irrigation_start)
  246.       state = s_irrigation_start;
  247.     else
  248.       state = s_irrigation_stop;
  249.   }
  250.  
  251.  
  252.  
  253.   // публикуем изменения автоматического режима:
  254.   if (autoModeOld != autoMode)
  255.   {
  256.     autoModeOld = autoMode;
  257.  
  258.     if (autoMode)    
  259.       valueStr = String("1");
  260.     else
  261.       valueStr = String("0");
  262.    
  263.     topic  = "/"+String(storage.moduleId)+ PARAM_MANUAL_AUTO_MODE;
  264.     result = myMqtt.publish(topic, valueStr, 0, 1);
  265.  
  266.     Serial.print("Publish topic: ");  //  "Публикация в топик: "
  267.     Serial.print(topic);
  268.     Serial.print(" value: ");  //  " значение: "
  269.     Serial.println(valueStr);  
  270.   }
  271.  
  272.   // публикуем изменения порогового значения:
  273.   if (soilHumidityThreshold != soilHumidityThresholdOld)
  274.   {
  275.     soilHumidityThresholdOld = soilHumidityThreshold;
  276.     valueStr = String(soilHumidityThreshold);
  277.    
  278.     topic  = "/"+String(storage.moduleId)+ PARAM_HUMIDITY_TRESHOLD;
  279.     result = myMqtt.publish(topic, valueStr, 0, 1);
  280.  
  281.     Serial.print("Publish topic: ");  //  "Публикация в топик: "
  282.     Serial.print(topic);
  283.     Serial.print(" value: ");         //  " значение: "
  284.     Serial.println(valueStr);  
  285.   }
  286.  
  287.   if (IsTimeout())
  288.   {
  289.     startTime = millis();
  290.     // выполняем обработку данных каждую секунду:
  291.     int aireading = analogRead(PIN_HUM_ANALOG);
  292.  
  293.     Serial.print("Analog value: ");  //  "Аналоговое значение: "
  294.     Serial.print(aireading);
  295.     Serial.print(" ");
  296.     // фильтр:
  297.     lastAnalogReading += (aireading - lastAnalogReading) / 10;  
  298.     Serial.print(lastAnalogReading);
  299.    
  300.    // вычисляем влажность почвы (в процентах):
  301.    int newSoilHum = map(lastAnalogReading, MIN_ANALOG_VAL, MAX_ANALOG_VAL, 100, 0);  
  302.    Serial.print(", Soil hum %:");  //  ", Влажность почвы в %:"
  303.    Serial.println(newSoilHum);
  304.        
  305.    // ограничиваем до 0-100%:
  306.    if (newSoilHum < 0)
  307.       newSoilHum = 0;
  308.  
  309.     if (newSoilHum > 100)
  310.       newSoilHum = 100;
  311.  
  312.    // если произошли изменения во влажности почвы, сообщаем о них:
  313.    if (soilHum != newSoilHum)
  314.    {
  315.      soilHum = newSoilHum;
  316.      //esp.send(msgHum.set(soilHum));
  317.      
  318.      valueStr = String(soilHum);
  319.      topic  = "/"+String(storage.moduleId)+ PARAM_HUMIDITY;
  320.      result = myMqtt.publish(topic, valueStr, 0, 1);
  321.  
  322.      Serial.print("Publish topic: ");  //  "Публикация в топик: "
  323.      Serial.print(topic);
  324.      Serial.print(" value: ");  //  " значение: "
  325.      Serial.println(valueStr);  
  326.    }
  327.    
  328.    
  329.    // код для работы с состоянием оросителя:
  330.    switch(state)
  331.    {
  332.      case s_idle:    
  333.        if (irrigatorCounter <= IRRIGATION_PAUSE_TIME)
  334.          irrigatorCounter++;
  335.        
  336.        if (irrigatorCounter >= IRRIGATION_PAUSE_TIME && autoMode)
  337.        {
  338.          if (soilHum <= soilHumidityThreshold)
  339.            state = s_irrigation_start;      
  340.        }        
  341.        break;
  342.      case s_irrigation_start:
  343.        irrigatorCounter = 0;
  344.        digitalWrite(PIN_PUMP, HIGH);
  345.        //esp.send(msgMotorPump.set((uint8_t)1));      
  346.        valueStr = String(1);
  347.        topic  = "/"+String(storage.moduleId)+ PARAM_PUMP_ON;
  348.        result = myMqtt.publish(topic, valueStr, 0, 1);    
  349.  
  350.        Serial.print("Publish topic: ");  //  "Публикация в топик: "
  351.        Serial.print(topic);
  352.        Serial.print(" value: ");  //  " значение: "
  353.        Serial.println(valueStr);  
  354.  
  355.        state = s_irrigation;
  356.        break;
  357.      case s_irrigation:
  358.        if (irrigatorCounter++ > IRRIGATION_TIME)
  359.          state = s_irrigation_stop;
  360.        break;
  361.      case s_irrigation_stop:
  362.        irrigatorCounter = 0;
  363.        state = s_idle;
  364.        //esp.send(msgMotorPump.set((uint8_t)0));
  365.        valueStr = String(0);
  366.        topic  = "/"+String(storage.moduleId)+ PARAM_PUMP_ON;
  367.        result = myMqtt.publish(topic, valueStr, 0, 1);    
  368.  
  369.        digitalWrite(PIN_PUMP, LOW);
  370.        break;
  371.    }
  372.   }
  373.  
  374. }
  375.  
  376. void loadConfig() {
  377.   // чтобы убедиться, что настройки есть, и они ваши;
  378.   // если настроек найдено не будет, будут использованы
  379.   // настройки по умолчанию:
  380.   if (EEPROM.read(CONFIG_START + 0) == CONFIG_VERSION[0] &&
  381.       EEPROM.read(CONFIG_START + 1) == CONFIG_VERSION[1] &&
  382.       EEPROM.read(CONFIG_START + 2) == CONFIG_VERSION[2])
  383.     for (unsigned int t=0; t<sizeof(storage); t++)
  384.       *((char*)&storage + t) = EEPROM.read(CONFIG_START + t);
  385. }
  386.  
  387. void saveConfig() {
  388.   for (unsigned int t=0; t<sizeof(storage); t++)
  389.     EEPROM.write(CONFIG_START + t, *((char*)&storage + t));
  390.  
  391.   EEPROM.commit();
  392. }
  393.  
  394.  
  395. String macToStr(const uint8_t* mac)
  396. {
  397.   String result;
  398.   for (int i = 0; i < 6; ++i) {
  399.     result += String(mac[i], 16);
  400.     if (i < 5)
  401.       result += ':';
  402.   }
  403.   return result;
  404. }
  405.  
  406. void waitOk()
  407. {
  408.   while(!stepOk)
  409.     delay(100);
  410.  
  411.   stepOk = false;
  412. }
  413.  
  414. boolean IsTimeout()
  415. {
  416.   unsigned long now = millis();
  417.   if (startTime <= now)
  418.   {
  419.     if ( (unsigned long)(now - startTime )  < MS_IN_SEC )
  420.       return false;
  421.   }
  422.   else
  423.   {
  424.     if ( (unsigned long)(startTime - now) < MS_IN_SEC )
  425.       return false;
  426.   }
  427.  
  428.   return true;
  429. }
  430.  
  431.  
  432. void subscribe()
  433. {
  434.   if (storage.moduleId != 0)
  435.   {
  436.     // параметр Sensor.Parameter1 – пороговое значение:
  437.     myMqtt.subscribe("/"+String(storage.moduleId)+ PARAM_HUMIDITY_TRESHOLD);
  438.  
  439.     // параметр Sensor.Parameter2 –
  440.     // переключение между ручным и автоматическим режимами:
  441.     myMqtt.subscribe("/"+String(storage.moduleId)+ PARAM_MANUAL_AUTO_MODE);
  442.  
  443.     // параметр Sensor.Parameter3 – включение/выключение помпы:
  444.     myMqtt.subscribe("/"+String(storage.moduleId)+ PARAM_PUMP_ON);
  445.   }
  446. }
  447.  
  448.  
  449. void myConnectedCb() {
  450. #ifdef DEBUG
  451.   Serial.println("connected to MQTT server");
  452.              //  "Подключение к серверу MQTT"
  453. #endif
  454.   subscribe();
  455. }
  456.  
  457. void myDisconnectedCb() {
  458. #ifdef DEBUG
  459.   Serial.println("disconnected. try to reconnect...");
  460.              //  "Произошло отключение. Пытаемся переподключиться..."
  461. #endif
  462.   delay(500);
  463.   myMqtt.connect();
  464. }
  465.  
  466. void myPublishedCb() {
  467. #ifdef DEBUG  
  468.   Serial.println("published.");  //  "Опубликовано."
  469. #endif
  470. }
  471.  
  472. void myDataCb(String& topic, String& data) {  
  473. #ifdef DEBUG
  474.   Serial.print("Receive topic: ");  //  "Принимающий топик: "
  475.   Serial.print(topic);
  476.   Serial.print(": ");
  477.   Serial.println(data);
  478. #endif
  479.   if (topic == String("/"+String(storage.moduleId)+ PARAM_HUMIDITY_TRESHOLD))
  480.   {
  481.     soilHumidityThreshold = data.toInt();
  482.     Serial.println("soilHumidityThreshold");
  483.     Serial.println(data);
  484.   }
  485.  
  486.   else if (topic == String("/"+String(storage.moduleId)+ PARAM_MANUAL_AUTO_MODE))
  487.   {
  488.     autoMode = (data == String("1"));
  489.     Serial.println("Auto mode");  //  "Автоматический режим"
  490.     Serial.println(data);
  491.   }
  492.   else if (topic == String("/"+String(storage.moduleId)+ PARAM_PUMP_ON))
  493.   {
  494.     //switchState = (data == String("1"))? true: false;
  495.     if (data == String("1"))
  496.       state = s_irrigation_start;
  497.     else
  498.       state = s_irrigation_stop;
  499.     Serial.println("Pump");  //  "Водяная помпа"
  500.     Serial.println(data);
  501.   }
  502. }

Подключение компонентов

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

Подключение датчика влажности почвы

Чтобы обеспечить питанием датчик влажности почвы, подключите контакт VCC на датчике к 3.3V на ESP8266, а контакт GND на датчике – к контакту GND на ESP8266. Затем подключите контакт AO на датчике (он отвечает за вывод аналоговых данных) к входному аналоговому контакту A0 на ESP8266. Контакт DO на датчике оставьте неподключенным.

Подключение мотора водяной помпы к ESP8266

Для этого понадобится реле-модуль. Поскольку реле-модуль использует 5-вольтовое питание, а ESP82663,3-вольтовое, нам нужно будет добавить в цепь транзистор, чтобы управлять 5-вольтовым реле при помощи 3,3 вольт. Кроме того, к контакту D0 на ESP8266 нужно подключить транзистор, а между D0 и транзистором – резистор на 5 кОм. Если вы подключите реле-модуль напрямую к модулю ESP8266, то просто поджарите его.

Другая сторона реле-модуля должна быть подключена к мотору водяной помпы и регулируемому источнику питания. Напряжение для мотора водяной помпы нужно поставить между 6 и 9 вольтами.

ESP8266 motor pump.png

Подключение кнопки для включения/выключения помпы

Если вы используете плату NodeMCU, то подключать кнопку не потребуется – можно воспользоваться кнопкой Flash на плате. Но если вы используете другой тип модуля ESP8266, тогда возьмите резистор на 10 кОм, а затем подключите одну его сторону к 3,3 вольтам, а вторую – к контакту D3. Потом подключите контакт D3 к контакту GND, а между ними – кнопку.

ESP8266 smart plant irrigation 5.png

См.также

Внешние ссылки

  1. iot-playground.com - ESP8266 smart plant irrigation system