В этом проекте мы узнаем, как сделать счетчик расхода воды на основе технологии Интернета вещей (IoT) с использованием NodeMCU ESP8266 и датчика расхода воды. Мы подключим датчик расхода воды на основе эффекта Холла YFS201 к плате NodeMCU ESP8266 и отобразим расход воды и общий ее объем на 0,96-дюймовом OLED-дисплее. Затем мы интегрируем наше оборудование с сервером Интернета вещей. Для сервера Интернета вещей мы будем использовать приложение Thingspeak. Данные о расходе и объеме воды можно будет загрузить на сервер Thingspeak и просматривать/контролировать из любой точки мира.
Ранее на нашем сайте мы рассматривали подключение датчика расхода воды YFS201 к плате Arduino.
Система управления водными ресурсами является важной частью городского управления. Управление водными ресурсами подразумевает подачу воды в соответствии с реальными потребностями и без потерь воды. Поэтому очень важно измерять расход и объем воды. Без измерения этих параметров управление водными ресурсами практически невозможно. Также стало очень важным удаленное отслеживание объема воды, расхода и качества воды с использованием подключения к Интернету. Поэтому существует необходимость в мониторинге системы управления водными ресурсами онлайн.
На рынке представлено множество датчиков расхода воды, но они слишком дороги в использовании. А многим требуется недорогой расходомер воды. Поэтому мы будем использовать датчик расхода воды на эффекте Холла YFS201 с платой NodeMCU ESP8266 и спроектируем простой расходомер воды на основе IoT.
Необходимые компоненты
- NodeMCU ESP8266 (купить на AliExpress).
- Датчик расхода воды (water flow sensor) YF-S201 (купить на AliExpress).
- Модуль OLED дисплея SSD1306 128×64 с интерфейсом I2C (купить на AliExpress).
- Макетная плата.
- Соединительные провода/перемычки.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Датчик расхода воды на эффекте Холла YF-S201
Это изображение датчика расхода воды на эффекте Холла YF-S201. Этот датчик можно подключить к водопроводу, поскольку у него есть как вход, так и выход. Внутри датчика находится вертушка, которая измеряет, сколько жидкости прошло через него. Имеется встроенный датчик магнитного эффекта Холла, который выдает электрический импульс при каждом обороте.
Датчик поставляется с тремя проводами:
1. Красный (питание 5-24 В постоянного тока).
2. Черный (заземление).
3. Желтый (импульсный выход Холла).
Расход воды можно рассчитать, подсчитав импульсы на выходе датчика. Каждый импульс составляет примерно 2,25 миллилитра. Этот датчик дешевле и лучше, но не самый точный, поскольку расход/объем немного варьируются в зависимости от расхода, давления жидкости и ориентации датчика. Чтобы получить точность измерений более 10%, требуется много калибровки. Вы можете сделать базовый счетчик расхода воды на основе Интернета вещей, используя этот датчик.
Импульсный сигнал представляет собой простую прямоугольную волну, поэтому его довольно легко зарегистрировать и преобразовать в литры в минуту, используя следующую формулу.
1 |
Pulse frequency (Hz) / 7.5 = flow rate in L/min |
Схема проекта
В нашем проекте OLED-дисплей будет показывать расход воды и общий объем воды, прошедшей через трубу. Те же данные о расходе и объеме могут регулярно отправляться на сервер Thingspeak с интервалом в 15 секунд. Также вы можете переключиться на использование приложения Blynk, если вам нужны немедленные данные. Аналогично, используя протокол MQTT, можно добиться лучшей беспроводной связи.
Схема подключения датчика расхода воды YF-S201 к NodeMCU ESP8266 представлена на следующем рисунке.
Датчик расхода воды — это цифровой датчик, поэтому мы можем подключить его выходной контакт к любому из цифровых контактов ESP8266. В моем случае я подключился к GPIO2 , т. е. D4 . Датчик работает при напряжении 5 В и может быть подключен к Vin ESP8266. Аналогично, контакты SDA и SCL I2C OLED-дисплея подключены к контактам D2 и D1 ESP8266 соответственно. OLED-дисплей работает при напряжении 3,3 В, поэтому его можно подключить к контакту 3,3 В Nodemcu.
Собранная на макетной плате конструкция проекта представлена на следующем рисунке.
Также, если хотите, конструкцию данного проекта можно собрать на специально спроектированной для этого печатной плате.
Печатная плата для проекта
Печатная плата для этого проекта была разработана в онлайн-инструменте для создания печатных плат EasyEDA. Ниже представлен вид спереди и вид сзади печатной платы.
Файл Gerber для изготовления данной печатной платы вы можете скачать по следующей ссылке.
Математический расчет для измерения расхода и объема воды
Мы можем определить скорость потока по изменению скорости воды. Скорость воды зависит от давления, которое заставляет проходить трубопроводы. Площадь поперечного сечения трубы известна и остается постоянной, поэтому мы вычисляем среднюю скорость, которая указывает на скорость потока.
Давайте рассмотрим Q — расход/общий расход воды через трубу, V — среднюю скорость, а A — площадь поперечного сечения трубы. В таком случае основное соотношение для определения расхода жидкости в таких случаях выглядит как Q=VxA
Частота датчика (Гц) = 7,5 * Q (литров/мин)
Литры = Q * прошедшее время (секунды) / 60 (секунды/минута)
Литры = (Частота (импульсы/секунду) / 7,5) * прошедшее время (секунды) / 60
Литры = Импульсы / (7,5 * 60)
Настройка Thingspeak
Теперь нам нужно настроить учетную запись Thingspeak. Чтобы настроить Thingspeak, выполните следующие шаги:
Шаг 1: Посетите https://thingspeak.com/ и создайте свою учетную запись, заполнив данные.
Шаг 2: Создайте новый канал, нажав “Channel” («Канал») и заполнив следующие данные, как показано на изображении ниже.
Шаг 3: Нажмите на API Key, вы увидите «Write API Key». Скопируйте API Key. Это очень важно поскольку данный API ключ потребуется нам при написании кода программы.
Шаг 4: Вы можете нажать “Private View” («Частный просмотр») и настроить окно отображения по своему усмотрению.
Исходный код программы
Теперь давайте посмотрим на код датчика расхода воды ESP8266 с использованием Arduino IDE. Код можно напрямую загрузить на плату NodeMCU. Но перед этим нам понадобится несколько библиотек для OLED-дисплея. Поэтому сначала загрузите библиотеки и добавьте их в Arduino IDE.
Измените ключ API Thingspeak, SSID Wi-Fi и пароль в следующих строках.
1 2 3 |
String apiKey = "KBD1JSZTUKCXJ15V"; const char *ssid = "Alexahome"; const char *pass = "loranthus"; |
Полный исходный код приведен ниже.
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 |
#include <ESP8266WiFi.h> #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); String apiKey = "KBD1JSZTUKCXJ15V"; // Enter your Write API key from ThingSpeak const char *ssid = "Alexahome"; // replace with your wifi ssid and wpa2 key const char *pass = "loranthus"; const char* server = "api.thingspeak.com"; #define LED_BUILTIN 16 #define SENSOR 2 long currentMillis = 0; long previousMillis = 0; int interval = 1000; boolean ledState = LOW; float calibrationFactor = 4.5; volatile byte pulseCount; byte pulse1Sec = 0; float flowRate; unsigned long flowMilliLitres; unsigned int totalMilliLitres; float flowLitres; float totalLitres; void IRAM_ATTR pulseCounter() { pulseCount++; } WiFiClient client; void setup() { Serial.begin(115200); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //initialize with the I2C addr 0x3C (128x64) display.clearDisplay(); delay(10); pinMode(LED_BUILTIN, OUTPUT); pinMode(SENSOR, INPUT_PULLUP); pulseCount = 0; flowRate = 0.0; flowMilliLitres = 0; totalMilliLitres = 0; previousMillis = 0; attachInterrupt(digitalPinToInterrupt(SENSOR), pulseCounter, FALLING); } void loop() { currentMillis = millis(); if (currentMillis - previousMillis > interval) { pulse1Sec = pulseCount; pulseCount = 0; // Because this loop may not complete in exactly 1 second intervals we calculate // the number of milliseconds that have passed since the last execution and use // that to scale the output. We also apply the calibrationFactor to scale the output // based on the number of pulses per second per units of measure (litres/minute in // this case) coming from the sensor. flowRate = ((1000.0 / (millis() - previousMillis)) * pulse1Sec) / calibrationFactor; previousMillis = millis(); // Divide the flow rate in litres/minute by 60 to determine how many litres have // passed through the sensor in this 1 second interval, then multiply by 1000 to // convert to millilitres. flowMilliLitres = (flowRate / 60) * 1000; flowLitres = (flowRate / 60); // Add the millilitres passed in this second to the cumulative total totalMilliLitres += flowMilliLitres; totalLitres += flowLitres; // Print the flow rate for this second in litres / minute Serial.print("Flow rate: "); Serial.print(float(flowRate)); // Print the integer part of the variable Serial.print("L/min"); Serial.print("\t"); // Print tab space display.clearDisplay(); display.setCursor(10,0); //oled display display.setTextSize(1); display.setTextColor(WHITE); display.print("Water Flow Meter"); display.setCursor(0,20); //oled display display.setTextSize(2); display.setTextColor(WHITE); display.print("R:"); display.print(float(flowRate)); display.setCursor(100,28); //oled display display.setTextSize(1); display.print("L/M"); // Print the cumulative total of litres flowed since starting Serial.print("Output Liquid Quantity: "); Serial.print(totalMilliLitres); Serial.print("mL / "); Serial.print(totalLitres); Serial.println("L"); display.setCursor(0,45); //oled display display.setTextSize(2); display.setTextColor(WHITE); display.print("V:"); display.print(totalLitres); display.setCursor(100,53); //oled display display.setTextSize(1); display.print("L"); display.display(); } if (client.connect(server, 80)) // "184.106.153.149" or api.thingspeak.com { String postStr = apiKey; postStr += "&field1="; postStr += String(float(flowRate)); postStr += "&field2="; postStr += String(totalLitres); postStr += "\r\n\r\n"; client.print("POST /update HTTP/1.1\n"); client.print("Host: api.thingspeak.com\n"); client.print("Connection: close\n"); client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n"); client.print("Content-Type: application/x-www-form-urlencoded\n"); client.print("Content-Length: "); client.print(postStr.length()); client.print("\n\n"); client.print(postStr); } client.stop(); } |
Мониторинг расхода и объема воды
После загрузки кода OLED-дисплей начнет работать и покажет расход и объем воды. Первоначально расход будет 0 литров/минуту (л/м). Также показанный общий объем будет 0 литров(л).
После включения двигателя и начала потока воды вы увидите на OLED-дисплее скорость потока (F) и объем (V).
Теперь вы также можете отслеживать данные о расходе и объеме воды на сервере Thingspeak. Вам просто нужно посетить Private View (частный просмотр) в панели инструментов Thingspeak.