Mese: Luglio 2021


Lezione 7

By lapinig,

Uso di sensori

In questa lezione vedremo come utilizzare alcuni sensori

Iniziamo però subito con la definizione del termine: un sensore o trasduttore è un dispositivo che converte una grandezza fisica in un altro tipo di grandezza fisica (a volte è sempre la stessa). Tipicamente però quelli che interessano a noi sono quelli che “traducono” una qualsiasi grandezza fisica in una grandezza di tipo elettrico (tipicamente una tensione elettrica) poichè dobbiamo “leggerla” con un microcontrollore. In realtà in ambiente elettronico i due termini “sensore” e “trasduttore” non sono esattamente equivalenti, il primo comprende anche la circuiteria che esegue l’adattamento al circuito che dovrà misurare questa tensione.

In questa lezione utilizzeremo diversi tipi di sensore, iniziamo con un sensore di luce ambientale (nello specifico una fotoresistenza). Tecnicamente il componente è conosciuto con la sigla LDR (Light Dependent Resistor). Un esempio di componente reperibile in commercio (ad esempio presso RS) può essere il NSL-19M51.

Esercitazione 14 – Luce Scale

Con la piattaforma TinkerCad realizziamo questo circuito

Si vuole realizzare un sistema per l’illuminazione delle scale di un condominio con alcune considerazioni di risparmio energetico:

  1. Tramite una fotoresistenza viene letta l’illuminazione ambientale (notare che il sensore è all’interno del vano scale)
  2. Premendo il pulsante la luce delle scale si accende per il tempo prefissato, solo però se l’illuminazione del vano scale è insufficiente (di giorno non si accende la luce bianca delle scale)
  3. Premendo nuovamente il pulsante, a temporizzazione già avviata, essa deve ripartire da zero (immaginiamo il bisogno di una persona che sale le scale lentamente ed ha bisogno di maggior tempo per raggiungere il piano desiderato)
  4. Una volta partita la temporizzazione, il sensore di luce non deve essere riletto, al fine di allungare la temporizzazione, poichè esso si trova nel vano scale e sicuramente viene illuminato dalla luce bianca.
  5. Si vuole, inoltre, una illuminazione di colore giallo posta a livello degli scalini (luce guardapasso o guidapasso), a LED di bassissima potenza e quindi a consumo ridottissimo. Questa luce si deve accendere automaticamente la notte, al di sotto di un certo livello di luminosità, per visualizzare i gradini ed evitare incidenti. Naturalmente questa luce si spengerà durante la temporizzazione della luce bianca.

Durante la lezione abbiamo visto e risolto alcuni problemi inerenti alla temporizzazione. Il codice completo lo potete trovare qui.

Esercitazione 15 – Sistema di allarme con sensore di movimento

Un altro esempio di sensore può essere il sensore di movimento con tecnica PIR (Passive InfraRed) prodotto da Parallax ma anche da Adafruit, del quale potete trovare il datasheet a questo link.

Con la piattaforma TinkerCad realizziamo questo circuito

Si vuole realizzare un semplice sistema di allarme, basato su di un sensore di movimento, che abbia queste caratteristiche:

  1. Appena viene rilevato un movimento si deve accendere la segnalazione gialla di PREALLARME. In ogni caso la segnalazione di preallarme deve rimanere accesa per almeno 3 secondi dal momento in cui cessa il movimento.
  2. Ogni evento di preallarme deve essere conteggiato e, al terzo preallarme che si presenta entro un lasso di tempo di 15 secondi, si deve accende la segnalazione rossa di allarme, che deve rimanere accesa per almeno 5 secondi. Durante la segnalazione di allarme quella di preallarme si deve spengere. Dopo i 15 secondi indicati il contatore dei preallarmi si deve resettare. Così come si resetta all’attivazione della segnalazione di allarme.
  3. Insieme alla segnalazione ottica di allarme si deve attivare, per il medesimo tempo, la segnalazione acustica tramite il buzzer piezoelettrico.

Durante la lezione abbiamo visto, passo-passo, come implementare tramite il software una dopo l’altra le richieste del cliente. La procedura consigliata è, sempre, quella di testare una funzione dopo l’altra, verificando ad ogni nuova aggiunta il corretto funzionamento di tutto il programma.

In effetti, nel collaudo finale, ci siamo accorti di una anomalia dovuta ad un caso non previsto nell’elencazione iniziale delle caratteristiche: se viene rilevato l’inizio di un movimento, correttamente si accende la spia gialla, correttamente si incrementa il conteggio dei preallarmi, ma, se il movimento è continuo nel tempo succede che non si attiverà mai la segnalazione di allarme.

Il problema è stato isolato utilizzando il metodo di debug del funzionamento tramite la comunicazione seriale: stampiamo sulla seriale le informazioni che necessitano per verificare cosa sta succedendo all’interno del microcontrollore. Questa è una tecnica molto usata nella fase di sviluppo e di collaudo finale del programma. Abbiamo anche visto come, tramite dei semplici #define, attivare/disattivare questa funzionalità di debug.

Abbiamo quindi aggiunto un’ulteriore variabile che memorizza l’istante in cui viene “visto” il primo movimento e, se esso non cessa, dopo 10 secondi di movimento continuativo, viene comunque attivato l’allarme.

Il programma definitivo lo trovate qui.

Riepilogo dei contenuti della lezione:

  1. Uso di comandi di #define, #ifdef, #else ed #endif per creare porzioni di codice da attivare/disattivare a piacimento.
  2. Uso di scrittura dati di debug sulla linea seriale per verificare lo stato di alcune variabile durante il funzionamento del programma.
  3. Combinazione di strutture di codice semplici in strutture più complesse, riuso del codice (creazione e riutilizzo di funzioni).

Alla prossima lezione…

Lezione 5

By lapinig,

Uso di un display LCD

In questa lezione vedremo come utilizzare un display LCD per le nostre applicazioni. A differenza delle precedenti lezioni, in cui veniva utilizzato un display a 7 segmenti, molto più limitato potendo visualizzare solo le cifre ed alcune lettere, questa volta utilizzeremo un componente che vi permetterà di visualizzare molte più informazioni ed in modo più dettagliato. Il display a caratteri oramai universalmente utilizzato è quello basato sul chip HITACHI HD-44780 e permette di governare display a 1, 2 o 4 righe, da 10, 12, 16, 20, 24 fino a 40 colonne.

Il modello da noi utilizzato è quello 16×2 (2 righe di 16 caratteri) che si trova anche come modello nell’ambiente TinkerCad.

Nelle interfacce “bordo macchina” delle schede che governano macchine complesse sono sempre presenti dei display, a volte di tipo “carattere” come quello che utilizzeremo oggi, ma molto più spesso di tipo “grafico”.

Esercitazione 10: Uso del display LCD

Con la piattaforma TinkerCad realizziamo questo circuito

Si vuole realizzare un controllo che piloti l’accensione temporizzata di un motore:

  1. Deve essere possibile impostare con due tasti il tempo di accensione del motore ( tasto incremento, tasto decremento ) con precisione di 0,5 secondi. Tempo minimo 0,5 sec e tempo massimo di 99.5 sec.
  2. Sul display dovrà essere sempre visualizzato il tempo rimanente di accensione del motore.
  3. Sul display dovrà essere sempre visualizzato lo stato del motore (STOP, RUN ed altri eventuali stati).

Richieste aggiuntive:

  • Una volta partita la temporizzazione del motore dovrà essere possibile, premendo di nuovo il pulsante di START, eseguire una pausa nella quale lo scorrimento del tempo si deve fermare ed il motore si spenge temporaneamente, ripremendo lo stesso pulsante il motore riparte e con esso la temporizzazione.
  • Una volta partito il motore, tramite un altro pulsante detto di STOP, dovrà poter essere annullata la temporizzazione.
  • I due pulsanti PIU e MENO permettono di regolare il tempo di attivazione con passi di 0,5 secondi ad ogni loro pressione. Questi pulsanti dovranno permettere, tramite la gestione della loro pressione prolungata (intorno a 1 secondo), l’accelerazione della modifica del tempo, in modo che mantenendo premuto il pulsante stesso il tempo impostato si autoincrementi velocemente.

Durante la lezione abbiamo incontrato diversi problemi a cui abbiamo posto soluzione, ricordiamone alcuni:

Lavorando con temporizzazioni espresse in decimi di secondo avevamo utilizzato numeri interi, il cui uso in linguaggio C è notevolmente più veloce. Dovendo però rappresentare tali tempi in una interfaccia destinata ad “umani” avevamo il problema di rappresentare tale tempo in secondi e frazioni di esso.

  • Abbiamo quindi utilizzato la divisione intera ( / ) che restituisce solo il quoziente e l’operazione di modulo ( % ) che è sempre una divisione intera che restituisce però solo il resto di essa.
  • Abbiamo utilizzato dei controlli ( IF ) per posizionare correttamente la stampa del numero se era composto solo da unità o anche da decine.

Abbiamo inoltre utilizzato variabili aggiuntive per permettere la messa in pausa della temporizzazione ed anche il temporaneo spengimento del motore.

Abbiamo utilizzato un controllo ( IF ) per determinare la funzionalità del pulsante di START che, una volta partita la temporizzazione, doveva modificare il suo comportamento.

Il programma terminato e completo in tutte le sue funzionalità lo trovate qui.

Il display utilizzato permette di visualizzare tutto il set di caratteri maiuscolo/minuscolo, numerico e segni di interpunzione delle lingue occidentali, alcuni caratteri dell’alfabeto greco ed anche un set di caratteri giapponese.

Riepilogo dei contenuti della lezione:

  1. Uso della divisione fra interi in linguaggio C (recuperando quoziente e resto).
  2. Puntualizzazione sulla flessibilità delle strutture per aggiungere/modificare funzionalità a questi “oggetti”.
  3. Uso di abbreviazioni nelle operazioni aritmetico-logiche: nella fattispecie uso di ++, –, +=, -=, *=, /=, |=, &=, ecc. ecc.
  4. Installazione di librerie aggiuntive e loro inclusione nel codice C (direttiva #include).

Alla prossima lezione…

Lezione 4

By lapinig,

La “scoperta dell’acqua calda”

In questa quarta lezione passiamo ad usare metodi volti a NON “dover riscoprire sempre l’acqua calda”…

Scrivendo un codice, dopo averlo collaudato e verificato il corretto funzionamento, eliminandone tutti i possibili errori o problemi, non conviene mai doverlo riscrivere sempre ad ogni nuovo programma.

Questo non vuol dire semplicemente che dobbiamo usare il “copia ed incolla” che, peraltro, è utilissimo. Vuole invece dire che occorre scrivere il codice in maniera da poterlo riutilizzare anche in altri programmi con poche o nessuna modifica. Partiremo in questa lezione con un programma già scritto nella lezione precedente, vedremo che la parte che ci interessa per la gestione del display è la medesima, mentre la parte che gestisce la pressione dei pulsanti (con anti-rimbalzo) è corretta ma andrà riscritta per gestire un numero maggiore di pulsanti senza raddoppiare il numero di righe di codice necessarie.

Esercitazione 9: Uso di strutture e funzioni

Con la piattaforma TinkerCad realizziamo questo circuito

Partendo dalla base di un altro esercizio già svolto nella Lezione 3, si deve realizzare un timer con conteggio alla rovescia e quattro pulsanti: due per la impostazione del tempo di durata, un pulsante di start ed un pulsante di stop/reset.

L’uscita comanda da Arduino potrebbe essere un timer per esposizione fotografica, un timer per accensione forno per cottura, ecc. ecc.

Organizziamo però meglio il lavoro rispetto all’esercizio di partenza: mentre in esso vi erano variabili con nomi diversi per gestire la pressione dei pulsanti con controllo anti-rimbalzo adesso, raddoppiando i pulsanti, non conviene più utilizzare questo metodo.

Occorre “riutilizzare” lo stesso codice per TUTTI i pulsanti, anche per quelli che verranno eventualmente aggiunti in futuro. Senz’altro creiamo una funzione che gestisca la pressione del pulsante (stato attuale, stato precedente, tempo dell’ultima variazione, ecc.). Per poter fare questo occorre prima generare una “struttura” ad-hoc.

// Struttura che raggruppa alcune variabili per la
// gestione dell’oggetto PULSANTE
typedef struct
{
int Porta;
bool newLettura;
bool oldLettura;
unsigned long long TimeUltimaVariazione;
// Stato STABILE del pulsante
bool StatoAttuale;
bool StatoPrecedente;
} _PULS_STRUCTURE;

Praticamente con l’istruzione typedef struct creiamo un “nuovo” tipo di variabile che in realtà è un gruppo di variabili. Dal nome possiamo riconoscere più o meno quelle utilizzare nella Lezione 3.

Di seguito con la riga

_PULS_STRUCTURE Pulsante[NUM_PULSANTI];

dove NUM_PULSANTI nel nostro caso vale 4, avvisiamo il compilatore che esiste un gruppo di 4 variabili (o array) di nome Pulsante organizzate con la nuova struttura creata di nome _PULS_STRUCTURE.

Per utilizzare le variabili contenute in questa struttura utilizzeremo comandi di questo tipo: Pulsante[3].newLettura = digitalRead(..….

Dove la variabile newLettura contenuta nel gruppo Pulsante all’indice 3, verrà scritta con il contenuto dell’ingresso letto sul piedino di Arduino indicato. Attenzione al fatto che l’indice 3 indica la quarta (ed ultima in questo caso) variabile Pulsante ovvero quella che si riferisce all’ultimo pulsante sulla destra.

L’uso di queste variabili indicizzate (o array) è molto utile e ci permette di creare una sola funzione che esegue i comandi da noi forniti per tutti gli indici, anche se fossero centinaia e centinaia…

Il codice completo del programma che abbiamo visto nel corso della lezione del 21 giugno scorso lo potete trovare qui.

Riepilogo dei contenuti della lezione:

  1. Abbiamo creato una struttura (typedef struct) per raggruppare più variabili riconducibili ad un gruppo che a sua volta può essere indicizzato. Nello scrivere il codice non dobbiamo “risparmiare” sul numero delle variabili che, spesso, sono centinaia od anche migliaia, ma sui loro nomi, in questo modo risparmieremo con la scrittura del codice, specialmente se usiamo variabili indicizzate (o array), potendo scrivere codice riutilizzabile.
  2. Abbiamo creato una funzione “riutilizzabile”, cioè con la stessa funzione, passandogli parametri diversi possiamo gestire, nel nostro esempio, più pulsanti.