В этом проекте мы рассмотрим систему орошения на базе Интернета вещей с использованием платы ESP32 и приложения Blynk. Это проект, основанный на концепции Интернете вещей (IoT), представляет собой интеллектуальную систему орошения и предлагает множество возможностей для автоматизации всего процесса орошения. Данная оросительная система построена с использованием таких компонентов как микроконтроллер ESP32, датчик влажности почвы, датчик уровня воды, модуль реле и датчик DHT22. Она будет отправлять данные в приложение Blynk. Также в составе системы есть водяной насос, который разбрызгивает воду в зависимости от состояния земли и таких факторов как влажность и температура. Эта система будет удобна для ферм и теплиц.
Ранее на нашем сайте мы уже рассматривали ряд аналогичных оросительных систем:
- умная оросительная система на NodeMCU ESP8266 и датчике влажности почвы;
- ирригационная система на ESP8266 с контролем влажности и уровня воды;
- автоматическая оросительная система на Arduino Uno;
- автоматическая система полива растений на основе Arduino.
Как работает наша умная ирригационная система?
Мы будем использовать емкостный датчик влажности почвы для измерения содержания влаги в почве. Вы также можете использовать резистивный датчик влажности почвы. Также мы используем датчик уровня воды для измерения уровня воды внутри резервуара для воды. Аналогичным образом, для измерения температуры и влажности воздуха мы предпочитаем датчик температуры и влажности DHT22. Используя силовое реле 5 В, мы будем управлять водяным насосом.
При включении нашей системы плата ESP32 подключается к приложению и облаку Blynk через Интернет. Затем значения влажности почвы отображаются в интерфейсе приложения Blynk. Всякий раз, когда датчик обнаруживает низкое количество (менее 50%) влаги в почве, двигатель автоматически включается. Следовательно, будет автоматически орошаться поле. Если датчик воды обнаруживает низкий уровень воды (менее 20%) внутри резервуара для воды, в этом случае двигатель не включится автоматически. Как только почва становится влажной, двигатель отключается. Кроме того, с помощью кнопки, созданной в этом приложении Blynk, мы можем включать и выключать модуль реле в ручном режиме. Вы можете следить за всем этим удаленно через приложение blynk из любой точки мира.
Необходимые компоненты
- Модуль ESP32 (купить на AliExpress).
- Датчик влажности почвы (купить на AliExpress).
- Датчик уровня воды
- Датчик температуры и влажности DHT22 (купить на AliExpress).
- Водяной насос (купить на AliExpress).
- Модуль реле (купить на AliExpress).
- Литий-ионный аккумулятор 3,7 В.
- Светодиодная лента RGB 5 В.
- Соединительные провода.
Емкостный датчик влажности почвы
Этот датчик представляет собой аналоговый емкостной датчик влажности почвы, который измеряет уровень влажности почвы посредством емкостного измерения. Датчик регулирует свою емкость в зависимости от количества воды в почве. Вы можете перевести это изменение емкости в уровень напряжения в диапазоне от минимум 1,2 В до максимум 3,0 В. Одним из преимуществ емкостного датчика влажности почвы является его конструкция из устойчивых к коррозии материалов, обеспечивающая длительный срок службы.
Датчик температуры и влажности DHT22
DHT22 — это простой и очень дешевый датчик, который измеряет температуру и влажность. Он использует специальный датчик, чтобы узнать, сколько влаги в воздухе, и датчик температуры для измерения температуры. Датчик передает нам эту информацию в цифровом виде по одному проводу. Его легко использовать, но нужно набраться терпения, поскольку получение новой информации занимает около 2 секунд. В нашем проекте мы будем использовать этот датчик чтобы определить насколько горячий и влажный воздух.
Схема проекта
Схема ирригационной системы на основе модуля ESP32 и приложения Blynk представлена на следующем рисунке.
Подключите датчик влажности почвы к контакту D35 модуля ESP32, датчик уровня воды к контакту D34 и датчик DHT22 к контакту D4. Двигатель подключается к реле. Для управления реле мы используем контакт D5 модуля ESP32. Подключите светодиодную ленту RGB к контакту D21 модуля ESP32. Вы можете запитать двигатель и реле, используя напряжение 3,7 В от литий-ионного аккумулятора. Для датчика DHT22, емкостного датчика влажности почвы и датчика уровня воды требуется только питание 3,3 В.
Внешний вид собранной конструкции проекта показан на следующем рисунке.
Настройка приложения Blynk
Встречайте новое приложение Blynk. После создания учетной записи посетите https://blynk.io. Затем введите идентификатор электронной почты и пароль и нажмите login («Войти»).
Сначала вам нужно создать новый шаблон в приложении Blynk. Чтобы создать новый шаблон в учетной записи приложения Blynk, выполните следующие действия. Перейдите в зону разработчика (Developer Zone) в меню слева. Нажмите меню My Template («Мой шаблон»). Создайте новый шаблон.
Из меню Widgets («Виджеты») вы можете добавить в интерфейс виджеты кнопок (Button Widgets) и Gauge Widgets (виджеты датчиков). Затем назовите его по своему усмотрению и выберите виртуальный вывод как V0. Затем измените значения с 1 на 0 и измените режим, поскольку переключатель виджетов «Датчик» (Gauge) меняет входные значения с 0 на 100. Наконец, настройте эти виджеты по своему усмотрению.
В информации об устройстве вы найдете свой Template ID (идентификатор шаблона), Template Name (имя шаблона) и AuthToken, скопируйте их и вставьте в код программы.
Объяснение кода программы
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
В коде нашей программы анимация светодиодных лент RGB и датчиков, таких как DHT22, датчик влажности почвы и датчик уровня воды управляются и контролируются через приложение Blynk. Насос и светодиодный индикатор управляются в зависимости от влажности почвы и уровня воды. Дополнительно имеются функции изменения цветовой палитры и других визуальных эффектов RGB LED ленты.
- Библиотека Wi-Fi — Скачать
- Библиотека Blynk — Скачать
- Библиотека DHT — Скачать
- Библиотека FastLED — Скачать
Зададим идентификатор шаблона Blynk, имя шаблона, токен аутентификации и настроим последовательный вывод для Blynk.
1 2 3 4 |
#define BLYNK_TEMPLATE_ID «Замените здесь свой BLYNK_TEMPLATE_ID» #define BLYNK_TEMPLATE_NAME "Замените здесь свой BLYNK_TEMPLATE_NAME" #define BLYNK_AUTH_TOKEN "Замените здесь свой BLYNK_AUTH_TOKEN" #define BLYNK_PRINT Serial |
В следующем фрагменте коды мы подключаем необходимые библиотеки (WiFi, Blynk, DHT, FastLED) и задаем детали аутентификации и учетные данные Wi-Fi.
1 2 3 4 5 6 7 |
#include <WiFi.h> #include <BlynkSimpleEsp32.h> #include "DHT.h" #include <FastLED.h> char auth[] = BLYNK_AUTH_TOKEN; char ssid[] = "Wifi Name"; char pass[] = "Wifi Password"; |
Далее настраиваем параметры светодиодной матрицы, такие как яркость, тип, порядок и расположение.
1 2 3 4 5 6 7 8 |
#define LED_PIN 21 #define BRIGHTNESS 255 #define LED_TYPE WS2811 #define COLOR_ORDER GRB const uint8_t kMatrixWidth = 16; const uint8_t kMatrixHeight = 16; const bool kMatrixSerpentineLayout = true; |
Затем настраиваем датчик DHT и определяем контакты для влажности почвы, уровня воды и светодиодов.
1 2 3 4 5 6 7 |
#define DHTPIN 4 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); const int soilMoisturePin = 35; // Analog pin for the soil moisture sensor const int waterLevelPin = 34; // Analog pin for the water level sensor const int ledPin = 2; |
После этого устанавливаем пороговые значения влажности почвы, штифтов насоса и переменных, связанных с управлением насосом и уровнем воды.
1 2 3 4 5 6 7 8 9 10 11 |
// Constants for soil moisture thresholds const int SOIL_MOISTURE_LOW = 50; // Adjusted to match the 0-100 range const int SOIL_MOISTURE_HIGH = 50; // Adjusted to match the 0-100 range const int pumpPin = 5; // Change this to the actual pin connected to the DC pump on ESP32 int pumpState = LOW; // Initialize pumpState to LOW (off) int pumpMode = 0; // 0 for automatic, 1 for manual int waterLevel = 0; // Water level indicator value unsigned long previousMillis = 0; const unsigned long interval = 1000; // Interval in milliseconds |
Инициализируем последовательную связь, выходные контакты, соединение Blynk и светодиодную матрицу.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
void setup() { Serial.begin(115200); digitalWrite(pumpPin,LOW); pinMode(ledPin, OUTPUT); pinMode(pumpPin, OUTPUT); dht.begin(); Blynk.begin(auth, ssid, pass); Blynk.virtualWrite(V2, LOW); Blynk.virtualWrite(V3, "LED OFF"); Blynk.virtualWrite(V6, LOW); // Initialize the mode button to automatic mode Blynk.virtualWrite(V5, LOW); // Initialize the pump button to OFF and On Blynk.virtualWrite(V8, LOW); // Initialize the RGB Led Strip button to OFF And On delay(3000); LEDS.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds,80); LEDS.setBrightness(BRIGHTNESS); } |
Также запрограммируем функции, запускаемые при взаимодействии с приложением Blynk, управления помпой, управления режимом (автоматический и ручной) и светодиодной лентой RGB.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
BLYNK_WRITE(V5) { // This function is called when the pump button state changes (Manual Control) if (pumpMode == 1) { // Check if the mode is manual pumpState = param.asInt(); // Read the state of the pump button (0 for OFF, 1 for ON) digitalWrite(pumpPin, pumpState); // Turn the pump on or off based on button state } } BLYNK_WRITE(V6) { // This function is called when the mode button state changes pumpMode = param.asInt(); // Read the state of the mode button (0 for automatic, 1 for manual) } BLYNK_WRITE(V8) { int value = param.asInt(); if (value == 1) { // Turn on the LED strip and start the animation ledStripOn = true; } else { // Turn off the LED strip ledStripOn = false; // You can also add code to clear the LED strip here if needed } } |
Если система находится в автоматическом режиме (pumpMode == 0), она считывает уровень влажности почвы с помощью датчика влажности почвы. Значение датчика отображается в диапазоне от 0 до 100, а функция autoControlPump вызывается для управления насосом в зависимости от влажности почвы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
void loop() { Blynk.run(); timer.run(); updateLEDStrip(); unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; // Read soil moisture or water level based on the flag if (pumpMode == 0) { int soilSensorValue = analogRead(soilMoisturePin); Serial.println(soilSensorValue); mappedSoilMoisture = map(soilSensorValue, 1023, 2750, 100, 0); // Update mappedSoilMoisture autoControlPump(mappedSoilMoisture); // Automatically control the pump based on soil moisture if in automatic mode } |
Считываем уровень воды с датчика уровня воды. Если уровень воды ниже порогового значения (450), то устанавливаем уровень воды равным 0. В противном случае он отображает значение уровня воды в диапазоне от 0 до 100.
1 2 3 4 5 6 7 8 |
// Read water level waterLevel = analogRead(waterLevelPin); Serial.println(waterLevel); if (waterLevel < 450) { waterLevel = 0; // Set water level to 0 if below a threshold } else { waterLevel = map(waterLevel, 1200, 1600, 0, 100); // Map water level to 0-100 } |
Вызываем функцию controlLED для управления светодиодом на основе сопоставленного уровня влажности почвы. Затем он вызывает функцию readAndSendSensorData, чтобы считывать температуру и влажность с датчика DHT и отправлять данные в приложение Blynk. Кроме того, он отправляет уровень воды в Blynk.
1 2 3 4 5 6 7 8 |
// Control LED controlLED(mappedSoilMoisture); // Read and send sensor data readAndSendSensorData(); Blynk.virtualWrite(V7, waterLevel); // Send water level to Blynk } } |
Тестирование работы проекта умной ирригации на основе ESP32
Водяной насос в нашем проекте предназначен для полного погружения в воду. Выпускная труба насоса расположена на поле для орошения.
Датчик влажности почвы вставляется в почву, а датчик уровня воды погружается в резервуар для воды. После включения устройства и открытия приложения Blynk ESP32 автоматически подключается к вашему Wi-Fi, предоставляя данные о влажности почвы, уровне воды, влажности и температуре воздуха в режиме реального времени непосредственно в приложении Blynk.
В автоматическом режиме, если влажность почвы снижается, автоматически включается водяной насос, орошающий поле до тех пор, пока не будет достигнут желаемый уровень влажности. Между тем, в ручном режиме у вас есть возможность управлять насосом вручную, включая или выключая его по вашему усмотрению. Для визуальной демонстрации его полной функциональности вы можете просмотреть подробную работу, показанную в видео ниже.
Исходный код программы
Все файлы для изготовления данного проекта можно скачать по следующей ссылке.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
//ESP32 smart irrigation code #define BLYNK_TEMPLATE_ID "Replace your BLYNK_TEMPLATE_ID here" #define BLYNK_TEMPLATE_NAME "Replace your BLYNK_TEMPLATE_NAME here" #define BLYNK_AUTH_TOKEN "Replace your BLYNK_AUTH_TOKEN here" #define BLYNK_PRINT Serial #include <WiFi.h> #include <BlynkSimpleEsp32.h> #include "DHT.h" #include <FastLED.h> char auth[] = BLYNK_AUTH_TOKEN; char ssid[] = "Wifi Name"; char pass[] = "Wifi Password"; #define LED_PIN 21 #define BRIGHTNESS 255 #define LED_TYPE WS2811 #define COLOR_ORDER GRB const uint8_t kMatrixWidth = 16; const uint8_t kMatrixHeight = 16; const bool kMatrixSerpentineLayout = true; #define NUM_LEDS (kMatrixWidth * kMatrixHeight) #define MAX_DIMENSION ((kMatrixWidth>kMatrixHeight) ? kMatrixWidth : kMatrixHeight) // The leds CRGB leds[kMatrixWidth * kMatrixHeight]; BlynkTimer timer; bool ledStripOn = false; // The 16 bit version of our coordinates static uint16_t x; static uint16_t y; static uint16_t z; uint16_t speed = 20; // speed is set dynamically once we've started up uint16_t scale = 30; // scale is set dynamically once we've started up uint8_t noise[MAX_DIMENSION][MAX_DIMENSION]; CRGBPalette16 currentPalette( PartyColors_p ); uint8_t colorLoop = 1; #define DHTPIN 4 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); const int soilMoisturePin = 35; // Analog pin for the soil moisture sensor const int waterLevelPin = 34; // Analog pin for the water level sensor const int ledPin = 2; // Constants for soil moisture thresholds const int SOIL_MOISTURE_LOW = 50; // Adjusted to match the 0-100 range const int SOIL_MOISTURE_HIGH = 50; // Adjusted to match the 0-100 range const int pumpPin = 5; // Change this to the actual pin connected to the DC pump on ESP32 int pumpState = LOW; // Initialize pumpState to LOW (off) int pumpMode = 0; // 0 for automatic, 1 for manual int waterLevel = 0; // Water level indicator value unsigned long previousMillis = 0; const unsigned long interval = 1000; // Interval in milliseconds float mappedSoilMoisture = 0; // Declare mappedSoilMoisture as a global variable void setup() { Serial.begin(115200); digitalWrite(pumpPin,LOW); pinMode(ledPin, OUTPUT); pinMode(pumpPin, OUTPUT); dht.begin(); Blynk.begin(auth, ssid, pass); Blynk.virtualWrite(V2, LOW); Blynk.virtualWrite(V3, "LED OFF"); Blynk.virtualWrite(V6, LOW); // Initialize the mode button to automatic mode Blynk.virtualWrite(V5, LOW); // Initialize the pump button to OFF Blynk.virtualWrite(V8, LOW); // Initialize the new feature button to OFF delay(3000); LEDS.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds,80); LEDS.setBrightness(BRIGHTNESS); // Initialize our coordinates to some random values x = random16(); y = random16(); z = random16(); } BLYNK_WRITE(V5) { // This function is called when the pump button state changes (Manual Control) if (pumpMode == 1) { // Check if the mode is manual pumpState = param.asInt(); // Read the state of the pump button (0 for OFF, 1 for ON) digitalWrite(pumpPin, pumpState); // Turn the pump on or off based on button state } } BLYNK_WRITE(V6) { // This function is called when the mode button state changes pumpMode = param.asInt(); // Read the state of the mode button (0 for automatic, 1 for manual) } BLYNK_WRITE(V8) { int value = param.asInt(); if (value == 1) { // Turn on the LED strip and start the animation ledStripOn = true; } else { // Turn off the LED strip ledStripOn = false; // You can also add code to clear the LED strip here if needed } } // Fill the x/y array of 8-bit noise values using the inoise8 function. void fillnoise8() { // If we're runing at a low "speed", some 8-bit artifacts become visible // from frame-to-frame. In order to reduce this, we can do some fast data-smoothing. // The amount of data smoothing we're doing depends on "speed". uint8_t dataSmoothing = 0; if( speed < 50) { dataSmoothing = 200 - (speed * 4); } for(int i = 0; i < MAX_DIMENSION; i++) { int ioffset = scale * i; for(int j = 0; j < MAX_DIMENSION; j++) { int joffset = scale * j; uint8_t data = inoise8(x + ioffset,y + joffset,z); // The range of the inoise8 function is roughly 16-238. // These two operations expand those values out to roughly 0..255 // You can comment them out if you want the raw noise data. data = qsub8(data,16); data = qadd8(data,scale8(data,39)); if( dataSmoothing ) { uint8_t olddata = noise[i][j]; uint8_t newdata = scale8( olddata, dataSmoothing) + scale8( data, 256 - dataSmoothing); data = newdata; } noise[i][j] = data; } } z += speed; // apply slow drift to X and Y, just for visual variation. x += speed / 8; y -= speed / 16; } void mapNoiseToLEDsUsingPalette() { static uint8_t ihue=0; for(int i = 0; i < kMatrixWidth; i++) { for(int j = 0; j < kMatrixHeight; j++) { // We use the value at the (i,j) coordinate in the noise // array for our brightness, and the flipped value from (j,i) // for our pixel's index into the color palette. uint8_t index = noise[j][i]; uint8_t bri = noise[i][j]; // if this palette is a 'loop', add a slowly-changing base value if( colorLoop) { index += ihue; } // brighten up, as the color palette itself often contains the // light/dark dynamic range desired if( bri > 127 ) { bri = 255; } else { bri = dim8_raw( bri * 2); } CRGB color = ColorFromPalette( currentPalette, index, bri); leds[XY(i,j)] = color; } } ihue+=1; } void loop() { Blynk.run(); timer.run(); updateLEDStrip(); unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; // Read soil moisture or water level based on the flag if (pumpMode == 0) { int soilSensorValue = analogRead(soilMoisturePin); Serial.println(soilSensorValue); mappedSoilMoisture = map(soilSensorValue, 1023, 2750, 100, 0); // Update mappedSoilMoisture autoControlPump(mappedSoilMoisture); // Automatically control the pump based on soil moisture if in automatic mode } // Read water level waterLevel = analogRead(waterLevelPin); Serial.println(waterLevel); if (waterLevel < 450) { waterLevel = 0; // Set water level to 0 if below a threshold } else { waterLevel = map(waterLevel, 1200, 1600, 0, 100); // Map water level to 0-100 } // Control LED controlLED(mappedSoilMoisture); // Read and send sensor data readAndSendSensorData(); Blynk.virtualWrite(V7, waterLevel); // Send water level to Blynk } } void autoControlPump(float mappedSoilMoisture) { if (waterLevel < 30 || waterLevel < 20) { // Water level is too low, do not turn on the pump pumpState = LOW; digitalWrite(ledPin, LOW); Blynk.virtualWrite(V2, HIGH); Blynk.setProperty(V2, "color", "#D3435C"); } else if (mappedSoilMoisture <= SOIL_MOISTURE_LOW) { // If soil moisture is below the threshold and water level is okay, turn the pump ON pumpState = HIGH; } else if (mappedSoilMoisture >= SOIL_MOISTURE_HIGH) { // If soil moisture is above the threshold, turn the pump OFF pumpState = LOW; } digitalWrite(pumpPin, pumpState); // Update the pump state if (pumpMode == 0) { Blynk.virtualWrite(V5, pumpState); // Update the pump button status on Blynk } } void controlLED(float mappedSoilMoisture) { if (mappedSoilMoisture <= SOIL_MOISTURE_LOW) { digitalWrite(ledPin, HIGH); Blynk.virtualWrite(V2, HIGH); Blynk.setProperty(V2, "color", "#00FF00"); Blynk.virtualWrite(V3, "LED ON"); Blynk.setProperty(V3, "color", "#00FF00"); } else if (mappedSoilMoisture >= SOIL_MOISTURE_HIGH) { digitalWrite(ledPin, LOW); Blynk.virtualWrite(V2, HIGH); Blynk.setProperty(V2, "color", "#D3435C"); Blynk.virtualWrite(V3, "LED OFF"); Blynk.setProperty(V3, "color", "#D3435C"); } } void readAndSendSensorData() { float humidity = dht.readHumidity(); float temperature = dht.readTemperature(); if (!isnan(humidity) && !isnan(temperature)) { Blynk.virtualWrite(V0, temperature); Blynk.virtualWrite(V1, humidity); Serial.println(temperature); Serial.println(humidity); } else { Serial.println(F("Failed to read from DHT sensor!")); } if (pumpMode == 0) { Blynk.virtualWrite(V4, mappedSoilMoisture); // Update mappedSoilMoisture on Blynk } } void updateLEDStrip() { if (ledStripOn) { // Your LED strip animation code here // This code will run when the LED strip is turned on // Make sure to update the leds array // For example, mapNoiseToLEDsUsingPalette(); ChangePaletteAndSettingsPeriodically(); fillnoise8(); // Call the noise generation function mapNoiseToLEDsUsingPalette(); // Map the noise data to LEDs LEDS.show(); // Show the LEDs // You may need to adjust the animation speed based on your preference delay(10); // Delay between frames (adjust as needed) } else { // Turn off the LED strip // You can also add code to clear the LED strip here if needed fill_solid(leds, NUM_LEDS, CRGB::Black); LEDS.show(); } } // There are several different palettes of colors demonstrated here. // // FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p, // OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p. // // Additionally, you can manually define your own color palettes, or you can write // code that creates color palettes on the fly. // 1 = 5 sec per palette // 2 = 10 sec per palette // etc #define HOLD_PALETTES_X_TIMES_AS_LONG 1 void ChangePaletteAndSettingsPeriodically() { uint8_t secondHand = ((millis() / 1000) / HOLD_PALETTES_X_TIMES_AS_LONG) % 60; static uint8_t lastSecond = 99; if( lastSecond != secondHand) { lastSecond = secondHand; if( secondHand == 0) { currentPalette = RainbowColors_p; speed = 20; scale = 30; colorLoop = 1; } if( secondHand == 5) { SetupPurpleAndGreenPalette(); speed = 10; scale = 50; colorLoop = 1; } if( secondHand == 10) { SetupBlackAndWhiteStripedPalette(); speed = 20; scale = 30; colorLoop = 1; } if( secondHand == 15) { currentPalette = ForestColors_p; speed = 8; scale =120; colorLoop = 0; } if( secondHand == 20) { currentPalette = CloudColors_p; speed = 4; scale = 30; colorLoop = 0; } if( secondHand == 25) { currentPalette = LavaColors_p; speed = 8; scale = 50; colorLoop = 0; } if( secondHand == 30) { currentPalette = OceanColors_p; speed = 20; scale = 90; colorLoop = 0; } if( secondHand == 35) { currentPalette = PartyColors_p; speed = 20; scale = 30; colorLoop = 1; } if( secondHand == 40) { SetupRandomPalette(); speed = 20; scale = 20; colorLoop = 1; } if( secondHand == 45) { SetupRandomPalette(); speed = 50; scale = 50; colorLoop = 1; } if( secondHand == 50) { SetupRandomPalette(); speed = 90; scale = 90; colorLoop = 1; } if( secondHand == 55) { currentPalette = RainbowStripeColors_p; speed = 30; scale = 20; colorLoop = 1; } } } // This function generates a random palette that's a gradient // between four different colors. The first is a dim hue, the second is // a bright hue, the third is a bright pastel, and the last is // another bright hue. This gives some visual bright/dark variation // which is more interesting than just a gradient of different hues. void SetupRandomPalette() { currentPalette = CRGBPalette16( CHSV( random8(), 255, 32), CHSV( random8(), 255, 255), CHSV( random8(), 128, 255), CHSV( random8(), 255, 255)); } // This function sets up a palette of black and white stripes, // using code. Since the palette is effectively an array of // sixteen CRGB colors, the various fill_* functions can be used // to set them up. void SetupBlackAndWhiteStripedPalette() { // 'black out' all 16 palette entries... fill_solid( currentPalette, 16, CRGB::Black); // and set every fourth one to white. currentPalette[0] = CRGB::White; currentPalette[4] = CRGB::White; currentPalette[8] = CRGB::White; currentPalette[12] = CRGB::White; } // This function sets up a palette of purple and green stripes. void SetupPurpleAndGreenPalette() { CRGB purple = CHSV( HUE_PURPLE, 255, 255); CRGB green = CHSV( HUE_GREEN, 255, 255); CRGB black = CRGB::Black; currentPalette = CRGBPalette16( green, green, black, black, purple, purple, black, black, green, green, black, black, purple, purple, black, black ); } // // Mark's xy coordinate mapping code. See the XYMatrix for more information on it. // uint16_t XY( uint8_t x, uint8_t y) { uint16_t i; if( kMatrixSerpentineLayout == false) { i = (y * kMatrixWidth) + x; } if( kMatrixSerpentineLayout == true) { if( y & 0x01) { // Odd rows run backwards uint8_t reverseX = (kMatrixWidth - 1) - x; i = (y * kMatrixWidth) + reverseX; } else { // Even rows run forwards i = (y * kMatrixWidth) + x; } } return i; } |
6 ответов к “Умная ирригационная система на ESP32 и приложении Blynk”
Добрый день. Купил все необходимое, плату esp32. Пробую её подключить к вай фай. Пробую повторить ваш проект. Но все равно не получается. Стою на месте. Может у вас есть возможность индивидуально объяснить что делаю не так?
Доброе утро. К сожалению, индивидуально вряд ли получится. Если у вас не получается подключить модуль ESP32 к сети WiFi я советую вам начать с более простого проекта (этот проект все таки сложноват для начинающих) — таких проектов на нашем сайте достаточно много. И этот проект я бы советовал вам пробовать в упрощенном варианте, например, без светодиодной ленты — в этом случае код данного проекта значительно упростится
Можно использовать насос на 12 вольт и что для этого нужно ещё сделать?
Добрый день, да, можно. Необходимо использовать модуль реле на 12 В, а питание на остальную часть схемы подавать через понижающий стабилизатор напряжения, например, микросхему AMS1117, и в этом случае питание на модуль ESP32 необходимо подавать на его контакт Vin, чтобы не сжечь модуль
Добрый день. А как быть если нужно сделать например на три горшка?
Как понимаю что реле нужно уже трех контактное, три насоса, три датчика влажности.. И как изменится сам код?
Добрый вечер. Да, реле нужно будет трехконтактное, каждым контактом будем управлять отдельно с контакта модуля ESP32. В автоматическом режиме нужно будет три раза повторить код:
int soilSensorValue = analogRead(soilMoisturePin);
Serial.println(soilSensorValue);
mappedSoilMoisture = map(soilSensorValue, 1023, 2750, 100, 0);
autoControlPump(mappedSoilMoisture);
В функцию analogRead при этом передавать номера контактов, к которым подключены датчики, а в функцию autoControlPump добавить в качестве аргумента номер контакта, с которого будем управлять реле, и все эти три раза передавать туда этих три разных контакта.