Indice

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

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:

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

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:

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

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:

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

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

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

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:

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

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:

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

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:

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:

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 principio di funzionamento del sensore è molto semplice:

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

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