EduRobot UNO – Come costruire il vostro primo Arduino Robot – Lezione 2

banner-edurobot-uno-lezione2

Collegamenti elettrici

Colleghiamo il sensore ad ultrasuoni sulla basetta

Inseriamo il sensore sulla breadboard in una posizione centrale sul fronte dell’EduRobot UNO. Collegate GND e Vcc come nell’immagine alle rispettive linee di alimentazioni sulla breadboard, da questi poi effettuate un collegamento al GND e a +5V sulla scheda Arduino.

21-edurobot-uno

22-edurobot-uno

Collegate con altri due fili i punti Trig e Echo rispettivamente ai pin 8 e 9 di Arduino.

23-edurobot-uno

Colleghiamo i motori

Utilizzando i 3 pin come mostrato nell’immagine che segue, spostate la parte plastica isolante a metà dei connettori metallici.

24-edurobot-uno

Inserite i pin sulla breadboard e collegate ad essi i motori.

25-edurobot-uno

I motori hanno ciascuno 3 file: GND (nero), segnale (bianco), Vcc (rosso). Il filo del segnale potrebbe presentarsi anche di altri colori (ad es. giallo).
Collegate GND e Vcc di ogni motore alle linee di alimentazioni presenti sulla breadboard.

27-edurobot-uno

Collegate il segnale del motore sinistro al pin 11 e il segnale del motore destro al pin 10 entrambi pin di tipo PWM.

26-edurobot-uno

Programmazione

Quando si incomincia a programma qualsiasi sia il linguaggio di programmazione usato è un classico realizzare il programma “Hello World!”, nel caso di Arduino un classico è il “blink” che permette di far lampeggiare un LED, ma un’alternativa potrebbe essere proprio quella di scrivere sulla Serial Monitor  “Hello World!”

Aprite l’IDE Arduino e scriviamo il nostro primo sketch.

28-edurobot-uno

Scriviamo il seguente sketch:

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  Serial.println("Hello World!");
}

Effettuate l’upload dello sketch, noterete in basso a sinistra del’IDE il messaggio “Done uploading”, ciò vi segnalerà che la compilazione e il trasferimento sono andati a buon fine. A questo punto fate click sulla lente di ingrandimento per aprire la Serial Monitor.

Dovreste visualizzare il messaggio “Hello World!” che viene stampato ripetutamente:

29-edurobot-uno

Andando avanti nell’analisi incontriamo la funzione setup()

void setup()
{
  Serial.begin(9600);
}

setup() è una funzione che viene eseguita una sola volta all’atto dell’accensione della scheda. La funzione setup() viene utilizzata per indicare la modalità di utilizzo dei pin e con Serial.begin(9600) inizializziamo la porta seriale impostando la velocità di comunicazione a 9600 baud.

Baud è sinonimo di simboli trasmessi al secondo, in altro modo: simboli/s la cui unità di misura è il “baud rate“, numero di simboli trasmessi al secondo in un sistema di trasmissione digitale come ad esempio un un modem.
Attenzione a non confondere il “baud rate” con il “bit rate” espresso in bit/s o bps.

La funzione successiva è il loop()

void loop()
{
  Serial.println("Hello World!");
}

Il loop() viene ripetuto continuamente fino a quando non si toglie l’alimentazione alla scheda, sostanzialmente è un ciclo infinito.
Questo è il corpo fondamentale di uno sketch Arduino, tutto ciò che andrete ad implementare risiederà all’interno del loop().
Nel caso in esempio il contenuto (in termini informatici il “body“) di questa funzione è semplice, il comando dice ad Arduino di inviare il testo, indicato tra virgolette (in termini informatici “la stringa”) alla porta seriale del computer.

Serial.println("Hello World!");

quindi verrà stampata a monitor la stringa: “Hello World!” con un successivo ritorno a capo, poiché la funzione è inserita all’interno del loop() verrà stampato ripetutamente “Hello World!”

Usiamo i servo

Per poter movimentare il nostro robot utilizziamo dei motori particolari: i servomotori particolari motori elettrici di cui si può controllare con un certo grado di accuratezza il gradi di rotazione.

#include <Servo.h>

// creazione degli oggetti servo
Servo MotoreSinistro;
Servo MotoreDestro;

void setup()
{
    MotoreSinistro.attach(11);
    MotoreDestro.attach(10);
}

void loop()
{
  MotoreSinistro.write(180);
  MotoreDestro.write(180);
}

La prima riga di comando permette di includere una libreria di Arduino, nello specifico quella che ci permette di usare i servomotori.
Una libreria è una porzione di codice esterno che consente di facilitare l’uso di molti dispositivi elettronici, nelle librerie vengono dettagliate tutte le funzionalità del dispositivo e le modalità di utilizzo, paragonate le librerie come a mattoncini di informazione che aggiungono funzionalità specifiche al vostro sketch permettendovi di poter usare un dispositivo elettronico, offrendo all’utente i modi (le funzioni) per operare su di esso.
Continuando le vostre sperimentazioni noterete che sono moltissime le librerie che sono state scritte per Arduino e se desiderate comprendere ancor di più a cosa serve e come si crea una libreria in Arduino seguite la lezione n. 8 su questo sito.

Le successive linee di codice:

Servo MotoreSinistro;
Servo MotoreDestro;

consentono di creare i due oggetti Servo (in informatica si dice istanziare i due oggetti), in altro modo è come dire: “voglio definire due contenitori a cui voglio assegnare le caratteristiche di un Servo, caratteristiche specificate nella libreria Servo.h“.

Nella funzione setup(), come detto in precedenza definiremo il modo con cui verranno usati i pin di Arduino, in questo caso diremo che ai “contenitori” MotoreSinistro e MotoreDestro diamo la funzionalità .attach() (in informatica si dice che abbiamo assegnato un metodo).
La funzione .attach() ha come parametro il pin a cui è collegato il servo, quindi con le due linee di codice:

MotoreSinistro.attach(11);
MotoreDestro.attach(10);

diciamo semplicemente che attacchiamo (colleghiamo) i due servo rispettivamente al pin 11 e al pin 10.

All’interno della funzione loop() troviamo il metodo .write() funzione che permette di controllare direzione e velocità di rotazione del servo. La .write() accetta come parametro un numero compreso tra 0 e 180 gradi.
L’intervallo 0, 180 deriva dal fatto che un servo “standard”, che non ha una rotazione continua come quella che ci stiamo accingendo ad usare, solitamente ruota solamente di 180 gradi, partendo da 0 gradi ruota raggiunge la parte centrale, 90 gradi, giungendo poi fino ai 180 gradi.
Con un servo a rotazione continua passando il valore 0 alla .write() diciamo che il servo deve ruotare alla massima velocità in una direzione, con il valore 90 gradi poniamo il servo in stop (posizione “neutra”) e con 180 gradi diciamo al servo di ruotare in senso opposto alla massima velocità.

Nota: consiglio di rialzare il vostro robot per evitare che vada a spasso per la vostra scrivania 🙂 e possiate più agevolmente verificarne il funzionamento.

Caricate lo sketch e provatene il funzionamento dovreste notare che stanno girando in direzioni opposte, non preoccupatevi nulla di sbagliato dipende solamente dal fatto che avete ribaltato i due servo uno rispetto all’altro, sono posti in direzione opposta, quindi per fare ruotare i servo nella medesima direzione è sufficiente inviare valori opposti alla funzione .write().

Provate quindi ad inserire in una delle due .write() il valore 0, caricate ora lo sketch su Arduino, dovreste ora vedere le ruote girare nella medesima direzione.

#include <Servo.h>

// creazione degli oggetti servo
Servo MotoreSinistro;
Servo MotoreDestro;

void setup()
{
    MotoreSinistro.attach(11);
    MotoreDestro.attach(10);
}

void loop()
{
  MotoreSinistro.write(0);
  MotoreDestro.write(180);
}

Sensore ad ultrasuoni

Per far evitare gli ostacoli al nostro robot utilizzeremo un sensore ad ultrasuoni, in altro modo useremo questo sensore per misurare la distanza dell’ostacolo, ma potremo anche pensare di usare questo sensore, ad esempio, in un sistema anti-intrusione che deve far suonare un allarme.
In questa lezione viene utilizzato il sensore HC-SR04, dispositivo economico e con un buon range operativo, ha una sensibilità dichiarata nei datasheet che va da 2 centimetri a 4,5 metri circa, in realtà la massima distanza da esperimenti che ho effettuato arriva a circa 3,5 metri, molto comunque dipende dai materiali colpiti e dalla loro capacità di assorbimento sonoro.

Ma come funziona un sensore di questo tipo?

Ripeto brevementa la lezione che avevo pubblicato su scuola.arduino.cc la spiegazione si riferisce ad un’altra tipologia di sensore ad ultrasuoni, ma il funzionamento è analogo.

I sensori ad ultrasuoni non forniscono direttamente la misura della distanza dell’oggetto più vicino, ma misurano il tempo impiegato da un segnale sonoro a raggiungere l’oggetto e ritornare al sensore.

L’impulso ad ultrasuoni inviato all’HC-SR04 è di circa 40KHz il tempo viene misurato in microsecondi, la tensione di funzionamento è di 5V, quindi potremo alimentarlo direttamente utilizzando Arduino.

L’HC-SR04 è dotato di 4 piedini: GND, eco, trigger, +Vcc.

Per convertire l’intervallo di tempo misurato in una lunghezza, bisogna ricordare che la velocità del suono è di 331,5 m/s a 0 °C e di 343,4 m/s a 20 °C ed in generale varia secondo la relazione:

v = 331,4 + 0,62 T

dove la temperatura T è misurata in °C.

Per effettuare una misura di distanza di un ostacolo assumiamo di lavorare ad una temperatura ambiente di 20 °C e quindi la velocità del suono sarà di 343 m/s (approssimiamo) che vuol dire anche 0,0343 cm/microsecondi.

Quindi, ricordando che v=s/t (v: velocità, s: spazio, t: tempo) allora lo spazio percorso sarà:

s = v*t

da cui

s = 0,0343 *t

però, per calcolare lo spazio percorso, bisogna tener conto che il suono percorre due volte la distanza da misurare (giunge sull’oggetto e ritorna indietro al sensore) quindi il valore di t ottenuto deve essere diviso per 2. La formula corretta per la misura dello spazio percorso è:

s = 0,0343 * t/2

eseguendo la divisione di 0,0343/2 possiamo scrivere:

s = 0,01715 * t

oppure:

s = t/58,31

approssimando

s = t/58

formula più semplice da ricordare.

Per calcolare la distanza dell’oggetto dal sensore sarà sufficiente dividere il tempo t (tempo impiegato dal segnale per giungere sull’oggetto e tornare al sensore) per 58.

Per poter effettuare una misurazione viene mantenuto a livello basso il pin Trigger, dopo di che viene fornito un impulso a livello alto della durata minima di 10µs riportandolo poi a livello basso, dopo questo momento la capsula trasmittente emette un burst (sequenza di livelli alti/bassi) a circa 40KHz, l’onda ultrasonica generata (burst) colpisce l’ostacolo, torna indietro venendo rilevata dalla capsula ricevente. L’elettronica del sensore effettua un calcolo del tempo di andata e ritorno del segnale emettendo sul pin Echo, normalmente a livello basso, un segnale a livello alto direttamente proporzionale alla distanza dell’ostacolo:

31-edurobot-uno

Passiamo alla programmazione

const int periodoStampaSuSeriale = 250;       // stampa sulla Serial Monitor ogni 1/4 di secondo
unsigned long ritardoSuSeriale = 0;

const int periodoLoop = 20;          // un periodo di 20 ms = una frequenza di 50Hz
unsigned long ritardoLoop  = 0;

// specifica i pin di trig e echo usati per il sensore ad ultrasuoni
const int TrigPin = 8;
const int EchoPin = 9;

int distanza;
int durata;

void setup()
{
    Serial.begin(9600);
    // configurazione dei pin Arduino a cui colleghiamo il sensore
    pinMode(TrigPin, OUTPUT);
    pinMode(EchoPin, INPUT);
}

void loop()
{
    printOutput(); // stampa un messaggio di debug sulla Serial Monitor
    if(millis() - ritardoLoop >= periodoLoop)
    {
        letturaSensoreUltrasuoni(); // legge e memorizza la distanza misurata
        ritardoLoop = millis();
    }
}

void letturaSensoreUltrasuoni()
{
    digitalWrite(TrigPin, HIGH);
    delayMicroseconds(10);                  // mantiene alto il trigger per almeno 10us
    digitalWrite(TrigPin, LOW);
    durata = pulseIn(EchoPin, HIGH);
    distanza = (durata/2)/29;
}

void printOutput()
{
    if((millis() - ritardoSuSeriale) > periodoStampaSuSeriale)
    {
        Serial.print("distanza: ");
        Serial.print(distanza);
        Serial.print("cm: ");
        Serial.println();
        ritardoSuSeriale = millis();
    }
}

 

Nel nostro sketch Arduino, abbiamo prima bisogno di configurare i pin digitali di I/O digitali a cui connettere il sensore ad ultrasuoni.

// specifica i pin di trig e echo usati per il sensore ad ultrasuoni
const int TrigPin = 8;
const int EchoPin = 9;

Nella definizione di variabili abbiamo definito le variabili come “const”, E’ sempre bene definire una variabile const se si sa che il valore non potrà mai essere modificato nel programma.

Nel setup() definiamo come verranno usati i pin

void setup()
{
    Serial.begin(9600);
    // configurazione dei pin Arduino a cui colleghiamo il sensore
    pinMode(TrigPin, OUTPUT);
    pinMode(EchoPin, INPUT);
}

Funzione principale di lettura è letturaSensoreUltrasuoni() che restituisce la distanza a cui si trova l’ostacolo:

void letturaSensoreUltrasuoni()
{
    digitalWrite(TrigPin, HIGH);
    delayMicroseconds(10);                  // mantiene alto il trigger per almeno 10us
    digitalWrite(TrigPin, LOW);
    durata = pulseIn(EchoPin, HIGH);
    distanza = (durata/2)/29;
}

viene posto il pin di trigger ad HIGH per 10 microsecondi, trascorso questo tempo viene riportato il trigger a LOW a questo punto tramite la funzione di sistema pulseIn viene calcolata la quantità di tempo in cui il segnale resta a livello HIGH, non appena lo stato letto passa a LOW pulseIn restituisce la durata in cui il segnalo è stato a livello HIGH.
Questo valore viene utilizzato per il calcolo della distanza mediante la formula:

distanza = (durata/2)/29;

Per effettuare il debug e verificare sulla Serial Monitor effettivamente la distanza rilevata dal sensore viene usata la funzione printOutput()

void printOutput()
{
    if((millis() - ritardoSuSeriale) > periodoStampaSuSeriale)
    {
        Serial.print("distanza: ");
        Serial.print(distanza);
        Serial.print("cm: ");
        Serial.println();
        ritardoSuSeriale = millis();
    }
}

Per periodi di 250 millisecondo viene stampato a monitor la distanza dell’ostacolo presente di fronte al sensore questo periodo è stabilito dalla condizione dell’if:

(millis() - ritardoSuSeriale) > periodoStampaSuSeriale

millis() restituisce il tempo in millisecondi da quando la scheda è in funzione a questo tempo viene sottratto il valore 250 e se la differenza risulta maggiore di zero allora viene stampato il testo:

distanza: XXcm

dove XX è il valore restituito dalla funzione letturaSensoreUltrasuoni()

il passo successivo è quello di assegnare a ritardoSuSeriale il valore attuale di millis() in questo modo nel successivo controllo si verifica se sono passati effettivamente 250 millisecondi.

A questo punto possiamo comprendere meglio il funzionamento del loop().

La prima funzione che viene invocata è:

printOutput();

che stampa sulla Serial Monitor la distanza dell’ostacolo

la condizione dell’if:

millis() - ritardoLoop >= periodoLoop

consente di effettuare letture da parte del sensore ad intervalli di 20 millisecondi. La logica di funzionamento di questa if è analoga a quanto già detto per l’if all’interno della printOutput().
Se la condizione dell’if è verificata (sono trascorsi 250 millisecondo dalla precedente lettura), viene restituita la distanza mediante la funzione letturaSensoreUltrasuoni() che si trova nel corpo della if.

Effettuate l’upload dello sketch ed aprite la serial monitor vedrete immediatamente comparire la distanza misurata dal sensore.

30-edurobot-uno

Esercizio 1

Realizzate un sitema che misura distanze brevi costituito da tre LED rispettivamente verde, giallo e rosso. Il LED dovranno accendersi nel seguente modo:

ostacolo a 10 cm accensione LED VERDE
ostacolo a 20 cm accensione LED VERDE e LED GIALLO
ostacolo a 30 cm accensione LED VERDE, LED GIALLO e LED ROSSO

Esercizio 2

Realizzate un sitema che misura distanze brevi costituito da tre LED rispettivamente verde, giallo e rosso. Il LED dovranno accendersi nel seguente modo:

ostacolo a 10 cm LED VERDE acceso
ostacolo a 20 cm LED VERDE spento, LED GIALLO acceso, LED ROSSO spento
ostacolo a 30 cm LED VERDE spento, LED GIALLO spento, LED ROSSO acceso

Esercizio 3

Realizzate un sitema che misura distanze brevi costituito da tre LED rispettivamente verde, giallo e rosso e un piezo che emette suoni diverse per distanze diverse. Il LED dovranno accendersi nel seguente modo:

ostacolo a 10 cm LED VERDE acceso – suono 1
ostacolo a 20 cm LED VERDE spento, LED GIALLO acceso, LED ROSSO spento – suono 2
ostacolo a 30 cm LED VERDE spento, LED GIALLO spento, LED ROSSO acceso – suono 3

5 pensieri su “EduRobot UNO – Come costruire il vostro primo Arduino Robot – Lezione 2

  1. Norman Gradin

    Ciao Michele!
    Questa era proprio la tripletta di lezioni che aspettavo che pubblicassi, è un ottima spiegazione per chi vuole avvicinarsi alla costruzione del proprio primo robottino.
    Grazie per questa ennesima perla di sapere!
    Norman

    Rispondi
    1. admin Autore articolo

      Grazie Norman, spero che il tutto possa servire come base di partenza per lo studente che intenda sviluppare qualcosa di più complesso.

      Saluti.

      Rispondi
  2. Antonio

    mi scusi michele ma in questa parte mi da un errore e non capisco a cosa sia dovuto

    ‘void setup()’:

    edurobot1:25: error: ‘EchoPin’ was not declared in this scope

    pinMode(EchoPin, INPUT);

    ^

    C:\Users\antonio votta\Documents\Arduino\edurobot1\edurobot1.ino: In function ‘void letturaSensoreUltrasuoni()’:

    edurobot1:44: error: ‘EchoPin’ was not declared in this scope

    durata = pulseIn(EchoPin, HIGH);

    ^

    exit status 1
    ‘EchoPin’ was not declared in this scope

    Questo report potrebbe essere più ricco di informazioni con l’opzione
    “Mostra un output dettagliato durante la compilazione”
    abilitata in File -> Impostazioni

    Rispondi

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.