Programmazione in movimento 1 - Le basi

Cosa è Arduino

Immagine slide
  • Arduino è una piattaforma di prototipazione hardware open source italiana
  • Arduino è una scheda a microprocessore basata sul processore Atmel AtMega 328, nella sua versione base
  • Arduino è programmabile in linguaggio Arduino, basato su Wiring, ma praticamente C
  • Per programmarlo si utilizza un semplice IDE, che si basa sul compilatore GCC per AVR
  • Basta premere un bottone dell'IDE per scaricare il programma sulla scheda, connessa tramite il cavo USB

I Tipi di Arduino

  • In realtà Arduino è una famiglia di schede
  • Oltre al modello base Arduino Uno, contiene anche schede diverse, per scopi diversi e addirittura schede con processore a 32 bit
  • Arduino Mega è una scheda con molti più piedini di I/O, più memoria e più risorse, compatibile con gli shield standard o con shield dedicati.
  • Arduino Nano è una versione miniaturizzata di Arduino Uno, non compatibile con gli shield
  • Arduino Mini - una versione ancor più ridotta, priva dell'interfaccia USB

I Tipi di Arduino

  • Arduino Lilipad non supporta shield ed è fatto per inserirlo in capi d'abbigliamento
  • Arduino Due e Arduino Leonardo, basate su processori a 32 bit

Arduino Uno R3

  • Come fornita, la scheda Arduino possiede
    1. Un processore con la circuiteria per funzionare
    2. Una connessione seriale al processore, tramite adattatore USB-Seriale
    3. Un LED programmabile (L1)
  • Il processore funziona a 16 MHz e contiene 32 KiB di Flash EPROM per il programma e 2KiB di RAM per i dati

Arduino Uno R3

  • Quindi, con la sola scheda Arduino è possibile scrivere programmi che:
    • Fanno lampeggiare il LED L1
    • Comunicano con il PC tramite la seriale

L'anatomia di Arduino

Immagine slide
  • Vediamo ora, uno per uno, cosa sono i componenti della scheda Arduino, a partire dall'angolo in alto a destra
  • 1 è il pulsante di reset; serve per riavviare a mano il programma, a partire dall'inizializzazione
  • 2 è il connettore che consente di collegarsi agli ingressi/uscite digitali. Alcune di queste uscite possono anche produrre tensioni a più valori con la tecnica del PWM
  • 3 è il connettore USB. Serve sia per alimentare la schedina che per programmarla o comunicare con essa

L'anatomia di Arduino

Immagine slide
  • 4 Questo componente converte l'USB del PC nella seriale che usa il microprocessore ATMega
  • 5 Questo è il quarzo che regola la velocità del convertitore da USB a Seriaòle
  • 6 Questo secondo quarzo sereve per regolare la velocità del processore ATMega di Arduino
  • 7 questo circuito regola la tensione di aliemntazione principale a 5V del sistema, quando non viene alimentato dall'USB
  • 8 Questo è il processore ATMega che fa funzionare il nostro sistema, sarà il processore che programmeremo.

L'anatomia di Arduino

Immagine slide
  • 9 Questo è il connettroe di alimentazione. Potrremo usarlo per alimentare la scheda se deve funzionare da sola, non connessa al PC, quindi non alimentata tramite USB. Potremo connettere una pila da 9 o 12 V.
  • 10 Questo è il circuito che produce la tensione di alimentazione secondaria a 3.3V per alimentare alcuni circuiti.
  • 11 Questo connettore mette a disposizione le tensioni di alimentazione di Arduino per alimentare le schede o i componentiu esterni

L'anatomia di Arduino

Immagine slide
  • 12 e questo ultimo connettore consente di misurare con l'Arduino delle tensioni prodotte da dei sensori, come ad esempio il livello di luce tramite un sensore di luce, oppure la temperatura ambiente

L'IDE di Arduino

Immagine slide
  • Uno dei punti di forza di Arduino è l'IDE che consente di scrivere programmi e scaricarli sulla piattaforma in un attimo
  • L'IDE è disponibile alla pagina http://arduino.cc/en/Main/Software per Windows, Linux (32 e 64 bit) e Mac OS
  • L'IDE è ance inserito nelle distribuzioni Ubuntu (dalla 10.10 - Maverick) e Debian (dalla 6.0 - Squeeze)

La struttura di un programma Arduino

  • Un programma per Arduino si compone sempre di due funzioni di base, che dovremo scrivere.
  • La prima, void setup () {}, serve per configurare la scheda indicando, ad esempio, la velocità della seriale e l'uso dei piedini che comunicano con l'esterno
  • Questa funzione viene eseguita una sola volta, all'accensione (reset) della scheda
  • La seconda, void loop() {}, contiene le azioni che la scheda eseguirà
  • Questa funzione, se termina, viene ripetuta all'infinito fino a che non si spegne la scheda

Il primo programma - Lampeggio del LED

  • Per prima cosa, a livello globale, il LED è connesso al piedino digitale 13, quindi predisporremo una #define per questo piedino:
    #define LEDPIN 13
  • Quindi nella funzione setup () occorre richiamare la funzione che imposta in uscita il piedino del LED:
    pinMode(LEDPIN, OUTPUT);

Il primo programma - Lampeggio del LED

  • Per finire, dovremo mettere le istruzioni nella funzione loop () per eseguire un solo lampeggio; sarà poi il sistema che ripeterà all'infinito la funzione loop () per reiterare il lampeggio:
    digitalWrite(LEDPIN, HIGH); // Accende il LED 'L'
    delay (250); // Attende 1/4 di secondo
    digitalWrite(LEDPIN, LOW); // Spegne il LED 'L'
    delay (750); // Attende 3/4 di secondo

La toolbar dell'IDE

Immagine slide
  • Per prima cosa dovremo salvare utilizzando l'icona 5. Ci verrà richiesto il nome del nostro sketch (il nostro progetto)
  • Lo sketch viene salvato automaticamente nella cartella degli sketch di Arduino.
  • Potremo ora verificare se il nostro sketch presenta degli errori. Premeremo l'icona 1 e il risultato della compilazione ci verrà mostrato nella finestra in basso dell'IDE
  • Per poter scaricare sull'Arduino ed provare lo sketch dovremo aver configurato l'IDE per il tipo di Arduino e per la porta seriale che possediamo.

La toolbar dell'IDE

Immagine slide
  • Nel menù Tools->Serial Port troveremo l'elenco delle porte seriali tra cui scegliere e nel menù Tools->Board l'elenco delle schede
  • Una volta configurato l'ambiente, potremo premere l'icona 2 per compilare lo sketch e scaricare il programma sulla scheda
  • Se vogliamo ricaricare uno sketch salvato in precedenza potremo premere l'icona 4, che ci presenterà l'elenco di tutti gli sketch che abbiamo salvato e tutti gli sketch di esempio distribuiti con l'ambiente. Lo sketch sostituirà quello correntemente caricato

La toolbar dell'IDE

Immagine slide
  • Attenzione che gli sketch di esempio vengono aperti direttamente e non copiati, quindi se li modificate non potrete più recuperare gli originali. Meglio copiarli prima in un nuovo sketch o salvare lo sketch con un nome diverso e in un diversa directory
  • Per creare un nuovo sketch utilizzeremo l'icona 3, che svuota la finestra e si predispone per un nuovo sketch

Utilizziamo la seriale

  • Il nostro Arduino contiene un convertitore USB-Seriale che consente di programmarlo
  • Questo convertitore e questa seriale possono anche essere utilizzati dai nostri sketch per colloquiare con il PC collegato
  • Per prima cosa dovremo, nella funzione setup (), inizializzare la velocità della seriale (ad esempio utilizzando la velocità standard di 9600 Baud) con la funzione Serial.begin (9600); (che in realtà è un metodo della classe Serial)

Utilizziamo la seriale

  • Dentro la funzione loop () potremo utilizzare Serial.read() che ritorna un carattere letto dalla seriale, se disponibile o -1 se non ci sono più caratteri disponibili
  • Serial.print (<valore>) converte <valore> in stringa e lo stampa. Questo metodo è sovraccaricato per tutti i tipi di dato disponibile, comprese le stringhe.
  • Serial.println(<valore>) è identica alla Serial.print(<valore>), salvo che va a capo al termine della stampa
  • Serial.write (<valore>) stampa il <valore> senza alcuna conversione (stampa binaria)

Utilizziamo la seriale

  • L'esempio allegato legge i caratteri uno ad uno e ne stampa il valore ASCII ed i carattere stesso.
  • Per provarlo apriremo il terminale con il menù Tools->Serial Monitor oppure con la piccola lente d'ingrandimento alla destra della finestra. Quello che scriveremo nella linea di input verrà inviato premendo invio o il bottone Send all'Arduino, mentre quello che l'Arduino invierà verrà visualizzato nella finestra in basso

Leggiamo una riga di testo

  • Se invece di trattare i singoli caratteri vogliamo leggere una intera riga, dovremo per prima cosa allocare un buffer per la riga letta
  • Dovremo stare attenti perché il processore ha 2 KiB di RAM ed il compilatore non ci indica quanta ne usa il nostro programma, quindi sta a noi economizzarla
  • Potremo poi scrivere una funzione char * gets (char *buf, int buflen) che legga l'intera riga; questa funzione far&agrave; un loop di lettura caratteri fino alla ricezione del carattere di fine riga.

Leggiamo una riga di testo

  • Per aiutarci, potremmo anche scriverci una funzione char getc () che attenda un carattere, piuttosto che ritornare -1 se il carattere non &egrave; disponibile, facendo un loop sulla Serial.read().
  • Per utilizzare questo programma dobbiamo ricordarci di configurare il terminale in modo da inviare un a capo alla fine di ogni riga inviata
  • Per fare questo occorre selezionare NewLine al posto di No line ending dalla lista a destra in basso nella finestra del terminale

Leggiamo un numero intero

  • Un altro esempio potrebbe essere quello di leggere un numero intero.
  • Potremo utilizzare la funzione char getc() scritta per l'esempio precedente
  • Potremo ora scrivere una funzione int getint () che legga caratteri finché sono compresi tra 0 e 9 e converta i caratteri letti in un intero. Ritornerà al primo carattere non compreso nell'intervallo.
  • Ricordo che per convertire un carattere tra 0 e 9 nel suo valore numerico basta sottrarre il carattere '0'

Leggiamo un numero intero

  • Potremo utilizzare il metodo di leggere le cifre dalla più significativa (la prima che viene digitata), moltiplicare quanto già convertito per la base 10 ed aggiungere il valore della nuova cifra al risultato. In questo modo non ci servirà un buffer.
  • Anche per utilizzare questo programma dobbiamo ricordarci di configurare il terminale in modo da inviare un a capo alla fine di ogni riga inviata
  • Per fare questo occorre selezionare NewLine al posto di No line ending dalla lista a destra in basso nella finestra del terminale

I componenti esterni e gli shield

  • Abbiamo detto all'inizio che Arduino è una piattaforma di prototipazione hardware
  • Questo significa che lo scopo principale di Arduino è quello di controllare componenti elettrici connessi ai suoi connettori
  • I componenti esterni possono essere collegati direttamente inserendo i fili dei componenti nei connettori
  • Altrimenti possiamo utilizzare sempre dei fili inseriti nei connettori per collegare delle schede esterne con dei circuiti elettronici (che è quello che faremo in queste lezioni)

I componenti esterni e gli shield

  • Per finire è possibile creare delle schedine che posseggano dei connettori che si inseriscano direttamente nei connettori di Arduino. Queste schedine prendono il nome di shield
  • Il mercato fornisce una ampia gamma di shield che eseguono le operazioni pi&ugrave; disparate come sistemi di comunicazione a radiofrequenza, antenne GPS, schede di rete ed altro
  • Nel nostro progetto invece utilizzeremo delle schedine generiche, qualche componente discreto ed una breadboard per connettere il tutto tramite fili

Corente e tensione

Immagine slide
  • Prima di proseguire è meglio chiarire alcuni semplici concetti di elettronica.
  • La tensione, o meglio differenza di pontenziale può essere vista come la differenza di altezza dell'acqua di una diga, rispetto al livello del fiume sottostante.
  • La differenza di potenziale elettrico, come la differenza di energia potenziale dell'acqua della diga di per se non produce lavoro.
  • Se vogliamo che l'acqua per esempio si trasformi in energia elettrica, dobbiamo farla scendere tramite un tubo dalla diga e farla passare per una centrale.

Corente e tensione

Immagine slide
  • Nel caso dell'elettricità dovremo farla passare attraverso un filo elettrico e portarla ad attraversare ad esempio una lampadina.
  • Mantenendo l'analogia con l'acqua, più è forte la corrente d'acqua nel tubo, più la centrale produce corrente.
  • Nel caso della nostra lampadina, più è forte la corrente elettrica che scorre attraverso l lampadina, più la lampadina si illumina.

Resistenza e legge di Ohm

  • A questo punto viene la domanda: data la differenza di potenziale posso determinare la corrente che passa?
  • La risposta non è sempre semplice: dipende da cosa metto in mezzo.
  • Il caso più semplice è che io metta in mezzo un resistore o un componente con un comportamento analogo (una lampadina è all'incirca così).
  • In un resistore la corrente aumenta linearmente all'aumentare della differenza di potenziale secondo un fattore di proporzionalità espresso in OHM.

Resistenza e legge di Ohm

  • Detta R la resistenza in OHM, I la corrente in AMPERE e V la differenza di potenziale in VOLT, le relazioni che posso scrivere sono:
    • V=R*I
    • I=V/R
    • R=V/I

Potenza

  • La potenza elettrica P, espressa in WATT è data dalla formula P=V*I dove V ed I sono gli stessi della slide precedente.
  • In un resistore questa potenza è completamente trasformata in calore.
  • In un motore elettrico è trasformata in movimento (potenza meccanica)
  • In una lampada o un LED la potenza viene trasformata in luce.
  • In un altoparlante viene trasformata in suono.

Potenza

  • In tutti i casi però una parte della potenza viene comunque trasformata in calore.

Correnti e tensioni di Arduino

  • Arduino Uno funziona a 5V.
  • Può essere alimentato tramite l'USB, nel qual caso la corrente che possiamo utilizzare è quella fornita dall'USB stessa (se è una USB normale, 500mA).
  • Arduino possiede anche un regolatore di tensione ed una presa di alimentazione tonda. In questa presa possiamo mandare una tensione tra 7,5V e 12V.
  • Il regolatore riesce ad erogare fino a 750 mA.
  • Arduino ha a bordo anche un regolatore a 3,3V, per alimentare circuiti che richiedono questa tensione.

Correnti e tensioni di Arduino

  • Questo regolatore può erogare fino a circa 250mA. Occorre ricordare che questa corrente viene prelevata dall'alimentazione a 5V, quindi va sottratta a quella delle altre periferiche.
  • Agli ingressi di Arduino possono essere collegati circuiti logici sia a 5V che a 3,3V.
  • Le uscite di Arduino sono a 5V, quindi occorre stare attenti che i circuiti che connettiamo sopportino questa tensione (molti integrati a 3,3V la sopportano, ma non tutti), altrimenti la dovremo ridurre con delle resistenze.

Leggere il valore di un resistore

Immagine slide
  • Nei resistori comuni il valore della resistenza è indicato tramite tre fasce colorate
  • Le due a sinistra indicano le cifre del valore mentre quella a destra indica il numero di 0 da aggiungere a destra delle cifre precedenti.

Leggere il valore di un resistore

Immagine slide
  • I valori associati ai colori sono:
    • 0 Nero
    • 1 Marrone
    • 2 rosso
    • 3 arancione
    • 4 giallo
    • 5 verde
    • 6 blu
    • 7 viola
    • 8 grigio
    • 9 bianco

Leggere il valore di un resistore

Immagine slide
  • Di conseguenza la resistenza in figura, che ha le strisce di colore marrone, nero e rosso, è di 1000 OHM vale a dire 1KOhm
  • L'ultima fascia è di solito argento od oro ed indica la precisione (argento=10%, oro=5%)

Fotoresistenza

Immagine slide
  • Le fotoresistenze sono dei resistori che cambiano il valore di resistenza a seconda di quanta luce colpisce la loro superficie.
  • Se vogliamo, con questo componente, misurare la luce, dobbiamo trasformare la resistenza in una differenza di potenziale proporzionale alla resistenza del componente
  • Se guardiamo la legge di Ohm, potremmo usare la forma V=R*I; se potessimo fornire una corrente costante di valore appropriato, potremmo trasformare la resistenza differenza di potenziale in maniera lineare.

Fotoresistenza

Immagine slide
  • Purtroppo, un generatore di corrente costante è un componente difficile da trovare.
  • Un'alternativa è quella di utilizzare un partitore di tensione,collegando a massa un capo della fotoresistenza e l'altro al positivo tramite una resistenza di opportuno valore, come nello schema a destra..
  • A questo punto potremo calcolare la tensione con la seguente formula: Vout=Vcc*R1/(R1+R2)

Colleghiamo la fotoresistenza

Immagine slide
  • Per prima cosa occorre collegare la fotoresistenza e la resistenza ad Arduino. Basta seguire lo schema qui a lato.
  • Lo schema prevede che la tensione prodotta dal partitore venga fornita all'ingresso A1 dell'Arduino.
  • Questo è un ingresso analogico, connesso ad un convertitore analogico/digitale a 10 bit che fornisce numeri da 0 (per 0 volt di ingresso) a 1024 (per 5 volt di ingresso)
  • Per leggere il valore basta richiamare la funzione analogRead(A1); che ritornerà il valore letto.

Colleghiamo la fotoresistenza

Immagine slide
  • Non occorre inizializzare nulla per poter leggere il valore, quindi in setup() inizializzeremo solo la seriale.
  • In loop() leggeremo il valore, lo stamperemo con Serial.println(); ed attenderemo mezzo secondo con delay(500);

LED

Immagine slide
  • Il LED (Light Emitting Diode) è un componente attivo che, se attraversato da corrente, emette luce.
  • Essendo un componente attivo, non conduce la corrente in entrambe le direzioni, ma soltanto dall'anodo al catodo.
  • Possiamo notare dalla foto che ha un piedino più lungo dell'altro. Questo piedino è l'anodo e va collegato alla tensione positiva.
  • A differenza del resistore, la tensione ai suoi capi varia di poco all'aumentare della corrente, ma resta da un valore che dipende dal tipo, tra 1,2V e 3V.

LED

Immagine slide
  • Se vogliamo alimentarlo a 5V, dovremo mettere in serie al LED una resistenza che consumi la restante tensione, facendo passare la corrente che desideriamo. La calcoleremo con la legge di Ohm: I=V/R
  • Di norma nei LED si fa passare una corrente tra i 10mA ed i 30mA. Una corrente troppo alta farebbe bruciare il LED.

Colleghiamo il LED

Immagine slide
  • Collegheremo il LED tra piedino 3 di Arduino e massa, tramite una resistenza da qualche centinaio di Ohm, per limitare la corrente.
  • Lo sketch sarà quello che all'inizio faceva lampeggiare il LED a bordo, modificato per far lampeggiare il nuovo LED connesso al piedino 3.

EXTRA: Mischiamo i due sketch e variamo il lampeggio

  • Ora possiamo modificare lo sketch. Voglio far lampeggiare sia il LED esterno che quello interno, con un diverso schema:
    1. Esterno per 100 mS
    2. Spento per 100 mS
    3. Esterno per 100 mS
    4. Spento per 100 mS
    5. Interno per 100 mS
    6. Spento per 500 mS

PWM

Immagine slide
  • Con la digitalWrite() noi possiamo o accendere completamente o spegnere completamente il nostro LED
  • Se volessimo invece accenderlo solo parzialmente dovremmo variare la tensione che abbiamo sul piedino, ma questo non è possibile, visto che il piedino è digitale.
  • In alternativa potremmo accendere e spegnere alternativamente ad una velocità elevata il piedino. Il nostro occhio vedrebbe la luce media emessa.
  • Se il tempo di accensione e tempo di spegnimento sono diversi, il livello di luce potrà variare da un minimo ad un massimo.

PWM

Immagine slide
  • Questa tecnica viene chiamata Pusle Width Modulation o PWM e viene gestita in hardware da Arduino per i piedini che hanno una ~ di fianco al numero.
  • La funzione analogWrite() imposta il piedino come PWM e ne regola il duty cycle (rapporto tra tempo a 5V e tempo a 0V) tra 0 (sempre a 0) e 255 (sempre a 5V). Il piedino deve essere stato impostato in uscita.

Extra: AnalogWrite

  • La funzione analogWrite ha due parametri: il primo è il piedino da gestire ed il secondo è il valor medio da impostare: analogWrite(PIEDINO, VALORE);
  • Non tutti i piedini dell'Arduino possono essere utilizzato con la AnalogWrite, ma solo quelli contrassegnati con il simbolo ~ (tilde), che sono il 3, 5, 6, 9, 10 e 11
  • Possiamo ora modificare il nostro sketch che accende e spegne il LED esterno in modo che tra l'accensione e lo spegnimento imposti il LED a mezza luce.

Extra: AnalogWrite

  • Verificato che il piedino 3 è nella nostra lista, possiamo ora aggiungere un piccolo intervallo di tempo nel quale imposteremo l'uscita a metà tensione, vale a dire 255/2 (arrotondato per eccesso) 128.

Extra: Ciclo For - dimmer

  • L'esempio precedente si avvicina a quello che vorrei ottenere. Mi piacerebbe vedere il LED che si accenda gradualmente.
  • Se voglio avere un'accensione graduale, dovrei passare attraverso tutti i possibili livelli della nostra analogWrite:
  • Un ovvio modo è quello di scrivere per 255 volte la coppia di istruzioni analogWrite e delay, con valori diversi di intensità.

Extra: Ciclo For - dimmer

  • Molto meglio è impostare una iterazione. Per questa iterazione utilizzeremo una variabile (ne abbiamo già viste) come contatore e useremo questo contatore come valore di intensità.
  • L'istruzione che crea un'iterazione (almeno una delle istruzioni) è for.
  • L'istruzione for si scrive i questo modo:
    for (INIZIALIZZAZIONE; CONDIZIONE; INCREMENTO) {
    ISTRUZIONI
    }

Extra: Ciclo For - dimmer

  • dove:
    • INIZIALIZZAZIONE imposta il valore iniziale del nostro contatore
    • CONDIZIONE verifica che il nostro contatore non abbia raggiunto il valore finale
    • INCREMENTO porta il contatore al prossimo valore
  • Vediamo il tutto nell'esempio.

Extra: La seriale - semplice

  • Come detto in precedenza, per utilizzare la seriale dovremo prima impostarne la velocità nella funzione setup() utilizzando la Serial.begin(9600) dove 9600 è il valore scelto (un valore standard) di bit per secondo.
  • Ora potremo, nella funzione loop(), stampare dei messaggi con la Serial.print e Serial.println.

Extra: La seriale - semplice

  • Ricordiamo che:
    • Serial.print(VALORE) stampa VALORE e rimane sulla stessa riga
    • Serial.println(VALORE) stampa VALORE e passa alla riga successiva
  • Vediamo tutto questo nell'esempio
[any material that should appear in print but not on the slide]