Programmazione in movimento 3b - Librerie

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);

Usiamo la fotoresistenza per comandare un LED

  • A questo punto potremmo pensare di accendere un LED quando la luce diventa troppo scarsa
  • Per semplificarci le cose utilizzeremo il LED sulla scheda connesso al pin 13.
  • Per decidere se accendere o spegnere il LED dovremo confrontare il valore letto dalla fotoresistenza con una costante
  • Guardando i valori letti nell'esercizio precedente, porrei la costante attorno a 250, potremo se mai correggerle in seguito.

Usiamo la fotoresistenza per comandare un LED

  • Per fare cose diverse a seconda del confronto useremo il costrutto if. La forma più semplice prevede di eseguire un'azione se la condizione è vera:
    if (CONDIZIONE) {
    AZIONE
    }
  • Dove:
    • CONDIZIONE è un'espressione booleana (costituita da confronti collegati da && per E logico, || per O logico e ! per NON)
    • AZIONE è l'elenco di istruzioni che verranno fatte solo se la CONDIZIONE è vera.

Usiamo la fotoresistenza per comandare un LED

  • La forma completa prevede di eseguire un'azione se la condizione è vera ed un'altra se è falsa:
    if (CONDIZIONE) {
    AZIONE
    } else {
    AZIONE2
    }
  • Dove CONDIZIONE e AZIONE sono quelle di prima e:
    • AZIONE2 è l'elenco di istruzioni che verranno fatte solo se la CONDIZIONE è falsa.
  • Ma vediamo l'esempio all'opera.

Il Servomotore

Immagine slide
  • I servomotori sono piccoli motori utilizzati in modellismo, la cui posizione può essere comandata tramite un impulso su di un filo.
  • Il tipo più comune ed economico, l'SG90, possiede un cavetto con tre fili ed un connettore che tramite fili rigidi può essere connesso direttamente ad Arduino.
  • I tre fili non hanno colori standard:
    • ARANCIO impulso di comando
    • ROSSO positivo
    • MARRONE massa

Il Servomotore

Immagine slide
  • Una volta connesso come da schema (probabilmente non useremo la breadboard ma direttamente i fili), potremo programmarlo.
  • Per produrre il segnale di comando ci viene in aiuto una libreria già presente nell'IDE, che però dovremo richiamare.

Comando del servomotore

  • Come già accennato, la prima cosa che dovremo indicare nel nostro sketch è il caricamento della libreria:
    #include <Servo.h>
  • Dovremo poi creare una variabile che rappresenti il nostro servomotore. Servo è il tipo della variabile:
    Servo attuatore;
  • Come le altre volte ci creeremo una costante con il numero di pin cui è connesso il servomotore:
    #define SERVOPIN 4

Comando del servomotore

  • Per connettere la nostra variabile al servomotore, utilizzeremo il seguente comando, ad esempio nella funzione setup():
    attuatore.attach(SERVOPIN);
  • Una volta eseguita la attach la nostra libreria invierà continuamente il segnale di comando al servo, e questo comporta che il servo continuerà a consumare parecchia corrente (circa 300 mA con l'SG90).
  • Se ad un certo punto il servo deve restare fermo e non bloccato, potremmo scollegarlo:
    attuatore.detach();

Comando del servomotore

  • Dobbiamo ricordare che quando usiamo la detach() il servo si ferma nella posizione in cui è, quindi se impostiamo un angolo, prima di fare la detach() dovremo attendere il tempo che il servo si posizioni.
  • Ancora, se, dopo aver fatto la detach() dobbiamo fare un nuovo movimento, dovremo rifare la attach().
  • Se infine voglio portarlo ad un angolo a, compreso tra 0 e 180, userò il comando:
    attuatore.write(a);

Rallentare il movimento

  • Nell'esempio precedente abbiamo impostato angoli molto diversi, richiedendo un movimento il più veloce possibile.
  • Il più delle volte invece vogliamo che il movimento venga eseguito in un determinato tempo.
  • Visto che questa necessità è estremamente comune, proviamo a scrivere una funzione per questo.

Rallentare il movimento

  • La funzione avrà quattro parametri:
    1. Servo s Il servo da muovere
    2. int da l'angolo iniziale
    3. int a l'angolo finale
    4. int tempo il numero di secondi
  • Questa funzione dovrà spezzare il movimento in una serie di movimenti più piccoli, ciascuno per un centesimo di secondo.

Rallentare il movimento

  • Un problema nello scrivere questa funzione è che le operazioni, internamente, vanno svolte con la virgola, mentre i numeri passati saranno interi (int).
  • Vediamo nell'esempio come risolvere questo problema.

Termometro

  • Come sensore di temperatura ho scelto un Dallas DS18B20
  • Questo sensore, a differenza del più comune LM35, è un sensore digitale.
  • L'interfaccia è molto semplice, anche se non standard. Utilizza un solo filo di dato bidirezionale, infatti si chiama OneWire.
  • Il datasheet lo trovate all'indirizzo: https://datasheets.maximintegrated.com/en/ds/DS18B20-PAR.pdf
  • Per usarlo però non è necessario implementare tutta la comunicazione OneWire.

Termometro

  • Si possono scaricare due librerie che gestiscono la comunicazione e le conversioni

Librerie

Librerie

  • Una libreria non è altro che un file in C++, con la sua intestazione .h ed alcuni file di corredo che contengono informazioni per l'IDE
  • Una libreria può anche contenere altri file .cpp o .h.
  • Comunque tutti i file di una libreria devono stare all'interno di una directory con il nome del file .cpp o .h principali, senza estensione.
  • Questa directory dovrà essere all'interno della directory libraries, che si trova nella directory dei nostri sketch, in genere sketchbook

Librerie

  • Per installare le nostre librerie occorrerà quindi scompattarle, creare una directory con il nome corretto, copiarvi i file e inserire questa directory in libraries

Esempio con il termometro

  • Nell'immagine a sinistra si vede come collegare il sensore di temperatura.
  • Dato che abbiamo una basetta di breakout con già il sensore, la resistenza e un connettore a tre piedini, collegheremo questa basetta alla breadboard ed elimineremo la resistenza.
  • Ora, dato che abbiamo installato le nostre librerie, potremo iniziare il nostro sketch richiamandole:
    #include <OneWire.h>
    #include <DallasTemperature.h>

Esempio con il termometro

  • Ora dovremo creare un'istanza della classe che gestisce il bus 1-Wire:
    OneWire oneWire(ONE_WIRE_BUS);
  • E della classe che gestisce il sensore:
    DallasTemperature dm18b20(&oneWire);
  • Nella funzione setup, dopo aver inizializzato alla solita maniera la seriale, inizializzeremo anche il sensore:
    dm18b20.begin();
  • Nella funzione loop quindi richiederemo la lettura delle temperature:
    dm18b20.requestTemperatures();

Esempio con il termometro

  • E per finire leggeremo il valore della temperatura che sarà ritornato dalla funzione:
    dm18b20.getTempCByIndex(0)
  • Faccio notare che 1-wire è un bus, quindi possono essere connessi più sensori di temperatura (o altri sensori 1-wire) che potranno essere letti variando l'indice (0 nel nostro caso) tra parentesi.
[any material that should appear in print but not on the slide]