marți, 19 martie 2013

Senzorul ultrasonic de distanta HC-SR04 si Arduino

    Am facut (si primit dupa 5 saptamani) o comanda-test de 7,70$ la chinezii de la DealExtreme (dx.com) pentru 3 produse, dintre care si un senzor ultrasonic de distanta HC-SR04, care poate masura distanta intre senzor si un obiect intre 2cm si 4m (4,5-5m dupa alte surse) la un unghi de maxim 15 grade, cu o precizie de 3mm. 




   Modulul HC-SR04 are 4 pini:
- alimentare +5V
- initiere semnal (TRIGGER)
- raspuns semnal (ECHO)
- masa (GND)



   Am gasit 2 variante de fisa tehnica (datasheet): una la  http://www.micropik.com/PDF/HCSR04.pdf si una la http://jaktek.com/wp-content/uploads/2011/12/HC-SR04.pdf.
   Din cele 2 am extras ca dupa trimiterea unui semnal pe terminalul TRIGGER cu durata de 10us (zece microsecunde), se asteapta raspunsul pe terminalul ECHO, iar durata acestui impuls obtinut impartit la 38 va da distanta pana la un obiect in cm; daca nu este nici un obstacol, timpul de raspuns este de 58ms. Durata impulsului obtinut la terminaul ECHO are durata intre 150us, corespunzatoare distantei de 2,58cm, si 25ms, corespunzatoare distantei de 4,31m=431cm.
   La o prima cautare a unui articol despre modulul HC-SR04 si Arduino, am dat de How to interface the HC-SR04 ultrasonic ranging module to Arduino in care este prezentat si un sketch, pentru afisarea pe ecranul calculatorului a distantei.

/*
 * Define the pins you want to use as trigger and echo.
 */

#define ECHOPIN 2        // Pin to receive echo pulse
#define TRIGPIN 3        // Pin to send trigger pulse

/*
 * setup function
 * Initialize the serial line (D0 & D1) at 115200.
 * Then set the pin defined to receive echo in INPUT 
 * and the pin to trigger to OUTPUT.
 */
 
void setup()
{
  Serial.begin(115200);
  pinMode(ECHOPIN, INPUT);
  pinMode(TRIGPIN, OUTPUT);
}

/*
 * loop function.
 * 
 */
void loop()
{
  // Start Ranging
  digitalWrite(TRIGPIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIGPIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGPIN, LOW);
  // Compute distance
  float distance = pulseIn(ECHOPIN, HIGH);
  distance= distance/58;
  Serial.println(distance);
  delay(200);
}
    Schema se conectare a modului la Arduino fiind:



   Aceasta schema se poate completa cu un afisaj LCD cu 2 randuri a 16 coloane.

   Va recomand sa studiati si articolul Ping Ultrasonic Range Finder de pe site-ul oficial ARDUINO este prezentat un senzor cu 3 pinii, adica e un terminal comun pentru trimitere si primire date despre distanta.




miercuri, 20.03.2013
   Dupa ce am realizat realizat montajul, am incarcat sketch-ul putin modificat deoarece eu am conectat terminalul TRIG la terminalul digital 9 (D9) al lui Arduino, iar pe ECHO la D8, deoarece eu am si partea de afisaj conectata:

#define ECHOPIN 8       // Pin to receive echo pulse
#define TRIGPIN 9        // Pin to send trigger pulse





   Dupa incarcarea sketch-ului am constat ca pe ecranul de monitorizare seriala am numai ciudatenii, datorita diferentei dintre viteza de transfer pe serial, in sketch de 115200bps, iar la monitorizare de 9600bps. Dupa ce am modificat la ecranul de monitorizare la 115200bps valorile au inceput sa arate normal.





   Am verificat distanta cu o rigla pentru o distanta mica de cca. 40cm si a fost ok, apoi o distanta de cca. 2m cu un telemetru si eroarea a fost de cca. 2mm, deci e ok.

  Am adaptat sketch-ul pentru a afisa distanta pe afisajul LCD 16x2:


// from http://www.xappsoftware.com/wordpress/2012/03/15/how-to-interface-the-hc-sr04-ultrasonic-ranging-module-to-arduino/

#define ECHOPIN 8      // Pin to receive echo pulse
#define TRIGPIN 9        // Pin to send trigger pulse

// from  http://arduino.cc/en/Tutorial/LiquidCrystalDisplay
// The circuit LCD 16x2:
// * LCD RS pin to digital pin 12
// * LCD Enable pin to digital pin 11
// * LCD D4 pin to digital pin 5
// * LCD D5 pin to digital pin 4
// * LCD D6 pin to digital pin 3
// * LCD D7 pin to digital pin 2
// * LCD R/W pin to ground
// * 10K resistor:
// * ends to +5V and ground
// * wiper to LCD VO pin (pin 3)

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// adapted sketch for ultrasonic module HC-SR04 and 16x2 LCD by niq_ro
// http://www.tehnic.go.ro 
// http://www.nicuflorica.blogspot.com

void setup()
{
  pinMode(ECHOPIN, INPUT);
  pinMode(TRIGPIN, OUTPUT);
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("www.tehnic.go.ro");
  lcd.setCursor(0, 1);
  lcd.print("creat de niq_ro");
  delay(2000);
  // clear the screen
  lcd.clear();
}

/*
 * loop function.
 * 
 */
void loop()
{
  // Start Ranging
  digitalWrite(TRIGPIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIGPIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGPIN, LOW);
  // Compute distance
  float distance = pulseIn(ECHOPIN, HIGH);
  distance= distance/58;
  // prind data on LCD  
  lcd.setCursor(0, 0);
  lcd.print("distanta este de");
  lcd.setCursor(2, 1);
  lcd.print("            ");
  lcd.setCursor(5, 1);
  lcd.print(distance);
  lcd.print("cm");
  delay(1000);
  //lcd.clear();
  
}




    Am modificat sketch-ul sa afiseze in mm, fara zecimale si sa faca o medie a 100 de masuratori, fiecare realiazata la 10ms una de alta:


// from http://www.xappsoftware.com/wordpress/2012/03/15/how-to-interface-the-hc-sr04-ultrasonic-ranging-module-to-arduino/

#define ECHOPIN 8        // Pin to receive echo pulse
#define TRIGPIN 9        // Pin to send trigger pulse

// from  http://arduino.cc/en/Tutorial/LiquidCrystalDisplay
// The circuit LCD 16x2:
// * LCD RS pin to digital pin 12
// * LCD Enable pin to digital pin 11
// * LCD D4 pin to digital pin 5
// * LCD D5 pin to digital pin 4
// * LCD D6 pin to digital pin 3
// * LCD D7 pin to digital pin 2
// * LCD R/W pin to ground
// * 10K resistor:
// * ends to +5V and ground
// * wiper to LCD VO pin (pin 3)

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// adapted sketch for ultrasonic module HC-SR04 and 16x2 LCD by niq_ro
// http://www.tehnic.go.ro 
// http://www.nicuflorica.blogspot.com

void setup()
{
  pinMode(ECHOPIN, INPUT);
  pinMode(TRIGPIN, OUTPUT);
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("www.tehnic.go.ro");
  lcd.setCursor(0, 1);
  lcd.print("creat de niq_ro");
  delay(2000);
  // clear the screen
  lcd.clear();
}

/*
 * loop function.
 * 
 */
void loop()
{
  float medie = 0.00;
  float distance1;
  for (int i=0; i <= 100; i++){ 
   // Start Ranging
  digitalWrite(TRIGPIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIGPIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGPIN, LOW);
  // Compute distance
  float distance = pulseIn(ECHOPIN, HIGH);
  distance1 = 10*distance/58;
  medie = medie + distance1;
  delay(10);
  }
  int dist = medie/100;
  // prind data on LCD  
  lcd.setCursor(0, 0);
  lcd.print("distanta este de");
  lcd.setCursor(2, 1);
  lcd.print("            ");
  lcd.setCursor(5, 1);
  lcd.print(dist);
  lcd.print("mm");
  delay(200);
  //lcd.clear();
  
}






    Am realizat 3 filmulete cu functionarea:
ultrasonic distance sensor with Arduino and LCD16x2:
ultrasonic distance sensor with Arduino and LCD16x2 (2)
ultrasonic distance sensor with Arduino and LCD16x2 (3)

    M-am gandit ca un indicator al gamei de masura poate fi mai sugestiv, asa ca ma considerat ca 4m este suficient, asa ca din cele 16 coloane ale unui rand pe ecranul LCD, pasii sunt de 250mm (25cm).
    Sketch-ul este:


// from http://www.xappsoftware.com/wordpress/2012/03/15/how-to-interface-the-hc-sr04-ultrasonic-ranging-module-to-arduino/

#define ECHOPIN 8        // Pin to receive echo pulse
#define TRIGPIN 9        // Pin to send trigger pulse

// from  http://arduino.cc/en/Tutorial/LiquidCrystalDisplay
// The circuit LCD 16x2:
// * LCD RS pin to digital pin 12
// * LCD Enable pin to digital pin 11
// * LCD D4 pin to digital pin 5
// * LCD D5 pin to digital pin 4
// * LCD D6 pin to digital pin 3
// * LCD D7 pin to digital pin 2
// * LCD R/W pin to ground
// * 10K resistor:
// * ends to +5V and ground
// * wiper to LCD VO pin (pin 3)

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// adapted sketch for ultrasonic module HC-SR04 and 16x2 LCD by niq_ro
// http://www.tehnic.go.ro 
// http://www.nicuflorica.blogspot.com

void setup()
{
  pinMode(ECHOPIN, INPUT);
  pinMode(TRIGPIN, OUTPUT);
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print first message to the LCD.
  lcd.print("www.tehnic.go.ro");
  lcd.setCursor(0, 1);
  lcd.print("creat de niq_ro");
  delay(2500);
  // clear the screen
  lcd.clear();

// Print second message to the LCD.
  lcd.setCursor(0, 0);
  lcd.print("masurare dist.cu");
  lcd.setCursor(0, 1);
  lcd.print("HC-SR04 ver.2m3");
  delay(2500);
  // clear the screen
  lcd.clear();
  
}

/*
 * loop function.
 * 
 */
void loop()
{
  float medie = 0.00;
  float distance1;
  for (int i=0; i <= 50; i++){ 
   // Start Ranging
  digitalWrite(TRIGPIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIGPIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGPIN, LOW);
  // Compute distance
  float distance = pulseIn(ECHOPIN, HIGH);
  distance1 = 10*distance/58;
  medie = medie + distance1;
  delay(10);
  }
  int dist = medie/50;
  // print data on first row at LCD  
  lcd.setCursor(0, 0);
  lcd.print("distanta: ");
  lcd.setCursor(9, 0);
  lcd.print("            ");
  lcd.setCursor(9, 0);
  lcd.print(dist);
  lcd.print("mm");
  delay(200);
  
  // print moving star on second row at LCD
  lcd.setCursor(0, 1);
  lcd.print("----------------");
     if (dist >= 3750)
  {
  lcd.setCursor(14, 1);
  lcd.print(">>");
  }
     else if (dist >= 3500)
  {
  lcd.setCursor(14, 1);
  lcd.print("*");
  }
     else if (dist >= 3250)
  {
  lcd.setCursor(12, 1);
  lcd.print("*");
  }
     else if (dist >= 3000)
  {
  lcd.setCursor(11, 1);
  lcd.print("*");
  }
     else if (dist >= 2750)
  {
  lcd.setCursor(10, 1);
  lcd.print("*");
  }
     else if (dist >= 2500)
  {
  lcd.setCursor(9, 1);
  lcd.print("*");
  }
     else if (dist >= 2250)
  {
  lcd.setCursor(8, 1);
  lcd.print("*");
  }
     else if (dist >= 2000)
  {
  lcd.setCursor(7, 1);
  lcd.print("*");
  }
     else if (dist >= 1750)
  {
  lcd.setCursor(6, 1);
  lcd.print("*");
  }
     else if (dist >= 1500)
  {
  lcd.setCursor(5, 1);
  lcd.print("*");
  }
   else if (dist >= 1250)
  {
  lcd.setCursor(4, 1);
  lcd.print("*");
  }
   else if (dist >= 1000)
  {
  lcd.setCursor(3, 1);
  lcd.print("*");
  }
   else if (dist >= 750)
  {
  lcd.setCursor(2, 1);
  lcd.print("*");
  }
   else if (dist >= 500)
  {
  lcd.setCursor(1, 1);
  lcd.print("*");
  }
 else if (dist >= 250)
  {
  lcd.setCursor(0, 1);
  lcd.print("*");
  }
}








    Am facut si un filmulet, numit ultrasonic distance sensor with Arduino and LCD16x2 (4):

17 comentarii:

  1. Răspunsuri
    1. multumesc... chiar nu e greu deloc de folosit... doar ca nu i-am gasit eu utilitate practica, momentan...

      Ștergere
  2. Felicitari, ai scris ceva dar a iesit f. bine articolul :)
    Acum ca tot ai precizat sursa dx.com, sunt curios cum a decurs tranzactia: in cat timp de la efectuarea platii au venit componentele, transportul e gratuit? De asemenea la o comanda ca a ta, de valoare 7,70 $ cat te-a costat efectiv toata distractia si care sunt aceste costuri suplimentare?

    Multumesc anticiapat si spor la treaba in continuare!

    RăspundețiȘtergere
  3. ...consider ca am scris clar ca in 5 saptamani a venit coletul...transportul e gratuit (free shipping)... nu sunt alte costuri...

    RăspundețiȘtergere
  4. Salut, imi poti spune te rog cat ti-a luat (ca timp) sa faci acest proiect ? mersi

    RăspundețiȘtergere
  5. Salut... sa-l reasamblez si sa incarc sketch-ul? 10 minute, de obicei... de ce?

    RăspundețiȘtergere
  6. Ma refer cat ti-a luat de la cap la coada. Proiectul asta (masurator de distanta cu ultrasunete) mi l-am ales ca proiect de licenta..si eram curios sa vad cam cat o sa imi ia. Mersi

    RăspundețiȘtergere
    Răspunsuri
    1. depinde de modul de realizare.. ceva in stilul facut de mine cu placa Arduino, afisaj LCD cu adaptor si firicele sau proiect transferat pe cablaj independent? in primul caz faci 20-30 de minute si al doilea mai trebuie proiectat cablajul, facut fizic, plantate piese...cam o saptamana...

      Ștergere
  7. Am inteles. Imi poti da un contact, mail/telefon, pentru ca as dori sa aflu mai multe detalii ? Nu de alta, dar nu as vrea sa incarc sectiunea asta cu intrebarile mele :) mersi

    RăspundețiȘtergere
    Răspunsuri
    1. Chiar e greu sa vezi ce e-mail am? in fine.... nicu.florica@gmail.com

      Ștergere
  8. senzorul reflecta pe luciu de apa ? (adica: a calcula distanta pana la nivelul apei intr-o fantana)

    RăspundețiȘtergere
  9. Vreau si eu unul complet.as vrea sa monitorizez un bazin cu apa

    RăspundețiȘtergere
    Răspunsuri
    1. bazin sau fântână? îmi trebuie o schiţă cu dimensiuni pentru a-mi da seama dacă e viabil sau nu un asemenea montaj...

      Ștergere
  10. Va salut! Imi puteti spune daca acest modul poate fi folosit si in alte aplicatii in afara de componenta a unei placi de dezvoltare arduino? Mai exact, se poate folosi ca declansator pentru un modul cu releu pentru impuls slab sau puternic? https://s.click.aliexpress.com/e/q90QuHi

    RăspundețiȘtergere
    Răspunsuri
    1. in modul nu e decat un emitator si un receptor... trebuie un sistem adaptor, cu un microcontroler si cel mai ieftin e Arduino, dar daca e vorba de detectie miscare folositi senzor PIR sau Doppler... vedeti http://nicuflorica.blogspot.com/2014/02/senzorul-de-prezenta-hc-sr501-si-arduino.html respectiv http://nicuflorica.blogspot.com/2018/02/senzor-de-miscare-tip-radar-doppler.html

      Ștergere
  11. functia pulsein este blocanta, deci, daca ai o distanta mai mare programul asteapta mai mult.
    pentru a evita asta folositi intreruperi

    RăspundețiȘtergere
    Răspunsuri
    1. multumesc, articolul are ceva vechime (7 ani si ceva)... pentru aplicatiile mele e ok si asa..

      Ștergere