Ako merať hĺbku vodnej nádrže pomocou ultrazvukového senzora

Ako merať hĺbku vodnej nádrže pomocou ultrazvukového senzora
Elektrolab Pridal  Elektrolab
  429 zobrazení
2
 0
Arduino a príbuzné platformy

V tomto článku sa dozviete, ako používať ultrazvukový senzora konkrétne sa dozviete, ako používať modul HC-SR04 v spojení s Arduinom na meranie hĺbky vodnej nádrže. Ultrazvukový snímač, či hladinomer je jednou z tých vecí, do ktorých sa niektorí ľudia neradi púšťajú len preto, že ich používanie a pochopenie práce s ním znie zložito. Faktom však je, že je to jedno z najdostupnejších a najzábavnejších príslušenstiev pre tých, ktorí sa  venujú mikrokontrolérom.

Kde kúpiť?

Ultrazvukový senzor HC-SR04 - Klikni (Banggood)

Ultrazvukový senzor HC-SR04 - Klikni (Aliexpress)

Arduino UNO - klikni (Banggood)

Arduino UNO - klikni (Aliexpress)

V prípade Arduina existuje viacero jednoduchých riešení, pretože existuje niekoľko veľmi spoľahlivých knižníc určených práve pre prácu s týmto senzorom. A pre tých, ktorí chcú ešte viac preniknúť do technických detailov senzora, sú k dispozícii repozitáre na stránke GitHub pre všetkých zdarma.

Existujú dve veci, ktoré uľahčujú používanie tohto typu senzora. Po prvé, jeho pripojenie je veľmi jednoduché, pretože vyžaduje len priame prepojenie medzi modulom a mikrokontrolérom. Po druhé, vďaka modulu je funkčnosť snímača relatívne jednoduchá. Túto časť lepšie pochopíte, keď sa nižšie dostaneme k jeho fungovaniu a popisu kódu.

Schéma zapojenia

Budete potrebovať nasledujúci softvér:

Majte na pamäti, že tento typ projektu by mal byť schopný spustiť akýkoľvek mikrokontrolér, ale my budeme pracovať konkrétne s Arduino IDE. Aby ste mohli postupovať podľa týchto pokynov, musí byť vaša doska kompatibilná aspoň s ním.

Ako funguje ultrazvukový senzor?

Základný princíp ultrazvukového snímača je pomerne jednoduchý: vysiela zvukové vlny zo svojho vysielača. Keď zvuk narazí na objekt, vytvorí sa odraz, ktorý sa odrazí späť k snímaču. Senzor používa mikrofón na detekciu tohoto odrazu. Rýchlosť zvukových vĺn je 343 m/s. Vynásobením tejto hodnoty s časom, za ktorý sa signál vrátil, získate vzdialenosť, ktorú signál prešiel. Keďže signál najprv putoval k objektu a potom späť, vzdialenosť k objektu získate vydelením dvoma. Modul HC-SR04 potrebuje 10 µs impulz z Arduina na spustenie zvukovej vlny vysielanej modulom. Arduino potom čaká na prichádzajúci impulz z modulu a použije čas potrebný na získanie vzdialenosti. Na to však nemusíte myslieť, pretože knižnica, ktorú budete používať, obsahuje všetko potrebné.

Poďme na kód

Pokiaľ ide o kód, najprv je potrebné zvážiť knižnice, ktoré musia byť zahrnuté. Potrebujeme iba jednu:

#include “HCSR04.h”

Potom musíme deklarovať všetky premenné a konštanty, ktoré budeme používať. Táto časť je rozdelená na dve časti: konfiguračné konštanty pinov a premenné súvisiace s ukladaním údajov:

/*PIN CONFIG*/
const int trig = 12; //Trigger pin
const int echo = 13; //Echo pin

*/VARIABLES*/ float distBuff; //Vyrovnávacia pamäť pre nespracovanú vzdialenosť snímanú snímačom
int tankFinal; //Konečná percentuálna hodnota plnosti nádrže
float allDist; //Súčet všetkých vzdialeností v allDist
float avgDist; //Súčet všetkých vzdialeností v allDist
int i; //Náhodná premenná používaná na riadenie slučky

Tu inicializujeme triedu modulu ultrazvukového senzora a ako vidíte, pridáme piny, ktoré bude používať:

HCSR04 hc(trig, echo); //HCSR04 Initialization (trig pin, echo pin)

V rámci funkcie setup ju stačí inicializovať pre sériovú komunikáciu:

void setup() {
  Serial.begin(9600); //Inicializácia sériovej komunikácie
}

Potom vo vnútri funkcie loop zakódujeme proces, ktorý Arduino vykoná a ktorý sa bude opakovať stále dokola:

void loop() {
  allDist = 0; //Opätovné spustenie súčtu vzdialeností

  for(i = 0;i < 25;i++){
    delay(5); //Oneskorenie medzi jednotlivými čítaniami, aby sa zabránilo chybe
    distBuff = hc.dist(); //Vzdialenosť
    if(distBuff > 0 && distBuff < 301) //Zabezpečíme, aby sme brali iba hodnoty medzi fyzickými
    {
      allDist = allDist + distBuff; //Súčet vzdialeností
    }
  }

 avgDist = allDist / 25; //Delenie vzdialeností na získanie priemeru
 tankFinal = map(avgDist, 2, 300, 100, 0); //Prepočet priemeru na percentá
 Serial.println(tankFinal); //Zobrazenie percentuálnej hodnoty
}

Kód najprv zabezpečí, aby premenná, ktorá má na starosti ukladanie súčtu, bola prázdna, potom sa vytvorí cyklus, ktorý má na starosti snímanie 25 hodnôt zo snímača, pričom sa ignorujú všetky hodnoty mimo vzdialenosti nádrže na vodu. Po vykonaní všetkých odčítaní vypočítame priemer a potom pomocou funkcie map prepočítame vzdialenosť na percentá nádrže.

Problémy, ktoré sa vyskytli počas testovania

Hoci som tento modul senzorov používal aj v iných projektoch, tentoraz som sa pokúsil o trochu iný prístup, aby fungoval: Pridal som vyhladzovací algoritmus pre údaje prichádzajúce z modulu. Bez vyhladzovania by som mohol zakaždým len vypísať získané údaje, ale v tomto prípade som vzal určitý počet údajov a vypočítal priemer. Nič výnimočné ani nič, čo by som predtým nerobil pri mnohých iných projektoch.

Pri čítaní sa mi však opakovane vyskytovala chyba, ktorá sa prejavila týmto spôsobom:

  1. Kód sa spustí.
  2. Kód dokonale odčítal výšku medzi mojím stolom a stropom na 49 %.
  3. Pomocou objektu simulujem niečo na úrovni 90 %, čo funguje tak, ako má.
  4. Potom sa čítanie zasekne na hodnote približne 70 %, keď objekt odstránim. Nižšie už neklesne.
  5. Znovu použijem objekt na simuláciu niečoho na 90 %, čo opäť funguje tak, ako má.
  6. Potom sa údaje vrátia do správneho stavu na úrovni 49 %, keď odstránim objekt.
  7. Tento problém sa potom opakuje znova od bodu 3.

Strávil som veľké množstvo času kontrolou knižnice, ktorú som používal, a urobil som v nej niekoľko zmien. Skúšal som tiež reštartovať modul pri každom odčítaní, ale nič nepomohlo a stále som mal rovnaký problém. Začal som si myslieť, že chybný je samotný modul, ale po ďalšom testovaní som dospel k dôležitému zisteniu. Keď som skutočne sledoval samotné "surové" údaje, čítanie poskytovalo perfektné výsledky, ale to sa zastavilo hneď, ako som prestal zobrazovať surové údaje. Pokúsil som sa teda simulovať čas zobrazovania pridaním oneskorenia. Začal som s dlhým oneskorením 30 ms, ktoré problém úspešne odstránilo. Potom som skúšal oneskorenia od 1 ms, až kým som pri 5 ms nezískal správne údaje.

Takéto správanie nie je pre mňa úplne nezvyčajné, pretože niektoré moduly potrebujú na spracovanie údajov určitý čas, aby sa vyhli rôznym druhom rušenia. Háčik bol v tom, že keby to bol problém, stalo by sa to pri každom čítaní, ale v tomto prípade sa to prepínalo tam a späť vždy, keď to prekročilo 70 %. Hľadal som nejaké informácie v jednom z mnohých datasheetov modulu a v jednom z nich sa navrhoval cyklus merania 60 ms, "aby sa zabránilo spusteniu signálu na signál echa". Úprimne povedané, stále neviem, čo to znamená. Pravdu povediac, nepodarilo sa mi nájsť odbornejší datasheet o tomto module, ale modul potrebuje nejaký pridaný čas, aby jeho merací cyklus fungoval bez problémov. Vo väčšine online návodov to nemusí byť zrejmé, pretože všetky používajú funkciu zobrezenie výsledku po každom čítaní, ktoré zaberá čas a funguje ako nechcené oneskorenie meracieho cyklu.

Výsledný kód

#include "HCSR04.h"

/*PIN CONFIG*/
const int trig = 12; //Trigger pin
const int echo = 13; //Echo pin

/*VARIABLES*/
float distBuff; //Vyrovnávacia pamäť pre nespracovanú vzdialenosť
int tankFinal; //Konečná percentuálna hodnota plnosti nádrže
float allDist; //Súčet všetkých vzdialeností zaznamenaných snímačom
float avgDist; //Priemer zo všetkých vzdialeností v allDist int i; //Náhodná premenná používaná na riadenie slučiek

HCSR04 hc(trig, echo); //HCSR04 Inicializácia (trig pin , echo pin)

void setup() {
  Serial.begin(9600); //Inicializácia sériovej komunikácie
}

void loop() {
  allDist = 0; //Opätovné spustenie súčtu vzdialeností

  for(i = 0;i < 25;i++){
    delay(5); //oneskorenie medzi jednotlivými čítaniami, aby sa zabránilo chybe
    distBuff = hc.dist(); //Vzdialenosť
    if(distBuff > 0 && distBuff < 301) //Zabezpečíme, aby sme brali len hodnoty medzi fyzikálnymi možnými rozsahmi
    {
      allDist = allDist + distBuff; //Súčet vzdialeností
    }
 }

  avgDist = allDist / 25; //Delenie vzdialeností na získanie priemeru
  tankFinal = map(avgDist, 2, 300, 100, 0); //Prepočet priemeru na percentá
  Serial.println(tankFinal); //Zobrazenie percentuálnej hodnoty
}

Testovanie HC-SR04 s nádržou na vodu

Pre reálnejšie testovacie prostredie som použil nádrž na vodu, ktorú mám doma. Ide o podzemnú nádrž na dažďovú vodu, do ktorej sa v posledných dňoch dostalo veľké množstvo vody, takže som očakával, že nádrž bude viac ako z polovice plná. Pri testovaní v reálnych podmienkach treba mať na pamäti: ultrazvukový snímač môže prijímať impulzy z pomerne širokého rozsahu smerov, takže pri testovaní vo veľmi otvorenom priestore môžu byť údaje nepresné.

Nádrž je hlboká 2 metre, ale ďalšími rozmermi som si nie je istý. Zhotovenie prototypu tohto snímača nie je až také zložité, pretože jeho zapojenie je veľmi jednoduché.

Treba si uvedomiť, že ak by niekto, kto testuje toto zariadenie, chcel zariadenie vodotesne uzavrieť, musí ponechať senzor zariadenia mimo krytu. Potom už stačí len nastaviť výstupné zariadenie, ktorým bol v mojom prípade  počítač. Ako môžete vidieť v kóde, spracované údaje opakovane posielam prostredníctvom sériovej komunikácie, takže na zobrazenie výsledkov môžete použiť sériový monitor:

Pokiaľ si však výsledky budete chcieť pozrieť zaujímavejším spôsobom, môžte použiť program Processing. Tu Processing prijíma sériové údaje a prevádza ich na grafiku a číslo, ktoré môžete vidieť nižšie:

Záver

Ultrazvukový snímač môže znieť hrozivo, ale v skutočnosti je jeho používanie pomerne jednoduché a najlepšie na tom je, že vám umožní robiť veľa vecí. Často sa napríklad používa na detekciu prekážok v robotoch a podobne ako pri iných veciach v elektronike, je jeho jediným obmedzením iba predstavivosť samotného tvorcu.

Kde kúpiť?

Ultrazvukový senzor HC-SR04 - Klikni (Banggood)

Ultrazvukový senzor HC-SR04 - Klikni (Aliexpress)

Arduino UNO - klikni (Banggood)

Arduino UNO - klikni (Aliexpress)

Máte aj vy zaujímavú konštrukciu, alebo článok?

Máte aj vy zaujímavú konštrukciu, alebo článok a chceli by ste sa o to podeliť s viac ako 200.000 čitateľmi? Tak neváhajte a dajte nám vedieť, radi ju uverejníme a to vrátane obrazových a video príloh. Rovnako uvítame aj autorov teoretických článkov, či autorov zaujímavých videí z oblasti elektroniky / elektrotechniky.

Kontaktujte nás!


Páčil sa Vám článok? Pridajte k nemu hodnotenie, alebo podporte jeho autora.
 

       

Komentáre k článku

Zatiaľ nebol pridaný žiadny komentár k článku. Pridáte prvý? Berte prosím na vedomie, že za obsah komentára je zodpovedný užívateľ, nie prevádzkovateľ týchto stránok.
Pre komentovanie sa musíte prihlásiť.

Vaša reklama na tomto mieste

Vyhľadajte niečo na našom blogu

PCBWay Promo

ourpcb Promo

PCBWay Promo

ourpcb Promo

PCBWay Promo

ourpcb Promo


Webwiki Button