Strumenti Utente

Strumenti Sito


arduino_3

Progetti con Arduino

Questa sezione descrive i progetti che realizzeremo con Arduino. Per ognuno troveremo una scheda con lo scopo del progetto e il materiale necessario, il circuito e lo sketch.

Per realizzare i circuiti useremo le baseboard in dotazione al laboratorio 12 collegando la scheda arduino con l'apposito plug. Con questa soluzione i pin della scheda Arduino non sono più accessibili ma vengono replicati sulla baseboard secondo questo schema.

Progetto 1: pilotare il LED sulla scheda

Scopo fare lampeggiare il LED collegato al pin 13 presente sulla scheda Arduino
Componenti in questo progetto non servono breadboard e componenti

sketch

/*
 * Progetto 1
 * Accende e spegne il LED ogni secondo
 * Nome Studente:
 * Creato il: data
 */
 
// Il pin collegato al LED
int led = 13;
 
// impostiamo la scheda
void setup() {                
  // impostiamo il pin come OUTPUT
  pinMode(led, OUTPUT);     
}
 
// il programma vero e proprio che viene ripetuto ciclicamente
void loop() {
  digitalWrite(led, HIGH);   // accende il LED (HIGH -> 5 Volt sul pin)
  delay(1000);               // attende un secondo (1000 millisecondi)
  digitalWrite(led, LOW);    // spegne il LED (LOW -> 0 Volt sul pin)
  delay(1000);               // attende un secondo (1000 millisecondi)
}

Osservazioni

  • è sempre bene mettere un'intestazione con il nome del programma e una descrizione di quello che fa
  • prima di tutto troviamo la dichiarazione delle variabili (potevamo direttamente usare il valore 13 ma assegnandolo a una variabile il programma è più chiaro e più facile da modificare)
  • seguono la funzione setup() e la funzione loop()
  • il programma contiene molti commenti che ne facilitano la comprensione

Progetto 2: pilotare un LED sulla breadboard

Scopo fare lampeggiare un LED
Componenti LED, resistore da 220Ω

Approfondimento sui componenti: il LED

LED rosso

Il LED (light emitting diode) è un particolare tipo di diodo che emette luce quando attraversato da corrente. Il suo comportamento nei circuiti elettrici non è da confondere con quello di una lampadina, infatti:

  • al suo interno la corrente può scorrere in un solo verso, dal morsetto positivo (anodo) a quello negativo (catodo)
  • la tensione ai suoi capi è costante (circa 2V) e non dipende dalla corrente
  • il LED non è in grado di limitare la corrente e si rompe se questa assume valori elevati (per evitare che questo accada si collega sempre una resistenza in serie)

Schema elettrico

progetto 2

sketch

Lo sketch è uguale al precedente ma possiamo scegliere uno qualunque dei pin digitali (nello schema elettrico è utilizzato il pin 9).

Osservazioni

  • il circuito montato sulla breadboard può essere alimentato dalla scheda Arduino (con i pin 5V e GND) o in altro modo (baseboard, alimentatore, batterie)
  • montando la scheda Arduino sulla baseboard lo schema elettrico non corrisponderà esattamente al circuito montato in laboratorio; in particolare non utilizzeremo direttamente i pin sulla scheda ma quelli corrispondenti sulla baseboard (vedi pinout)
  • il LED va posizionato correttamente perché la corrente può scorrere solo dall'anodo (reoforo più lungo) al catodo (reoforo più corto e “tacca” sull'anello alla base del LED); l'anodo deve essere collegato al + e il catodo alla massa (GND)
  • la resistenza serve a limitare la corrente che circola sul LED; senza resistenza il LED si rompe

Progetto 3: LED e input digitale

Scopo accendere un LED con la pressione di un pulsante
Componenti LED, resistori da 100Ω 220Ω e 10kΩ, pulsante NO

Approfondimento sui componenti: il pulsante

pulsante

Il pulsante è in grado di aprire e chiudere un circuito come un interruttore ma presenta una sola posizione stabile:

  • il pulsante normalmente aperto (NO) chiude il circuito quando viene premuto ma lo riapre immediatamente quando viene rilasciato
  • il pulsante normalmente chiuso (NC) apre il circuito quando viene premuto e lo chiude immediatamente quando viene rilasciato

L'apertura o chiusura automatica avviene grazie a un meccanismo a molla che riporta i contatti nella posizione predefinita. Questa soluzione meccanica può causare dei problemi perché la molla tende a far rimbalzare i contatti e il passaggio da aperto a chiuso e viceversa può non essere netto. Lo stesso tipo di problema si presenta anche negli interruttori e viene risolto con i circuiti antirimbalzo (ce ne occuperemo l'anno prossimo).

Schema elettrico

progetto 3

sketch

/*
 * Progetto 3: 
 * Accende un LED con la pressione di un pulsante
 * Nome studente:
 * Creato il: data
 */
 
// pin utilizzati per accendere il LED e leggere lo stato del pulsante
int led = 9;
int pulsante = 3;
 
// impostiamo i due pin digitali come output e input
void setup() {                
  pinMode(led, OUTPUT);     
  pinMode(pulsante, INPUT);
}
 
void loop() {
  if(digitalRead(pulsante) == HIGH) { // se è premuto il pulsante
      digitalWrite(led, HIGH);        // accende il LED
  } 
  else {
    digitalWrite(led, LOW);           // altrimenti spegne il LED
  }
}

Osservazioni

  • in laboratorio il circuito viene alimentato dai pin sulla baseboard invece che da quelli della scheda Arduino
  • negli schemi useremo il filo rosso per i collegamenti con l'alimentazione (5V) e quello nero per la massa (GND)
  • al posto del filo arancione è bene mettere un resistenza da 100Ω per evitare la rottura del pin se lo si imposta per errore come output
  • la resistenza da 10kΩ è detta resistenza di pull-down e serve ad evitare che l'ingresso del pin digitale assuma un valore non valido quando il pulsante non è premuto; quando il pulsante è premuto il pin è collegato ai 5 Volt (HIGH) dell'alimentazione, quando non è premuto è collegato a massa attraverso la resistenza (LOW) come mostrato in figura

input digitale e resistenza di //pull-down//

Variante: commutazione col pulsante

E' possibile accendere e spegnere alternativamente il LED ad ogni pressione del tasto. Per far questo occorre modificare lo sketch in questo modo:

  • definiamo due variabili, statoPulsante e utlimoStatoPulsante per memorizzare lo stato del pulsante e lo stato immediatamente precedente; se i due valori sono diversi significa che il bottone è stato premuto o rilasciato
  • utilizziamo la variablie statoLed per tenere conto dello stato del LED (0 corrisponde a spento e 1 ad acceso); quando viene premuto il pulsante modifichiamo il valore di questa variabile
  • nella funzione loop ad ogni ciclo:
    • leggiamo lo stato del pulsante e lo confrontiamo con quello precedente
    • se i due valori sono diversi e il pulsante è premuto commutiamo, cioè:
      • se il LED era spento lo accendiamo e modifichiamo la variabile statoLed di conseguenza
      • se era acceso lo spegnamo e modifichiamo la variabile statoLed di conseguenza
    • infine aggiorniamo la variabile ultimoStatoPulsante

NB questa modifica metterà in evidenza il problema del rimbalzo dei contatti.

/*
 * Progetto 3 - variante
 * Commutare un LED tra acceso e spento con la pressione di pulsante
 * Nome studente:
 * Creato il: data
 */
 
// pin collegati al LED e al pulsante
int led = 9;
int pulsante = 3;
// valore attuale e precedente sul pin collegato al pulsante
int statoPulsante;
int ultimoStatoPulsante;
// stato del LED (0 = spento, 1 = acceso)
int statoLed = 0;
 
void setup() {                
  // impostiamo il pin del LED come uscita
  pinMode(led, OUTPUT);     
  // impostiamo il pin del pulsante come ingresso
  pinMode(pulsante, INPUT);
  // valore iniziale sul pin del pulsante
  ultimoStatoPulsante = digitalRead(pulsante);
}
 
void loop() {
  // leggo il valore sul pin del pulsante
  statoPulsante = digitalRead(pulsante);
  // se il valore è cambiato rispetto al precedente vuol dire
  // che il pulsante è stato premuto o rilasciato
  if(statoPulsante != ultimoStatoPulsante) {
    // se il pulsante è stato premuto commuta tra acceso e spento
    // (se è stato rilasciato non succede niente)
    if(statoPulsante == HIGH) {
      // se il LED era spento lo accende
      if (statoLed == 0) {
        digitalWrite(led, HIGH);
        statoLed = 1;
      }
      // se il LED era acceso lo spenge
      else {
        digitalWrite(led, LOW);
        statoLed = 0;
      }
    }
  }
  // aggiorna ultimoStatoPulsante
  ultimoStatoPulsante = statoPulsante; 
}

Progetto 4: input analogico e porta seriale

Scopo leggere un valore da un pin analogico e trasmetterlo al PC tramite seriale
Componenti potenziometro da 10kΩ

Approfondimento sui componenti: il potenziometro

potenziometro per breadboard

Il potenziometro è un componente a tre morsetti costituito da un resistore con una presa centrale mobile comandata da una manopola (o una vite o un cursore). Tra il morsetto centrale e gli altri due è possibile ottenere un valore di resistenza a piacere compreso tra zero e il valore del resistore. Solitamente i potenziometri sono usati per regolare la tensione come nell'esempio in figura:

regolazione di tensione con un potenziometro

La tensione applicata tra i morsetti 1 e 3 viene suddivisa in base alla posizione del contatto mobile 2 e il tratto compreso tra il contatto mobile 2 e il morsetto 3 sarà sottoposto a una tensione proporzionale alla sua resistenza. Spostando il contatto 2 è possibile variare la resistenza e di conseguenza regolare la tensione tra 0 e 5 Volt.

Schema elettrico

progetto 4

sketch

/*
 * Progetto 4: 
 * Legge un valore di tensione su un pin analogico e lo trasmette 
 * al PC con una comunicazione seriale attraverso la porta USB
 * Nome studente:
 * Creato il: data
 */
 
// pin analogico utilizzato
int potenziometro = 0;
// valore analogico (da 0 a 1023)
int valore = 0;
 
// stabiliamo una comunicazione seriale con velocità 9600 baud
void setup() {                
  Serial.begin(9600);
}
 
void loop() {
  // leggiamo il valore analogico
  valore = analogRead(potenziometro);
  // inviamo il valore al PC
  Serial.print("La tensione sul pin analogico è ");
  Serial.print(valore);
  Serial.println(" milliVolt");
  // piccola pausa
  delay(200);
}

Osservazioni

  • per visualizzare i valori bisogna utilizzare il monitor seriale dell'IDE Arduino
  • durante la comunicazione lampeggiano i led TX (trasmissione) e RX (ricezione)
  • se si usa la seriale non è possibile utilizzare i pin digitali 0 e 1 perché i piedini corrispondenti del microcontrollore sono usati per la ricezione e trasmissione
  • la velocità di trasmissione è espressa in baud cioè in caratteri al secondo
  • l'istruzione Serial.print(valore); trasmette un valore sulla seriale senza andare a capo al termine; Serial.println(valore); fa la stessa cosa ma andando a capo ogni volta (per approfondire vedi la pagina nella guida di riferimento
  • visualizzare il valore delle variabili sul monitor seriale può essere molto utile nel debugging di un programma, cioè per trovare e correggere eventuali errori (bug) di programmazione

Progetto 5: effetto "supercar" con i LED

Supercar

Scopo accendere in sequenza un gruppo di LED creando un effetto “rimbalzo”
Componenti 5 LED, resistori da 180Ω

Approfondimento sul linguaggio di programmazione: gli array

Un array è un insieme di variabili dello stesso tipo a cui diamo un unico nome. Per accedere ai vari valori si usa un indice che identifica la variabile corrisondente. In definitiva possiamo pensare agli array come a dei contenitori (un solo nome) con tanti elementi a cui possiamo accedere usando un indice.

Un array può essere dichiarato (e inizializzato) in questi modi:

int contenitore[5];  // specificando la dimensione (array di 5 elementi)
int pin[] = {2, 4, 8, 3, 6}; // senza dimensione ma indicando i singoli elementi
int voti[6] = {2, 4, 8, 5, 7};  // indicando dimensione e inizializzando alcuni elementi

Per accedere a un elemento di un array si usa un indice - che parte sempre da zero - tra parentesi quadre:

contenitore[0] = 2; // assegna il valore 2 al primo elemento dell'array
digitalWrite(pin[2], HIGH); // imposta alto il *terzo* elemento dell'array
voti[6] = 10; // è un errore!!! se l'array contiene 6 elementi l'ultimo è voti[5]

L'errore nell'esempio precedente è piuttosto comune e difficile da individuare; va evitato assolutamente perché così facendo si scrive un valore in una parte della memoria che non appartiene all'array causando il malfunzionamento del programma.

Solitamente per accedere in sequenza agli elementi di un array si usa un ciclo for:

int pin[5] = {2, 3, 4, 5, 6};  // array di cinque elementi
for(int indice = 0; indice < 5; indice++) {
  digitalWrite(pin[indice], HIGH);  // imposto tutti i pin alti
}

Schema elettrico

progetto 5

sketch

/*
 * Progetto 5: 
 * accende in sequenza 5 LED creando un effetto rimbalzo (alla supercar)
 * Nome studente:
 * Creato il: data
 */
 
// array con i pin collegati ai 5 LED
int pinLed[] = { 1, 2, 3, 4, 5};
// direzione (1 -> dal pin 1 al pin 5, -1 -> dal pin 5 al pin 1)
int direzione = 1;
// indice dell'array che indica su quale LED operare
int ledCorrente = 0;
 
void setup() {
  // imposto tutti i pin digitali come uscite
  for (int x = 0; x < 5; x++) {
    pinMode(pinLed[x], OUTPUT);
  }
}
 
void loop() {
  // spengo tutti i LED  
  for (int x = 0; x < 5; x++) {
    digitalWrite(pinLed[x], LOW);
  }  
  // accendo il LED corrente
  digitalWrite(pinLed[ledCorrente], HIGH);
  // aggiorno ledCorrente in base alla variabile direzione (ad es. se il LED 
  // corrente è il secondo dell'array e la direzione è 1 il prossimo è il terzo
  ledCorrente = ledCorrente + direzione;
  // cambio direzione se siamo agli estremi (0 -> primo elemento, 4 -> ultimo)
  if (ledCorrente == 4) {
    direzione = -1;
  }
  if (ledCorrente == 0) {
    direzione = 1;
  }
  // piccola pausa
  delay(100);
}

Osservazioni

  • il Progetto poteva essere realizzato diversamente, ad esempio accendendo e spegnendo i LED singolarmente o usando un due cicli for (uno per direzione)
  • l'approccio scelto consente di iterare tra gli elementi dell'array direttamente con la funzione loop e eventualmente di estendre il programma; ad esempio se volessimo regolare la velocità con un potenziometro è sufficiente cambiare l'ultima istruzione in delay(analogRead(0));
  • la variabile ledCorrente è l'indice usato per accedere agli elementi dell'array; il suo valore viene aumentato o diminuito ad ogni ciclo a seconda della variabile direzione
  • al posto di ledCorrente = ledCorrente + direzione; si poteva usare la notazione più sintentica ledCorrente += direzione;
  • quando raggiungiamo il primo o l'ultimo elemento dell'array (quindi il primo o l'ultimo LED) cambiamo direzione
  • NB utilizzando il pin 1 per uno dei LED non è possibile sfruttare la comunicazione seriale (che richiede i pin 0 e 1)

Progetto 6: fotoresistore e LED

Scopo visualizziamo l'intesità luminosa misurata da un fotoresistore con dei LED
Componenti 5 LED, 5 resistori da 180Ω, resistore da 10KΩ, fotoresistore

Approfondimento sui componenti: il fotoresistore

Una fotocellula (o fotorivelatore) è un dispositivo che misura l'intensità luminosa e la trasforma in un segnale elettrico. Il fotoresistore è il tipo più semplice di fotocellula ed è un componente la cui resistenza è inversamente proporzionale alla quantità di luce a cui è esposto.

fotoresistore

La resistenza del fotoresistore usato in questa prova è maggiore di 20kΩ in condizioni di totale oscurità e scende sotto i 100Ω quando esposto direttamente alla luce di una lampada.

fotoresistore come potenziometro

Comportandosi come una resistenza variabile è possibile usare il fotoresistore come un potenziometro comandato dalla luce invce che da una manopola. Se collegato in serie ad un resistore di valore costante, come nello schema in figura, la tensione ai suoi capi sarà:

`V_(FR) = (R_(FR))/(R_(FR) + R)*V`

dove V è la tensione totale, R la resistenza del resistore e RFR la resistenza variabile del fotoresistore.

Schema elettrico

progetto 6

sketch

/*
 * Progetto 6: 
 * indica l'intensità luminosa rilevata da un fotoresistore
 * accendendo una serie di 5 LED
 * Nome studente:
 * Creato il: data
 */
 
// array con i pin collegati ai 5 LED
int pinLed[] = { 2, 3, 4, 5, 6};
 
// valore della tensione ai capi del fotoresistore
// completa oscurità  -> circa 800
// esposizione diretta a una lampada -> circa 20
int valoreFR;
 
void setup() {
  // imposto tutti i pin digitali come uscite
  for (int x = 0; x < 5; x++) {
    pinMode(pinLed[x], OUTPUT);
  }
  Serial.begin(9600);
}
 
void loop() {
  // leggo la tensione ai capi del LED
  valoreFR = analogRead(0);
  Serial.println(valoreFR);
 
  // spengo tutti i LED  
  for (int x = 0; x < 5; x++) {
    digitalWrite(pinLed[x], LOW);
  }  
 
  // accendo un certo numero di LED in base alla luce che investe il fotoresistore
  if (valoreFR < 500) {
    digitalWrite(pinLed[0], HIGH);
  }
  if (valoreFR < 400) {
    digitalWrite(pinLed[1], HIGH);
  }
  if (valoreFR < 300) {
    digitalWrite(pinLed[2], HIGH);
  }
  if (valoreFR < 150) {
    digitalWrite(pinLed[3], HIGH);
  }
  if (valoreFR < 50) {
    digitalWrite(pinLed[4], HIGH);
  }
 
  // piccola pausa
  delay(500);
}

Osservazioni

  • in questo progetto la comunicazione seriale è usata per il debugging e per tarare i valori che determinano l'accensione dei vari LED
  • è una buona idea misurare la resistenza del fotoresistore nelle due condizioni limite (completa oscurità e esposizione a una lampada) per scegliere il valore della resistenza collegata in serie
  • la tensione ai capi del fotoresistore è compresa tra 0 Volt e un valore che dipende dalla resistenza collegata in serie; non raggiunge mai i 5 Volt quindi il valore massimo di valoreFR è minore di 1023

Progetto 7: cicalino piezoelettrico

Scopo suonare una melodia con un cicalino piezoelettrico
Componenti cicalino piezoelettrico

Approfondimento sui componenti: il cicalino piezoelettrico

I materiali piezoelettrici esibiscono questo comportamento:

  • quando subiscono una deformazione meccanica generano una tensione (esempi di applicazione: accendino, microfono)
  • quando sono sottoposto a una tensione subiscono una deformazione (esempi di applicazione: cicalino)

cicalino piezoelettrico

All'interno del cicalino è presente un elemento piezoelettrico che emette un click ogni volta che viene sottoposto a una tensione a causa della deformazione provocata dall'effetto piezoelettrico. Se viene applicata alternativamente una tensione il cicalino emetterà un suono la cui tonalità dipende dalla frequenza con cui la tensione passa dal valore alto a quello basso.

Schema elettrico

progetto 7

sketch

/*
 * Progetto 7
 * Suonare una melodia con il cicalino piezoelettrico
 * Nome Studente:
 * Creato il: data
 */
 
// pin collegato al cicalino
int pinCicalino = 10;
 
// note della melodia (frequenza come da tabella)
int melodia[] = {262, 262, 392, 392, 440, 440, 392, 349, 349, 330, 330, 294, 294, 262};
// durata delle note in millisecondi
int durataNota[] = {500, 500, 500, 500, 500, 500, 1000, 500, 500, 500, 500, 500, 500, 1000};
 
void setup() {
}
 
void loop() {
  // suona in sequenza le note della melodia (14 note in tutto)
  for (int nota = 0; nota < 14; nota++) {
    tone(pinCicalino, melodia[nota],durataNota[nota]);
    // pausa lunga quanto la durata della nota
    delay(durataNota[nota]);
    // interrome il suono prima di emettere la prossima nota
    noTone(pinCicalino);
  }
}

Osservazioni

  • la funzione tone(pin, frequenza, durata) genera un onda quadra (alterna il valore alto e basso di tensione) su un pin digitale; questo segnale è in grado di pilotare un cicalino facendogli emettere un suono
  • la tonalità del suono dipende dalla frequenza dell'onda espressa in Hertz
  • la durata del suono è impostata in millisecondi
  • il suono può essere interrotto con la funzione noTone(pin)
  • non è necessario impostare il pin utilizzato dalla funzione tone() come uscita
  • nella tabella seguente sono indicate le frequenze di alcune note (vedere qui per un elenco competo)
notafrequenza
do262
do#277
re294
re#311
mi330
fa349
fa#370
sol392
sol#415
la440
la#466
si494

Progetto 8: sensore a ultrasuoni

Scopo rilevare la distanza con un sensore a ultrasuoni
Componenti sensore a ultrasuoni HC-SR04

Approfondimento sui componenti: sensore a ultrasuoni

I sensori ad ultrasuoni servono a misurare la distanza di un oggetto e funzionano secondo il principio del sonar:

  • il sensore genera un'onda sonora inudibile (ultrasuoni)
  • se l'onda incontra un ostacolo una parte di essa viene riflessa (eco)
  • il sensore rileva l'eco e misura il tempo impiegato dall'onda per tornare al sensore
  • dal tempo si risale alla distanza (d=v·t dove v è la velocità del suono)

principio di funzionamento del sonar

Il sensore utilizzato in questo progetto è il modello HC-SR04. E' un sensore economico e facile da utilizzare che è in grado di misurare distanze comprese tra 2 centimetri e 4 metri.

sensore a ultrasuoni HC-SR04

Il sensore contiene al suo interno un piccolo microcontrollore che si occupa della misura e dispone di due pin per l'alimentazione (Vcc e GND) e due pin digitali per la misura (Trig e Echo). Quando si invia un impulso di 10 microsecondo al pin trigger il sensore genera un'onda a ultrasuoni, misura il tempo che impiega a tornare dopo aver colpito un ostacolo e invia un impulso sul pin echo di durata proporzionale alla distanza. La distanza in centimetri si calcola dividendo la durata dell'impulso in microsecondi per 58.

Schema elettrico

progetto 8

sketch

/*
 * Progetto 8
 * Rilevare la distanza con un sensore a ultrasuoni
 * Nome Studente:
 * Creato il: data
 */
 
// pin collegato al trigger del sensore 
// un impulso di almeno 10 microsecondi fa partire l'onda a ultrasuoni 
int trigPin = 9; 
 
// pin collegato al pin echo del sensore 
// l'impulso inviato dal sensore ha una durata proporzionale alla distanza 
int echoPin = 8; 
 
// durata dell'impuslo sul pin echo (in microsecondi) 
unsigned long durata = 0; 
 
// distanza rilevata dal sensore (in centimetri) 
int distanzaCm = 0; 
 
void setup(){ 
   pinMode(echoPin, INPUT); 
   pinMode(trigPin, OUTPUT); 
  Serial.begin(9600); 
} 
 
void loop(){ 
  // invio un impulso di 10 microsecondi dalla scheda al pin trigger 
  digitalWrite(trigPin, HIGH); 
  delayMicroseconds(10); 
  digitalWrite(trigPin, LOW); 
 
  // calcolo la durata dell'impulso di ritorno inviato dal sensore 
  durata = pulseIn(echoPin, HIGH); 
 
  // converto la durata dell'impulso in una distanza in centimetri 
  distanzaCm = durata / 58; 
 
  // invio il dato alla seriale 
  Serial.print("distanza rilevata dal sensore: "); 
  Serial.print(distanzaCm); 
  Serial.println(" centimetri"); 
  delay(500); 
}

Osservazioni

  • la funzione delayMicroseconds() è l'equivalente di delay() ma il ritardo è espresso in microsecondi invece che in millisecondi
  • per misurare la durata in microsecondi dell'impulso echo inviato dal sensore alla scheda Arduino si usa la funzione pulseIn(pin, valore, timeout), dove pin è il pin digitale di ingresso che riceve l'impulso, valore è la costante HIGH o LOW a seconda che si voglia misurare il tempo in cui l'impulso assume il valore alto o basso di tensione e il parametro opzionale timeout è il limite di tempo oltre il quale la funzione restituisce il valore zero quando non viene rilevato nessun impulso
  • il sensore utilizzato nella prova misura fino a circa 2 metri, oltre questa soglia l'impulso echo è sempre alto e la funzione pulseIn() restituisce il valore zero dopo un timeout di un secondo; sarebbe opportuno tenerne conto:
    • indicando quando la misura è oltre il valore massimo
    • aggiustando il timeout di pulseIn()per non rallentare le misure
  • la durata dell'impulso echo in microsecondi può essere maggiore del massimo valore consentito per le variabili di tipo int (32767); per la variabile durata si usa allora il tipo unsigned long che può assumere valori da 0 a 4 miliardi
  • non è difficile estendere il programma in modo che si comporti come un sensore di parcheggio di un auto: quando si avvicina un ostacolo si emettono dei suoni intermittenti (con un cicalino piezoelettrico per esempio) la cui frequenza aumenta al diminuire della distanza

Progetto 9: sensore a infrarosso

Scopo rilevare la presenza di un ostacolo con un sensore a infrarosso
Componenti sensore a infrarosso TCRT5000

Approfondimento sui componenti: sensore a infrarosso

I sensori a infrarosso (IR) vengono usati per:

  • rilevare la presenza di un oggetto
  • distinguere zone chiare e riflettenti da altre scure e che assorbono la luce
  • misurare una distanza da un ostacolo

In questa prova useremo una scheda con sensore IR fatta per rilevare ostacoli (o linee scure). Il sensore vero e proprio (TCRT5000) è composto di due parti:

  • l'emettitore: un diodo LED che emette un raggio infrarosso (invisibile all'occhio umano)
  • il rivelatore: un fototransistor che genera un segnale proporzionale all'intensità del raggio infrarosso che lo colpisce

Le due immagini sotto mostrano il lato inferiore e quello superiore della scheda con sensore IR:

sensore IR (lato inferiore)sensore IR (lato superiore)

Si riconoscono:

  • il sensore vero e proprio con LED (blu) e fototransistor (nero), posto nella parte inferiore
  • una serie di componenti a montaggio superficiale (resistori, condensatori, LED indicatori)
  • un integrato (comparatore) e un trimmer che servono per l'uscita digitale
  • quattro piedini: due per l'alimentazione della scheda (VCC e GND) e due con l'uscita analogica (A0) e digitale (D0)

Il principio di funzionamento del sensore è molto semplice:

  • il LED emette un raggio infrarosso
  • se il raggio colpisce un ostacolo viene (parzialmente) riflesso
  • il fototransistor riceve il raggio riflesso e produce un segnale proporzionale alla sua intensità

L'uscita analogica fornisce un'indicazione, con una tensione tra 0 e 5 Volt, di quanto è vicino l'ostacolo. L'uscita digitale (0 o 5 Volt) indica la presenza o meno di un ostacolo entro una distanza che è possibile impostare con il trimmer.

Questo tipo di sensori costituiscono un'alternativa a quelli (più complicati e costosi) a ultrasuoni ma funzionano peggio perché la luce ambientale può falsare la misura e gli oggetti possono riflettere la luce in maniera molto diversa (ad esempio uno specchio o a una superficie nera e opaca).

Schema elettrico

Circuito con sensore a infrarosso

sketch

/*
 * Progetto 9
 * Rilevare la distanza con un sensore a infrarosso
 * Nome Studente:
 * Creato il: data
 */
 
// pin collegato all'uscita digitale del sensore IR
// LOW -> ostacolo rilevato; HIGH -> nessun ostacolo
int ostacolo = 13; 
// valore analogico di tensione presente nell'uscita AO del sensore IR
// valori bassi -> ostacolo vicino; valori alti -> ostacolo lontano
int tensioneIR;
 
void setup(){ 
  pinMode(ostacolo, INPUT); 
  Serial.begin(9600); 
} 
 
void loop(){ 
  // rilevo la presenza dell'ostacolo
  if(digitalRead(ostacolo) == LOW){
    Serial.println("Rilevato ostacolo");
  }
  else {
    Serial.println("Nessun ostacolo rilevato"); 
  }
 
  // valore analogico che dipende dalla distanza
  tensioneIR = analogRead(0);
  Serial.print("Valore analogico generato dal sensore IR: ");
  Serial.println(tensioneIR);
  delay(500); 
}

Osservazioni

  • il rilevamento ostacolo funziona correttamente e volendo è possibile tarare la distanza con il trimmer
  • il valore analogico di tensione dell'uscita analogica del sensore dipende dalla distanza a cui si trova l'ostacolo ma anche dal tipo di ostacolo (dalla sua forma, dal materiale, dal colore) e da come riflette la luce; ponendo alla stessa distanza un oggetto piano e chiaro e uno scuro e irregolare si otterranno valori molto diversi
  • il sensore IR non è adatto a misurare la distanza (se non in condizioni controllate, cioè conoscendo le proprietà dell'ostacolo e le condizioni ambientali)1) ma solo la presenza o meno di un ostacolo o di una superficie riflettente/scura

Torna all'indice.

1)
esistono sensori IR più complicati progettati apposta per misurare la distanza sfruttando l'angolo di riflessione del raggio, ad esempio quelli prodotti da Sharp
Questo sito Web utilizza i cookie. Utilizzando il sito Web, l'utente accetta la memorizzazione dei cookie sul proprio computer. Inoltre riconosci di aver letto e compreso la nostra Informativa sulla privacy. Se non sei d'accordo, lascia il sito.Maggiori informazioni sui cookie
arduino_3.txt · Ultima modifica: 2020/07/03 15:56 da 127.0.0.1