Usare gli ultrasuoni con i Robot

Scheda per usare gli ultrasuoni per dirigere il tuo Robot

Usare gli ultrasuoni per dirigere il tuo Robot

Cosa sono i sensori a ultrasuoni?

In breve sono l’equivalente elettronico delle orecchie dei pipistrelli, niente horror comunque: si tratta di microfoni specialmente sensibili ai suoni oltre i 20 Khz (Kilo Hertz), generalmente non udibili dall’orecchio umano ma facilmente recepiti dai mammiferi. Pensa a cose come il fischietto per i cani o ai ping usati sui sottomarini per trovare le navi.

La versione elettronica del sonar viene usata nei sensori di parcheggio delle automobili e grazie alla enorme diffusione i costi si sono abbassati moltissimo. Ne useremo tre in questo progetto e avrai con poca spesa e un software molto semplice il tuo primo Robot capace di movimento autonomo.

Come usare il sensore a ultrasuoni HC-SR04 con Arduino

In questo post vedremo come usare il sensore HCSR04 e cercheremo di spiegare come si usa, come funziona e quali caratteristiche ci possono fare comodo per lavorare con Arduino e i nostri Robot in genere. Di seguito riporto le caratteristiche elettriche e dopo vedremo come usarlo in un progetto pratico.

Notebook

Il sensore HC-SR04 montato su una Breadboard per Arduino

Descrizione

Come detto prima l’HC-SR04 usa il principio del Sonar per calcolare la distanza da un oggetto e dunque sfrutta la riflessione del suono sugli ostacoli solidi e la costanza della velocità del suono. Riesce a fornire con buona esattezza la distanza da un oggetto e restituisce dei valori costanti e progressivi, senza ritardi.

Fisicamente è piccolo, seppure non minuscolo e nella parte anteriore presenta due tronchi di cono in plastica. Uno si limita a trasmettere il segnale mentre l’altro lo riceve. Il sensore rileva il segnale e crea un impulso elettrico di durata proporzionale al ritardo.

Caratteristiche elettriche e dinamiche

Le specifiche tecniche del sensore HC-SR04:

  Alimentazione       : +5V DC
  Corrente a riposo   : <2mA
  Corrente di lavoro  : 15mA
  Angolo panoramico   : <15°
  Distanza di rilevazione : 2cm – 400 cm
  Risoluzione : 0.3 cm
  Angolo di misurazione: 30 gradi
  Durata del segnale di trigger: 10uS
  Dimensioni: 45mm x 20mm x 15mm

 

Come funziona?

Nel dettaglio in sensore opera in questo modo:

  1. – Il trasmettitore manda un impulso ad ultrasuoni,
  2. – Il segnale sonoro incontra un oggetto solido,
  3. – Il ricevitore riceva l’onda riflessa (l’impulso riflesso).

Il tempo che passa tra la trasmissione e la ricezione del segnale ci permette di calcolare la distanza reale di un oggetto. Come è possibile? Perchè sappiamo con precisione la velocità del suono a livello del mare che è circa 330 mt al secondo e basta fare una proporzione per avere la distanza in centimetri, la risoluzione che verosimilmente ci servirà con i Robot mobili.

La disposizione dei pin dell’ HC-SR04

Notebook

  -  VCC  : +5VDC
  -  Trig : Trigger (INPUT)
  -  Echo : Echo (OUTPUT)
  -  GND  : GND

Dove comprarlo su Internet:

51tbSvuOcAL

Ti consiglio di aquistare il sensore ultrasonico HC-SR04 su Amazon cercando il prezzo più basso tra i prodotti con almeno 4 stelle. In alternativa puoi cercare su banggood.com.

Come fanno i Robot a calcolare le distanze usando il sensore HCSR04 e Arduino

In questi progetto il sensore legge e scrive la distanza da un oggetto nel monitor serial del tuo IDE Arduino. L’obiettivo del progetto è iniziare a capire come funziona il sensore, poi nella parte centrale di questo post costruiremo un vero Robot, con una logica di funzionamento “complessa” e capacità dinamiche.

Nota: Esiste una libreria per Arduino chiamata NewPing che ci renderà il lavoro molto più semplice.

Le parti richieste

Ecco una lista delle cose che vi serviranno:

  -  Arduino UNO
  -  Sensore Ultrasonico (HCSR04)
  -  Breadboard
  -  Jumper
  -  Batteria 9V
  -  Portabatteria con Jack standard 9V

Lo schema

Segui attentamente la disposizione dei connettori, studia la foto e potrai collegare Il sensore ultrasonico HC-SR04 al tuo Arduino in pochi minuti.

Come collegare Arduino al sensore HC-SR04

nella parte sinistra i pin del sensore, a destra quelli di Arduino

  -  VCC    <——>  5V
  -  Trig   <——>  Pin 11
  -  Echo   <——>  Pin 12
  -  GND    <——>  GND

 

e infine Il codice completo…

Copia e incolla questo programma nel tuo IDE di arduino, fai l’upload con la compilazione automatica, ignora i warning e fai attenzione ai messaggi di errore.

Come funziona il codice in dettaglio

Per prima cosa dobbiamo creare le variabili per il pin di trasmissione e per quello di ricezione. Il pin di trasmissione è connesso al Pin digitale 11, mentre quello di Ricezione va al Pin digitale 12:

int PinTrasmissione = 11; 
int PinRicezione    = 12;

Poi serve creare due variabili del tipo long per conservare i valori di durata e centimetri. La variabile “durata” conserva il tempo tra trasmissione e ricezione del segnale, la variabile “cm” conserva la distanza in centimetri.

long durata, cm;

Nella fase di setup(), la porta seriale viene inizializzata a 9600 di baud rate, e vengono settati i pin di Output e Input.

Serial.begin (9600);
pinMode(PinTrasmissione, OUTPUT);
pinMode(PinRicezione, INPUT );

Nel loop() inneschiamo il sensore mandando un impulso HIGH di 10 microsecondi. Ma prima mandiamo un breve impulso LOW per resettare il sensore e ottenere un impuso HIGH piĂą pulito:

digitalWrite(PinTrasmissione, LOW);
delayMicroseconds(5);
digitalWrite(PinTrasmissione, HIGH);
delayMicroseconds(10);
digitalWrite(PinTrasmissione, LOW);

Fatto questo possiamo leggere il segnale dal sensore, un impulso HIGH la cui durata esprime il tempo in microsecondi passato fra la tramissione dell’impulso e la sua ricezione.

In poche parole il sensore invia un impulso elettrico più lungo a secondo della distanza, in questo modo il calcolo aritmetico diventa quindi una semplice moltiplicazione.

durata = pulseIn(PinTrasmissione, HIGH);

Adesso dobbiamo convertire la durata dell’ impulso elettrico del sensore in una vera distanza in centimetri. La calcoliamo in questo modo solo apparentemente complesso:

prima versione:
distanza = (durata/2) x (la velocitĂ  del suono)
   e poichè la velocità è esattamente: 0.0343 cm/microsecondo...

seconda versione:
distanza = (durata/2)  x 0.0343
   e visto che 1/0.0343 equivale a 29.1 avremo*

terza versione:
distanza = (durata /2) / 29.1 

*moltiplicare per 0.343 è come dividere per l'inverso (cioè 29.1)

Inoltre dobbiamo dividere per due perchè il sensore non distingue tra andata e ritorno ed emette un valore complessivo errato, per così dire, ma facile da correggere.

Ma alla fine tutto si riduce a questa semplice operazione: distanza = (durata /2) / 29.1 e per ora questo ci basta!

A fine programma scriviamo il risultato su Monitor Seriale dell’ IDE:

Serial.print("cm:");
Serial.print(cm);
Serial.println();

Poichè siamo dentro a loop() non ci serve usare istruzioni “FOR” o “WHILE”: la logica interna del software di Arduino ci risparmia questa operazione. Con altri linguaggi senza il costrutto sintattico “loop()” dovremmo arrangiarci scrivendo altre linee di codice.

 

Il programma per Arduino modificato con l’uso di NewPing: una libreria alternativa per Robot terrestri

Semplice da usare NewPing in certe occasioni risulta consigliabile quando dobbiamo limitarci a calcolare distanze in modo diretto, senza elaborare il segnale di ritorno. La libreria si trova a questo indirizzo in formato zippato clicca qui. Dopo avere scaricato e installato la libreria puoi usare il codice sottostante:

 

 

Come funziona il programma con NewPing

Calcolare la distanza di un oggetto con NewPing è molto semplice. Innanzitutto devi includere la la libreria nel programma:

#include <NewPing.h>

Poi come al solito devi definire i Pin di Trasmissione e di ricezione. Il Pin di trasmissione del sensore viene connesso al Pin 11 di Arduino mentre quello di Ricezione finisce sul Pin 12. Bisogna inoltre definire una distanza massima.

#define PIN_TRASMISSIONE 11
#define PIN_RICEZIONE 12
#define DISTANZA_MAX 200

Adesso possiamo chiamare la libreria dal programma:

NewPing sonar(PIN_TRASMISSIONE, PIN_RICEZIONE, DISTANZA_MAX); 

Nel setup(), come al solito bisogna settare la Porta Seriale allavelocitĂ  di 9600 baud (bit al secondo).

Serial.begin(9600);

In fine nel loop(), per avere la distanza in cm basta usare la chiamata di funzione ping_cm(). In questo caso possiamo parlare di metodo perchè il linguaggio C++ da cui deriva il linguaggio di Arduino è un linguaggio di programmazione ad oggetti. Noi ci adeguiamo alla terminologia e invece di chiamata a funzione parliamo di metodo.

unsigned int distanza = sonar.ping_cm();
Serial.print(distanza);
Serial.println(" cm");

Le solite istruzioni di print permettono di vedere sull’IDE di Arduino le distanza dagli oggetti anche in movimento. Provate a vedere la differenza di comportamento con il programma precedente. Se tutto ha funzionato correttamente non dovremmo avere differenze.

Il progetto completo di un Robot guidato dagli ultrasuoni (prima parte)

Il materiale necessario e i link per acquistarlo:

  
  -  Arduino Nano R3

link

  -  Motorini elettrici generici

link

  -  Sensore Ultrasonico - HC-SR04

link

  -  Breadboard

link

  -  Batteria USB da 3.000 mAh 
  -  Telaio Coretec Tiny 4WD Robot

link

  -  Driver motori elettrico L298N DC

link

  

Lo schema del circuito

schema del circuito

clicca sulla immagine per avere la versione ingrandita

Il movimento viene fornito da 4 motori elettrici a corrente continua del tipo che trovate in qualsiasi telaio per rover economici. Sono il tipo più comune anche al di fuori dei Robot: spesso sono paragonati ai motori brushless di maggiore precisione ma anche di maggior delicatezza. Collegarli direttamente ad Arduino sarebbe impossibile perchè la corrente assorbita lo brucerebbe in pochi secondi.

Per fortuna non dobbiamo progettarci da soli il driver a transistor per un funzione così banale, ci basterà comprare 2 driver duali per pilotare i 4 motori complessivi del Robot. In questo progetto useremo gli L9110 che hanno costo molto basso e affidabilità a tutta prova.

foto ingrandita 5X del driver per motori elettrici L9110 a doppia uscita

foto ingrandita 5X Arduino Nano rev.3 con in evidenza il chip ATmega328

HC-SR04

Useremo sempre Arduino Nano per i progetti di droni aerei e per i piccoli droni terrestri. Useremo Arduino classico e Mega per i progetti statici e Robot terrestri di una certa dimensione.

I sensori ad ultrasuoni sono l’unico componente “attivo” di questo progetto e vengono continuamente interrogati dal software caricato su arduino. Senza particolari elaborazioni i dati sulla distanza da pareti ed oggetti finiscono per per far cambiare direzione o invertire la marcia.

Il codice da incollare sul tuo Ide Arduino

Come funziona il codice del progetto

Le righe da 1 a 11 dichiarano (cioè assegnano un valore)

const int PinEchoAnteriore = 7;
const int PinTriggerAnteriore = 6;
const int PinEchoSinistra = 11;
const int PinTriggerSinistra = 10;
const int PinEchoDestra = 9;
const int PinTriggerDestro = 8;
const int motorinoL1 = 2;
const int motorinoL2 = 3;
const int motorinoR1 = 4;
const int motorinoR2 = 5;
const int RitardoMedio = 20;

 

a dei riferimenti mnemonici chiamati costanti. Le costanti hanno un particolare valore (2, 10, 4.555 …) che serve in vari punti del programma. Se volete cambiarne il valore per fare esperimenti vi basta modificarle ad inizio del codice, senza impazzire a cercarle e cambiarle una ad una.

Le righe da 13 a 18 riservano uno spazio in memoria per contenere

volatile float MassimaDistanzaAnteriore = 25.00;
volatile float DurataPerAnteriore, DistanzaAnterioreInCm;
volatile float DurataPerSinistra, DistanzaSinistraInCm;
volatile float DurataPerDestra, DistanzaDestraInCm;
volatile float MassimaDistanzaSinistra;
volatile float MassimaDistanzaDestra = 20.00;

sei variabili di tipo float. Ho usato questo tipo particolare (detto anche a “virgola mobile”) perchè deve contenere dei valori decimali. I numeri con delle cifre dopo la virgola sono trattati da tutti i computer in un modo molto particolare. Sono registrati in memoria usando 2 numeri interi detti mantissa e logaritmo, ma per il momento ti basta ricordare che i due tipi di variabile non sono intercambiabili.

Scrivere un numero del tipo 0,5 in una variabile di tipo INT avrà il risultato di salvare uno ZERO! Invece è possibile scrivere qualsiasi numero intero dentro una variabile FLOAT.

Perchè tante complicazioni per salvare un banalissimo numero? La risposta la dobbiamo cercare nel linguaggio di base di Arduino, il C++, un linguaggio fortemente orientato al calcolo numerico e alla velocità ma con delle restrizioni molto precise sulle variabili.

Le righe da 21 a 36 fanno parte del setup del programma, cioè di una in genere breve, sequenza di operazioni da fare una tantum e solo all’inizio. Ad esempio pinMode(PinEchoAnteriore, INPUT); serve a spegare ad arduino che la porta 7 (cosi definita in const int PinEchoAnteriore = 7;) viene abilitata a leggere dei segnali. Le porte di arduino possono funzionare in input e output ma non contemporaneamente ed è necessario predisporle all’inizio.

Ricorda che non devi digitare questo ammasso di comandi sull’IDE di arduino ma devi limitarti a copiare dalla pagina web o dal programma originale su Github.com. Ti basta cliccare sul link, premere CTRL-A (che vuol dire – seleziona tutto), e poi premere CTRL-C per copiare. Quindi vai sull’IDE di Arduino e premi CTRL-V per incollare. Usare i tasti è piĂą complicato all’inizio ma è molto piĂą veloce che usare il mouse.

Le righe da 37 a 50 definiscono il cosidetto loop del programma, un ciclo di operazioni che vengono ripetute dall’inzio non appena arrivati alla fine. Il loop si limita a controllare le distanze anteriori e laterali e attiva le funzioni correttive Muovi verso destra o sinistra. Se non ci sono ostacoli scrive “OK” sul monitor seriale e guida il Robot verso avanti.

void loop() {
ControlloDistanzaAnteriore();
if (DistanzaAnterioreInCm < MassimaDistanzaAnteriore) {
  Serial.println(“Troppo vicino!”);
  ControlloDistanzaSinistra();
  delay(RitardoMedio);
  ControlloDistanzaDestra();
  delay(RitardoMedio);
  if (DistanzaSinistraInCm < DistanzaDestraInCm)
    MuoviaDestra();
  else if (DistanzaSinistraInCm > DistanzaDestraInCm) {
    MuoviaSinistra();
  }
}
else {
  Serial.println(“OK”);
  VaiAvanti();
}