Obsah

Měření výšky hladiny a teploty vody v nádrži

Jedná se o bastl pro moji potřebu, pokud přijdete s čímkoliv elegantnějším, dejte mi prosím vědět - zajímá mě to.

Základní popis s příběhem

Spolu s pořízením a instalací nádrže na dešťovou vodu o objemu 5 m3 jsem chtěl mít přehled o tom, jak je nádrž plná bez toho, abych se tam musel nedej bože chodit dívat. Obecně mě zajímá nakolik jaký déšť nádrž doplní, o kolik klesne hladina při zalévání apod. Když už budu měřit hladinu, tak proč ne i teplotu - o jedno čidlo navíc už mě nezabije a alespoň uvidím, jaká je teplota vody když uhodí tropická vedra nebo naopak když přijdou (pokud ještě někdy ;-)) pořádné mrazy. Nádrž mám shora izolovanou polystyrénem a navíc jsem nad ní ještě udělal strop, takže očekávám minimální změny. Jímka je sice pochozí, ale vůbec se mi nelíbilo, že v určitých místech i přes extrudovaný polystyrén a zásyp pruží - nechtěl jsem její materiál zbytečně namáhat. Jde o takovýto typ nádrže:

Po poradě na Twitteru jsem se rozhodl pro měření ultrazvukem, po sestavení vyzkoušel několik pokusných měření a ukázalo se to jako funkční. Trvalé měření ale zatím nemám - pořád ještě potřebuji upravit okolí nádrže a montáž krabice bude až jako jedna z posledních činností.

Jak to funguje: změřím teplotu a opakovaně (kvůli odchylce) ultrazvukem výšku hladiny s tím, že čidlo umístím nahoru do servisního otvoru nádrže (komínku). Mezi čidlem a hladinou bude vždy odstup větší, než je minimální změřitelná vzdálenost. Na tmep.cz budu přes Wi-Fi každou minutu posílat teplotu spolu se vzdáleností převedenou na procentuální zaplnění nádrže, které bude na webu vidět jako vlhkost. Ale časem upravím i to :-)

Použité komponenty

Krabice, propojovací kablíky apod. jsem už měl. Případně koupíte v elektru, co se vám bude konkrétně hodit.

Vzhledem k tomu, že jsem nechtěl čekat až si budu moct hrát s projektem, pro který jsem se nadchnul, jsem základní součástky objednal v ČR - konkrétně z dratek.cz. Celkem mě to vyšlo na 1 028 Kč. Při objednávce z Číny byste určitě výrazně ušetřili, na druhou stranu rád podpořím český obchod a nejedná se o žádné horentní sumy.

ESP8266 ESP-12E OTA WeMos D1 CH340 WiFi Arduino IDE UNO R3
Ultrazvukový Vodotěsný Modul pro Měření Vzdálenosti pro Arduino JSN-SR04T
Teploměr vodotěsný - sonda 3m DS18B20
Napájecí adaptér síťový 5V 1000mA 5,5/2,1 mm VIGAN

Fotky z realizace

20221027-132907.jpeg

Zdrojový kód

Opět - jedná se o bastl, funkční rychlokvašku. V kódu je určitě potřeba nastavit/nahradit/upravit:

nadrz
/* 
 * Měření výšky hladiny a teploty v nádrži a následné odesílání na portál tmep.cz
 * 
 * Použité komponenty:
 * Prototypová deska Wemos D1
 * Ultrazvukový vodotěsný modul pro měření vzdálenosti JSN-SR04T
 * Dallas čidlo na teplotu
 * 
 * Zbastleno z příkladů na arduino-shop.cz a wiki.tmep.cz
 * 
 * https://arduino-shop.cz/arduino/1457-esp8266-esp-12e-ota-wemos-d1-ch340-wifi-arduino-ide-uno-r3.html
 * https://navody.arduino-shop.cz/navody-k-produktum/teplotni-senzor-ds18b20.html
 * https://navody.arduino-shop.cz/navody-k-produktum/ultrazvukovy-vodotesny-modul-pro-mereni-vzdalenosti-jsn-sr04t.html
 * https://wiki.tmep.cz/doku.php?id=zarizeni:esp8266
 * 
 */
 
// ESP
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <Ethernet.h>
// Ultrazvuk
#include <NewPing.h>
// Teplota
#include <OneWire.h>
#include <DallasTemperature.h>
 
// Pripojeni k wi-fi síti
const char* nazevWifi = "NAZEVWIFI";
const char* hesloWifi = "HESLOKWIFI";
 
// Piny a nastaveni
#define pinTrigger    5
#define pinEcho       4
#define maxVzdalenost 450
const int pinCidlaTeplomer = 14;
 
// Inicializace ultrazvukového měřícího modulu z knihovny
NewPing sonar(pinTrigger, pinEcho, maxVzdalenost);
// Vytvoření instance oneWireDS z knihovny OneWire
OneWire oneWireDS(pinCidlaTeplomer);
// Vytvoření instance senzoryDS z knihovny DallasTemperature
DallasTemperature senzoryDS(&oneWireDS);
// Pro TCP spojení
WiFiClient client;
 
// Pole kde indexem je namerena vzdalenost a hodnotou procentualni vyjadreni plnosti nadrze
int procenta[] = { 100, 99, 99, 98, 97, 97, 96, 95, 95, 94, 93, 93, 92, 91, 91, 90, 89, 89, 88, 87, 87, 86, 85, 85, 84, 83, 83, 82, 81, 81, 80, 79, 79, 78, 77, 77, 76, 75, 75, 74, 73, 73, 72, 71, 71, 70, 69, 69, 68, 67, 67, 66, 65, 65, 64, 63, 63, 62, 61, 61, 60, 59, 59, 58, 57, 57, 56, 55, 55, 54, 53, 53, 52, 51, 51, 50, 49, 49, 48, 47, 47, 46, 45, 45, 44, 43, 43, 42, 41, 41, 40, 39, 39, 38, 37, 37, 36, 35, 35, 34, 33, 33, 32, 31, 31, 30, 29, 29, 28, 27, 27, 26, 25, 25, 24, 23, 23, 22, 21, 21, 20, 19, 19, 18, 17, 17, 16, 15, 15, 14, 13, 13, 12, 11, 11, 10, 9, 9, 8, 7, 7, 6, 5, 5, 4, 3, 3, 2, 1, 1, 0 }; 
 
void setup()
{
  // Zahájení komunikace po sériové lince
  Serial.begin(9600);
 
  // Zapnutí komunikace knihovny s teplotním čidlem
  senzoryDS.begin();
 
  // Připojení k wifi
  WiFi.begin(nazevWifi, hesloWifi);
  // čekání na úspěšné připojení k routeru,
  // v průběhu čekání se vytiskne každých
  // 500 milisekund tečka po sériové lince
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Pripojeno k WiFi siti ");
  Serial.println(nazevWifi);
  Serial.print("IP adresa: ");
  Serial.println(WiFi.localIP());
}
 
void loop()
{
  // načtení informací ze všech připojených čidel na daném pinu
  senzoryDS.requestTemperatures();
  // výpis teploty na sériovou linku, při připojení více čidel
  // na jeden pin můžeme postupně načíst všechny teploty
  // pomocí změny čísla v závorce (0) - pořadí dle unikátní adresy čidel
  Serial.print("Teplota cidla DS18B20: ");
  Serial.print(senzoryDS.getTempCByIndex(0));
  Serial.println(" stupnu Celsia");
 
  // načtení vzdálenosti v centimetrech do vytvořené proměnné vzdalenost
  int vzdalenost = sonar.ping_cm();
  // pauza před dalším měřením
  delay(50);
  // pokud byla detekována vzdálenost větší než 0,
  // provedeme další měření
  if (vzdalenost > 0)
  {
    vzdalenost = 0;
    // pro získání stabilnějších výsledků provedeme 10 měření
    // a výsledky budeme přičítat do proměnné vzdalenost
    for(int i = 0; i < 10; i++)
    {
      vzdalenost += sonar.ping_cm();
      delay(50);
    }
    // v proměnné vzdálenost máme součet posledních 5 měření
    // a musíme tedy provést dělení 10 pro získání průměru
    vzdalenost = vzdalenost/10;
 
    // Odecteme kominek + odtok
    vzdalenost = vzdalenost - 45;
 
    if(vzdalenost > 150)
    {
        vzdalenost = 150;
    }
 
    if(vzdalenost < 0)
    {
        vzdalenost = 0;
    }
 
    // vytištění informací po sériové lince
    Serial.print("Vzdalenost mezi senzorem a predmetem je ");
    Serial.print(vzdalenost);
    Serial.println(" cm.");
  }
  // pokud byla detekována vzdálenost 0, je předmět mimo měřící rozsah,
  // tedy příliš blízko nebo naopak daleko
  else
  {
    Serial.println("Vzdalenost mezi senzorem a predmetem je mimo merici rozsah.");
    delay(500);
  }
 
  if(client.available())
  {
    char c = client.read();
    Serial.write(c);
  }
 
  // Kdyby bylo uz nejake spojeni nahodou otevrene...
  client.stop();
 
  // if there's a successful connection:
  if (client.connect("http://nadrz.tmep.cz", 80))
  {
    Serial.print("Pripojuji se na tmep.cz...");
 
    // send the HTTP GET request:
    client.print("GET /?");
    client.print("tep");
    client.print("=");
    client.print(senzoryDS.getTempCByIndex(0));
    client.print("&humV");
    client.print("=");
    client.print(procenta[vzdalenost]);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println("nadrz.tmep.cz");
    client.println("User-Agent: arduino-ethernet");
    client.println("Connection: close");
    client.println();
 
    Serial.println(" OK.");
  }
  else
  {
    // if you couldn't make a connection:
    Serial.println(" spojeni selhalo");
  }
 
  delay(60000);
}