Μέτρηση αποστάσεων με τον αισθητήρα HC-SR04

Ένας τρόπος για να μετράμε αποστάσεις ηλεκτρονικά, είναι με την χρήση της μεθόδου της ανάκλασης των υπερήχων. Οι υπέρηχοι είναι ηχητικά κύματα που διαδίδονται στον αέρα και έχουν συχνότητες πάνω από 20.000Ηz. Το ανθρώπινο αυτί μπορεί να ακούσει ηχητικά κύματα μεταξύ 20Hz έως 20.000Ηz. Για ήχους συχνότητας μεγαλύτερης από 20.000Ηz, που ονομάζονται υπέρηχοι, δεν προκαλούν την αίσθηση της ακοής για το ανθρώπινο αυτί.

Σε αυτό το εδάφιο θα μάθουμε πώς να μετράμε αποστάσεις με τον υπερηχητικό αισθητήρα HC-SR04 χρησιμοποιώντας το Arduino, ο οποίος έχει την ικανότητα να αναγνωρίζει εμπόδια με την μέθοδο της ανάκλασης υπερήχων τα οποία βρίσκονται σε απόσταση μικρότερη από 400cm. Ο αισθητήρας αυτός έχει πολλά πλεονεκτήματα όπως τη μικρή κατανάλωση (μπορεί να τροφοδοτηθεί από μπαταρίες), είναι φθηνός, εύκολος χειρισμός και είναι δημοφιλής στους χομπίστες.

Ο HC-SR04 αποτελείται από δυο υπερηχητικούς transducers, ο ένας δρα σαν πομπός που εκπέμπει υπερηχητικούς παλμούς συχνότητας 40ΚΗz, ενώ ο άλλος είναι διαμορφωμένος σαν δέκτης. Η εκπομπή των υπερηχητικών παλμών από τον πομπό αρχίζει με την εφαρμογή ενός παλμού τάσης με διάρκεια το λιγότερο 10μS στον ακροδέκτη σκανδαλισμού Trig. Ο δέκτης παράγει στον ακροδέκτη echo ένα παλμό, το πλάτος του οποίου μπορεί να χρησιμοποιηθεί για να ορίσει την απόσταση που διανύουν οι υπερηχητικοί παλμοί και τελικά την απόσταση του αντικειμένου. Η διάρκεια του παλμού τάσης στον ακροδέκτη echo είναι ανάλογο της απόστασης που διανύουν οι υπερηχητικοί παλμοί, το οποίο κυμαίνεται μεταξύ 150μS και 25mS. Αν αυτό το χρονικό διάστημα ξεπεράσει τα 38mS αυτό σημαίνει ότι δεν υπάρχει αντικείμενο μπροστά για να ανακλαστούν τα υπερηχητικά κύματα.

Ο αισθητήρας είναι μικρός σε μέγεθος, εύκολος στη χρήση και μπορεί να χρησιμοποιηθεί σε ρομποτικές κατασκευές, ανιχνεύοντας αντικείμενα σε απόσταση μεταξύ 2cm και 400cm με ακρίβεια 3mm. Λειτουργεί με τάση 5V και μπορεί να χρησιμοποιηθεί με το Arduino ή με άλλον μικροελεγκτή που χρησιμοποιεί λογική 5V.

Χαρακτηριστικά του υπερηχητικού αισθητήρα HC-SR04

Διάταξη ακροδεκτών του HC-SR04

Vcc Τροφοδοσία τάσης DC στα 5V
Trig Σκανδαλισμός για αποστολή υπερηχητικών παλμών
Echo Παράγει ένα παλμό έως το ανακλώμενο σήμα ληφθεί. Το πλάτος του παλμού είναι ανάλογο με την απόσταση που διανύει το ηπερηχητικό κύμα από τη στιγμή της εκπομπής έως τη λήψη του.
GND Συνδεση στα 0V

Μέθοδος μέτρησης αποστάσεων με υπερήχους

Ας δούμε τον τρόπο με τον οποίο λειτουργεί ο αισθητήρας HC-SR04. Η διαδικασία ξεκινά με την αποστολή ενός παλμού από τον μικροελεγκτή στον ακροδέκτη Trigger του αισθητήρα, διάρκειας το λιγότερο 10μS. Σαν ανταπόκριση ο αισθητήρας στέλνει μια ριπή από υπερηχητικούς παλμούς συχνότητας 40ΚΗz, ενώ ταυτόχρονα με την αρχή της εκπομπής ο ακροδέκτης echo μεταβαίνει από LOW σε HIGH. Ο τρόπος εκπομπής των παλμών είναι τέτοιος που επιτρέπει στο δέκτη να διακρίνει το εκπεμπόμενο σήμα από το θόρυβο.

Από τη στιγμή της εκπομπής έως την λήψη του υπερηχητικού πακέτου το σήμα στον ακροδέκτη echo είναι HIGH. Το σήμα echo θα γυρίσει σε LOW με τη λήψη του ανακλώμενου σήματος. Το πλάτος αυτού του παλμού στον ακροδέκτη echo ορίζει την απόσταση του αισθητήρα από το εμπόδιο.

Στην περίπτωση που το υπερηχητικό σήμα δεν ανακλαστεί, ο παλμός στον ακροδέκτη echo θα πάρει την μέγιστη διάρκεια των 38mS και έπειτα θα γυρίσει σε LOW. Το σήμα echo είναι HIGH καθ’ όλη τη διάρκεια της κίνησης των υπερηχητικών παλμών πρόσπτωσης και ανάκλασης από το αντικείμενο.

Η διάρκεια του παλμού HIGH του σήματος echo ορίζει την απόσταση του αντικειμένου από τον αισθητήρα. Ο παλμός echo έχει πλάτος από 150μS έως 25mS που εξαρτάται από το χρόνο που πήρε από την εκπομπή μέχρι τη λήψη του υπερηχητικού σήματος.

Το πλάτος του παλμού στον ακροδέκτη Echo χρησιμοποιείται για την εύρεση της απόστασης του αισθητήρα από το αντικείμενο στο οποίο ανακλώνται οι υπέρηχοι. Όπως μάθαμε στο σχολείο η απόσταση του αντικειμένου από τον HC-SR04 υπολογίζεται από την σχέση:

Απόσταση = Ταχύτητα  Χ   Χρόνος

Όπου η ταχύτητα είναι η ταχύτητα διάδοσης των υπερήχων στον αέρα και χρόνος είναι η χρονική διάρκεια που οι υπερηχητικοί παλμοί χρειάζονται να καλύψουν μια καθορισμένη απόσταση.

Ας κάνουμε ένα παράδειγμα για να το δούμε σαφέστερα. Υποθέτουμε ότι έχουμε ένα αντικείμενο μπροστά στον αισθητήρα σε άγνωστη απόσταση και λαμβάνουμε ένα παλμό πλάτους 650μs στον ακροδέκτη Echo. Για να υπολογίσουμε την απόσταση θα χρησιμοποιήσουμε την προηγούμενη σχέση.

Γνωρίζουμε την ταχύτητα του ήχου η οποία είναι 340m/s. Θα πρέπει να την εκφράσουμε σε μονάδες cm/μs. Κάνουμε τα μαθηματικά και βρίσκουμε την ταχύτητα σε αυτή τη μονάδα ίση με 0,034cm/μs. Έτσι η ζητούμενη απόσταση έχει τιμή:

Απόσταση = 0,034cm/μs   X    650μs

Δεν έχουμε τελειώσει! Θυμηθείτε ο παλμός echo ορίζει το χρόνο που παίρνουν τα υπερηχητικά κύματα να κινηθούν από τον αισθητήρα προς το αντικείμενο στο οποίο ανακλούνται και να γυρίσουν πίσω στο δέκτη. Έτσι θα πρέπει να διαιρέσουμε το αποτέλεσμα δια δυο. Δηλαδή:

Απόσταση = (0,034cm/s  X  650μs) / 2   ή   Απόσταση = 11cm

Έτσι τώρα γνωρίζουμε ότι το αντικείμενο βρίσκεται σε απόσταση 11 εκατοστά από τον αισθητήρα.

Περιορισμοί χρήσης των υπερήχων για μέτρηση αποστάσεων

Ο αισθητήρας HC-SR04 σε όρους ακρίβειας και χρησιμότητας προσφέρει πολλά πλεονεκτήματα συγκρινόμενος με άλλες μετρητικές συσκευές χαμηλού κόστους. Αυτό δεν σημαίνει ότι μπορεί να μετρήσει τα «πάντα». Στις ακόλουθες περιπτώσεις ο αισθητήρας δεν είναι ικανός να ανταποκριθεί:

1] Η απόσταση μεταξύ του αισθητήρα και του αντικειμένου είναι μεγαλύτερη από 400cm.

2] Η γωνία που σχηματίζεται από την διεύθυνση διάδοσης των υπερήχων και της καθέτου στην ανακλώμενη επιφάνεια είναι μεγαλύτερη από 45 μοίρες.

3] Το αντικείμενο στο οποίο θέλουμε να μετρήσουμε την απόσταση από τον αισθητήρα είναι πολύ μικρό και δεν μπορούν να ανακλαστούν τα υπερηχητικά κύματα.

4] Έχει βρεθεί πειραματικά ότι αντικείμενα από μαλακό υλικό όπως μαλακά υφασμάτινα αρκουδάκια δεν είναι ικανά να ανακλάσουν τα υπερηχητικά κύματα κι έτσι είναι δύσκολο να μετρήσουμε την απόσταση χρησιμοποιώντας υπερήχους.

Διασύνδεση του HC-SR04 με το Arduino

Μια που έχουμε καταλάβει πως ο υπερηχητικός αισθητήρας δουλεύει ας δούμε μια εφαρμογή συνδέοντας τον HC-SR04 με το Arduino και συγκεκριμένα με την αναπτυξιακή πλακέτα βασισμένη στο Arduino που παρουσιάσαμε σε άλλο άρθρο.

Συνδέουμε το HC-SR04 με το Arduino ως εξής: Συνδέουμε τον ακροδέκτη VDD του αισθητήρα με τα 5V της αναπτυξιακής πλακέτας, τον ακροδέκτη GRD του αισθητήρα με το Graound του Arduino, τον ακροδέκτη Trig με τον ακροδέκτη 8 του Arduino και τον ακροδέκτη Echo με τον ακροδέκτη  9  του Arduino. Ο τρόπος σύνδεσης των ακροδεκτών του αισθητήρα με την αναπτυξιακή πλακέτα φαίνεται στον ακόλουθο πίνακα:

Ανέβασμα του κώδικα στο Arduino

Αντί μετά τον σκανδαλισμό Trig να μετράμε το πλάτος του παλμού Echo «δια χειρός», θα χρησιμοποιήσουμε μια ειδική βιβλιοθήκη την NewPing. Πριν φορτώσεις τον κώδικα στο Arduino Nano θα πρέπει να έχεις εγκαταστήσεις αυτήν την βιβλιοθήκη NewPing στο περιβάλλον Arduino IDE. Ακολούθησε τα παρακάτω βήματα για να την εγκαταστήσεις.

1] Πάτησε εδώ NewPing_v1.9.0.zip για να κατεβάσεις την βιβλιοθήκη. Θα πρέπει να έχεις ένα συμπιεσμένο αρχείο .zip στο φάκελο downloads.
2] Κάνε unzip το αρχείο .zip και θα πρέπει να πάρεις τον φάκελο NewPing.
3] Μετακίνησε την βιβλιοθήκη NewPing στο φάκελο των βιβλιοθηκών του περιβάλλοντος Arduino IDE.
4] Κάνε επανεκκίνηση της εφαρμογής Arduino IDE

Μετά την διασύνδεση του αισθητήρα HC-SR04 με την αναπτυξιακή πλακέτα βασισμένη στο Arduino Nano που παρουσιάζουμε σε άλλο άρθρο και μετά την εγκατάσταση της βιβλιοθήκης NewPing, ανέβασε τον ακόλουθο κώδικά στο περιβάλλον IDE και μετά φόρτωσε τον στο Arduino Nano. Πρόσεξε να επιλέξεις τη σωστή θύρα που έχεις συνδέσει το Arduino και αν το Arduino Nano που χρησιμοποιείς είναι κινέζικης παραγωγής, δοκίμασε στην επιλογή πλακέτα την “Arduino Duemilanove or Diecimila”

#include "NewPing.h"
#include <LiquidCrystal.h>

LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

// Διασύνδεσε τον HC-SR04 με το πιν Trig στο Arduino Pin 9 και το πιν Echo με το Arduino πιν 10
#define TRIGGER_PIN 8
#define ECHO_PIN 9

// Μέγιστη απόσταση που θέλουμε να ανιχνεύσουμε σε εκατοστά.
#define MAX_DISTANCE 400  

// Δημιουργία ενός αντικειμένου NewPing με τον ορισμό των πινς και την μέγιστη απόσταση.
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

float duration;
float distance;

void setup() 
{
  pinMode(TRIGGER_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  lcd.begin(20, 4);
  lcd.clear();
  lcd.setCursor(0, 0);  
}

void loop() 
{
  lcd.clear();
  lcd.setCursor(0,1);  
  lcd.print("Distance:");
  lcd.setCursor(0, 2);
  
  // Αποστολή παλμών και εύρεση της απόστασης σε εκατοστά.
  distance = sonar.ping_cm();
    
  // Στέλνει τα αποτελέσματα στο LCD.
    
  if (distance >= 400 || distance <= 2) 
  {
    lcd.print("Out of range");
  }
  else 
  {
    lcd.print(distance);
    lcd.print("cm");
  }
  delay(500);
}

 Επεξήγηση του κώδικα

Ο παραπάνω κώδικας είναι απλός και δουλεύει καλά αλλά έχει ακρίβεια έως ένα εκατοστό. Αν θέλεις οι μετρήσεις να είναι δεκαδικές θα πρέπει να χρησιμοποιείσεις τη NewPing σε «duration mode» αντί σε «distance mode». Έτσι θα πρέπει να αντικαταστήσεις τις

// Στέλνει μια ριπή παλμών και υπολογίζει την απόσταση σε cm
distance = sonar.ping_cm();

Με τις παρακάτω γραμμές:

duration = sonar.ping();
distance = (duration / 2) * 0.0343;

Μπορούμε να πάμε σε επόμενο επίπεδο ακρίβειας των μετρήσεων ως εξής: Κάνουμε επαναλαμβανόμενες μετρήσεις και μετά παίρνουμε την μέση τιμή τους. Αντικαθιστούμε τις επόμενες γραμμές στον αρχικό κώδικα και στις οποίες δίνουμε εντολή για 5 επαναληπτικές μετρήσεις.

int iterations = 5;
duration = sonar.ping_median(iterations);
distance = (duration / 2) * 0.0343;

Ένας διαφορετικός τρόπος μέτρησης αποστάσεων με τον HC-SR04

Ας δούμε ένα άλλο τρόπο υπολογισμού αποστάσεων με τον υπερηχητικό αισθητήρα HC-SR04. Από την στιγμή που στείλουμε ένα παλμό στον ακροδέκτη Trig του αισθητήρα υπερηχητικοί παλμοί εκπέμπονται και μετράμε με την βοήθεια της συνάρτησης pulseIn(echopin, HIGH) τη χρονική διάρκεια που τα υπερηχητικά κύματα πάνε και γυρίζουν πίσω στον αισθητήρα, διαμορφώνοντας ένα παλμό στον ακροδέκτη Echo που το πλάτος του είναι ανάλογο της μετρούμενης απόστασης.

Επίσης χρησιμοποιούμε τη βιβλιοθήκη LcdBarGraph που μας βοηθά να σχεδιάζουμε στην οθόνη LCD μια οριζόντια μπάρα της οποίας το μήκος είναι ανάλογο του παλμού echo δηλαδή της μετρούμενης απόστασης. Για να το πραγματοποιήσουμε θα πρέπει να εγκαταστήσουμε τη βιβλιοθήκη LcdBarGraph στο περιβάλλον βιβλιοθηκών του Arduino IDE. Για να την εγκαταστήσεις ακολούθησε τα επόμενα βήματα.

1] Πάτησε εδώ LcdBarGraph-1.5.zip για να κατεβάσεις την βιβλιοθήκη. Θα πρέπει να έχεις ένα συμπιεσμένο αρχείο .zip στο φάκελο downloads.
2] Κάνε unzip το αρχείο .zip και θα πρέπει να πάρεις τον φάκελο LcdBarGraph.
3] Μετακίνησε την βιβλιοθήκη LcdBarGraph στο φάκελο των βιβλιοθηκών του περιβάλλοντος Arduino IDE.
4] Κάνε επανεκκίνηση της εφαρμογής Arduino IDE

Μετά που εγκαταστήσεις τη βιβλιοθήκη ανέβασε στο Arduino τον ακόλουθο κώδικα:

// Συμπεριλαμβάνει τη βιβλιοθήκη LiquidCrystal
#include <LiquidCrystal.h> 

// Συμπεριλαμβάνει την βιβλιοθήκη LcdBarGraph 
#include <LcdBarGraph.h>

// Μέγιστη απόσταση που θέλουμε να ανιχνεύσουμε σε cm.
#define max_distance 200

// Δημιουργεί ένα αντικείμενο LCD. Παράμετροι:(rs, enable, d4, d5, d6, d7)

LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

LcdBarGraph lbg(&lcd, 16, 0, 1); // Δημιουργεί ένα αντικείμενο LCD Bargraph.

const int trigPin = 8;
const int echoPin = 9;
long duration;
int distance;

void setup() 
{
  lcd.begin(20,4); // Αρχικοποιεί την διεπαφή με την οθόνη LCD.
  
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() 
{
  // Στέλνει ένα παλμό στο πιν Trig του HC-SR04
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  // Μετρά την διάρκεια του παλμού στο πιν Echo.
  duration = pulseIn(echoPin, HIGH);
  
  // Υπολογίζει την απόσταση από την χρονική διάρκεια του παλμού Echo.
  // Χρησιμοποιεί σαν ταχύτητα του ήχου 343 μέτρα ανα δευτερόλεπτο.
  distance= duration*0.034/2;
  // if(distance <= 3 || distance >= 200) distance = 0;
  // Τυπώνει "Distance: [value]" στην πρώτη γραμμή του LCD
  lcd.setCursor(0,0);
  for(int i = 0; i < 16; i++) lcd.print(" "); // Καθαρίζει την πρώτη γραμμή.
  lcd.setCursor(0, 0);
  lcd.print("Distance: ");
  if(distance <= 3 || distance >= 200) {
        lcd.print("err");
        distance = 0;
     }
     else {
        lcd.print(distance);
        lcd.print(" cm");
     }  
  // Σχεδιάζει μια μπάρα στη δεύτερη γραμμή του LCD
  lcd.setCursor(0,1);
  lbg.drawValue(distance, max_distance);
  delay(1000);
}

Επεξήγηση του κώδικα

Πρώτα θα πρέπει να εγκαταστήσεις τη βιβλιοθήκη LiquidCrystal  όπως γνωρίζουμε. Μετά από αυτό θα πρέπει να δημιουργήσεις ένα αντικείμενο LcdBarGraph με το μόλις δημιουργημένο αντικείμενο LiquidCrystal. Θα πρέπει να εισάγεις την αναφορά του αντικειμένου LiquidCrystal στη συνάρτηση δημιουργίας του LcdBarGraph.

Ο δημιουργός του LcdBarGraph αντικειμένου παίρνει τρείς επιπλέον παραμέτρους. Η δεύτερη παράμετρος είναι ο αριθμός στηλών χαρακτήρων του LCD (στη δικιά μας περίπτωση είναι 16). Οι άλλες δυο παράμετροι είναι προαιρετικές και δηλώνουν την αρχή της μπάρας.

//Δημιουργεί ένα υπόδειγμα bargraph
LcdBarGraph  lbg(&lcd, 16, 0, 1);

Μόλις πάρουμε τιμές για την απόσταση με τον αισθητήρα HC-SR04 θα χρησιμοποιήσουμε τη συνάρτηση drawValue(value, maxValue) για να σχεδιάσουμε την μπάρα στην οθόνη. Αυτή η συνάρτηση σχεδιάζει μια μπάρα με μήκος μεταξύ 0 και maxValue

//Εμφάνιση της μπάρας στην LCD
lbg.drawValue(distance, max_distance);