Categoria: Elettronica


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.

Lezione 3

By lapinig,

Operazioni di controllo (mascherature)

In questa terza lezione passiamo ad analizzare la parte essenzialmente di “controllo” svolta da un microcontrollore. Una volta acquisite le situazioni in cui si trovano gli ingressi, collegati al mondo esterno, il microcontrollore può effettuare una serie di controlli, spesso andando a verificare lo stato di un singolo bit, tramite una sequenza di “mascherature” per eliminare, di volta in volta, i bit non influenti ed isolare solo quelli necessari.

Esercitazione 7: Uso di mascherature di controllo

Con la piattaforma TinkerCad realizziamo questo circuito

Si vuole realizzare il seguente funzionamento:

  1. Il dip switch 1 accende/spenge il Led Verde
  2. Il dip switch 2 accende/spenge il Led Rosso
  3. Quando il dip switch 3 è alto allora il terzo led (Blu) si accenderà quando i primi due led hanno stati diversi, altrimenti resterà spento
  4. Quando il dip switch 4 è alto allora il terzo led (Blu) si accenderà quando il primi due led hanno il medesimo stato, altrimenti resterà spento.

Nella richiesta non sono state prese in esame le altre due possibili combinazioni del 3° e 4° dip-switch, eventualmente si potrebbe prevedere l’ipotesi che il Led Blu sia sempre spento quando i suddetti dip-switch sono entrambi bassi ovvero sempre acceso quando i due dip-switch sono entrambi alti.

Il codice sorgente completo per ottenere questa comportamento lo trovate qui.

Esercitazione 8: Uso del controllo switch()

Con la piattaforma TinkerCad realizziamo questo circuito

Il microcontrollore di Arduino pilota, tramite sette (od otto) uscite un display a 7 segmenti LED. Si vuole realizzare quindi un convertitore binario-decimale con relativo visualizzatore. Come ci siamo accorti ben presto durante la lezione, le combinazioni possibili sul dip-switch a 4 contatti sono 16, ben oltre le dieci combinazioni della numerazione decimale.

Il display utilizzato ha una struttura come indicato di seguito

Il display da noi utilizzato è però del tipo a catodo comune, quindi tutti e otto i led sono invertiti ed il piedino comune (Common) è collegato a tutti i catodi e pertanto, per poter accendere il segmento, andrà collegato a GND (alimentazione negativa), mentre il pin di uscita di Arduino porterà al singolo segmento il positivo.

I singoli segmenti hanno una sigla indicata con le lettere alfabetiche dalla A fino G, partendo dal segmento in alto e proseguendo in senso orario. Il punto decimale (Decimal Point) è indicato dalla sigla DP.

Mentre è abbastanza ovvio capire quali segmenti vanno accesi per ottenere le combinazioni numeriche da 0 fino a 9 (numerazione decimale), un po’ meno chiaro è cosa fare con le combinazioni da 10 a 15. Utilizzeremo per la visualizzazione sul display la codifica esadecimale, faremo quindi un visualizzatore in base 16. I simboli ,da sempre utilizzati in ambiente elettronico/informatico per visualizzare queste combinazioni, sono le lettere dell’alfabeto dalla A fino alla F.

Per visualizzare questi ulteriori simboli utilizzeremo a volte le lettere maiuscole e a volte le lettere minuscole, poichè questo tipo di display, molto semplice e con pochi piedini è nato ben prima di queste esigenze. Qui sotto potete vedere alcuni esempi di visualizzazione di caratteri alfabetici

Per la cronaca esistono altri modelli di display che arrivano fino a 14/16 segmenti e che riescono a visualizzare qualsiasi carattere alfabetico.

Il codice sorgente completo per ottenere questa comportamento lo trovate qui.

Riepilogo dei contenuti della lezione:

  1. Abbiamo creato una funzione separata Visualizza() per cercare di non “intasare” la funzione loop() facendola diventare estremamente lunga. Questo modo di procedere è consigliato perchè permette di mantenere “leggibile” il codice sorgente e permette anche di creare funzioni che, tramite il copia/incolla, possono essere facilmente riutilizzate in altri programmi (non bisogna mai “riscoprire l’acqua calda” tutte le volte).
  2. Abbiamo i vari tipi di controllo if()/else anche con più ramificazioni if()/elseif()/else.
  3. Abbiamo utilizzato il controllo switch() quando il numero di ramificazioni del controllo if() cominciare a diventare insostenibile.
  4. Abbiamo utilizzato le “mascherature” con le funzioni AND (&) ed OR (|). Qui potete vedere alcuni esempi che abbiamo visto durante la lezione. Anche qui potete vedere altri esempi.
  5. Abbiamo utilizzato la scrittura delle maschere in esadecimale (0x5B ad esempio) per poter passare direttamente e velocemente da numeri binari a numeri facilmente leggibili da noi “umani”.

Alla prossima lezione…

Lezione 2

By lapinig,

Operazioni di INPUT

In questa seconda lezione passiamo ad analizzare l’altra operazione che permette al microcontrollore che governa Arduino di interagire con il mondo “esterno”.

Si tratta dell’operazione di INPUT. L’operazione viene definita di “ingresso” (input) poichè i dati del mondo esterno “entrano” all’interno del microcontrollore.

A differenza della scorsa lezione si tratta quindi di operazioni di lettura.

Esercitazione 4: Uso di interruttori

Con la piattaforma TinkerCad realizziamo questo circuito

Quello che si vuole realizzare è un funzionamento di questo tipo:

  1. Commutando lo switch S1 si deve accendere/spengere il Led Verde
  2. Commutando lo switch S2 si deve accendere/spengere il Led Rosso

Il programma è quindi molto facile da realizzare… il codice lo trovate qui.

Scritto quasi ad “occhi chiusi” perchè tanto è semplice… ma, ma… andando in simulazione ci accorgiamo che non funziona. O meglio, qualcosa fa, ma non esattamente quello che volevamo. All’inizio a volte i led sono spenti, ma spesso sono accesi, in ogni caso facendo scorrere la slitta dell’interruttore si accendono e non si spengono più.

Per controllare meglio proviamo a collegare un multimetro, impostato come voltmetro, all’ingresso del microcontrollore. In effetti ci accorgiamo che la tensione passa da 5 volt (alimentazione positiva) a quasi zero, ma non zero, ovvero a poco più di 50 mV. Inoltre l’interruttore su cui abbiamo collegato il voltmetro adesso funziona perfettamente, ossia accende e spenge regolarmente il Led Rosso.

Cosa succede?

Quando spostiamo la slitta dell’interruttore e scolleghiamo il piedino del microcontrollore dalla tensione di +5 volt, il filo connesso al piedino rimane scollegato, libero, ossia non connesso a nessun potenziale elettrico, in gergo si dice che è “flottante”. Un conduttore lasciato libero in aria funziona come da antenna e riesce a captare piccoli segnali elettrici o a mantenere per lungo tempo il potenziale che aveva in precedenza, prima di riuscire a disperderlo. In sostanza in genere si comporta spesso come se fosse collegato ad una sorgente di tensione, in ogni caso il potenziale a cui si pone è assolutamente aleatorio.

Per evitare questo problema ogni conduttore deve essere sempre e comunque legato ad un potenziale alto (alimentazione positiva) o basso (alimentazione negativa o massa). Nel nostro caso possiamo risolvere collegando un resistore da 10 Kohm verso il negativo (resistore di pull-down), riprovando con il medesimo programma di prima vedremo che il problema non si ripresenta e tutto funziona correttamente. Vedremo anche che la tensione sul piedino andrà da +5 volt a 0 volt.

Esercitazione 5 e 6: Uso di pulsanti

Con la piattaforma TinkerCad realizziamo questo circuito

Memori dell’esperienza precedente questa volta mettiamo subito i resistori di pull-down sul piedino del microcontrollore.

Prima di effettuare i collegamenti occorre puntualizzare il tipo di pulsante da noi utilizzato. In questo tipo di pulsante i quattro terminali sono collegati a coppie: i piedini 1 e 2 sono collegati insieme tra loro, così come i piedini 3 e 4, quando viene premuto il pulsante queste due coppie 1-2 e 3-4 vengono a sua volta collegate fra loro.

Guardando lo schema realizzato con TinkerCad i piedini sulla sinistra ed etichettati con 1a e 1b costituiscono una coppia, mentre quelli con etichetta 2a e 2b costituiscono l’altra coppia. Per visualizzare l’etichetta basta posizionare il puntatore del mouse sul piedino ed attendere un istante.

La funzione da realizzare richiesta al programma è la seguente:

  1. All’inizio tutti i Led sono spenti.
  2. Premendo il pulsante di sinistra una volta il Led Verde si accende (poichè era spento)
  3. Premendo il pulsante di sinistra una volta ancora il Led Verde si dovrà spengere e così via.
  4. Il pulsante destro si comporterà come il precedente, però attivando/disattivando l’accensione del Led Rosso.

Come abbiamo visto durante la lezione, da adesso in poi converrà strutturare la sequenza del programma in questo modo:

  1. Il programma deve “leggere” lo stato di TUTTI gli ingressi e lo memorizza temporaneamente in memoria (RAM) per gli usi successivi. In pratica il microcontrollore fa una “foto” dello stato del mondo esterno.
  2. Il microcontrollore, tramite il programma, elabora questi dati e prende delle “decisioni”, in pratica crea altri dati.
  3. Il microcontrollore emette in uscita alcuni dati (risultati dalle elaborazioni precedenti e quindi dagli ingressi letti), “scrive” cioè verso il mondo esterno.

Il programma creato (che trovate qui), che a prima vista non presenta errori, però non si comporta come desiderato. Durante la simulazione a volte la pressione del pulsante fa cambiare di stato al Led associato ma, molto più spesso lo lascia invariato. Nel corso della lezione abbiamo visto che introducendo un certo ritardo nell’esecuzione della funzione loop(), si ottiene un miglioramento, ma il programma non funziona ancora correttamente. Inoltre vi ho già “intimato” di non utilizzare mai l’istruzione delay() poichè essa provoca un blocco totale del microcontrollore (in questo caso per 100 msec) durante il quale esso non fa altro che attendere…

Occorre modificare sostanzialmente il programma, impostandolo in modo che il microcontrollore in ogni momento sappia com’è lo stato di un ingresso, com’era in precedenza e quanto tempo è trascorso dall’ultima variazione di quell’ingresso. La procedura a prima vista potrebbe sembrare un’inutile complicazione, in realtà il tutto si traduce in una maggior sicurezza ed affidabilità del funzionamento, inoltre viene risolto anche un altro problema, quello dei “rimbalzi” a cui ho accennato durante la lezione.

In questo documento potete trovare spiegato l’argomento in maniera più dettagliata. Mentre a questo link trovate il programma definitivo che risolve anche i problemi presentatisi fino ad ora.

All’interno del programma trovate anche un ulteriore quesito. Prossimamente troverete qui sotto la soluzione da me proposta.

Riepilogo dei contenuti della lezione:

  1. L’istruzione digitalRead() effettua delle “letture” dagli ingressi ovvero il mondo “esterno” entra nel microcontrollore.
  2. Abbiamo visto che l’istruzione if() permette al microcontrollore di prendere delle decisioni (o effettuare scelte), essa può essere legata (opzionalmente) anche all’istruzione else che permette di effettuare decisioni alternative.
  3. Abbiamo utilizzato il simbolo “! che in linguaggio C significa negazione ovvero il contrario di…
  4. Abbiamo utilizzato il simbolo “>” ossia maggiore di (ovviamente esiste anche il contrario “<“) che può essere utilizzato nei confronti per prendere delle decisioni. Esiste anche il simbolo comparativo di uguaglianza “==” ed il simbolo di disuguaglianza “!=” (diverso da…) come anche i simboli “>=” e “<=” (maggiore o uguale a… e minore o uguale a...)
  5. Abbiamo utilizzato il simbolo “&&” per legare due condizioni (entrambe da verificare cioè devono essere entrambe vere) nel costrutto if().

Alla prossima lezione…

Lezione 1

By lapinig,

Operazioni di OUTPUT

Partiamo dalle più semplici operazioni gestibili con un microcontrollore come quello utilizzato nella scheda Arduino.

Esercitazione 1: Lampeggio Verde/Rosso

Con la piattaforma TinkerCad realizziamo questo circuito

Il funzionamento richiesto deve essere il seguente (con temporizzazioni fisse di 0,5 sec ovvero 500 msec):

  1. Si deve accendere il solo Led Verde
  2. Quindi si accende anche il Led Rosso insieme al Verde
  3. Si spenge il Led Verde (ma rimane acceso il Rosso)
  4. Si spegne anche il Led Rosso
  5. Il ciclo si ripete all’infinito

Il codice completo lo trovate qui (utilizzatelo solo dopo aver provato da soli).

Esercitazione 2: Semaforo semplificato a due vie

Come seconda prova propongo questo circuito

Immaginiamo di dover realizzare la gestione di una sequenza semaforica costituita da due gruppi di luci (rosso/giallo/verde) presenti in un incrocio di due vie. Per semplificare le due direzioni NS (Nord-Sud) e EW (Est-Ovest) hanno le stesse luci a coppie ossia il Rosso Nord si accenderà insieme al Rosso Sud, il Verde Nord insieme al Verde Sud, ecc.

Chiaramente quando nella direzione NS è acceso il colore Verde oppure Giallo, nella direzione ortogonale EW dovrà obbligatoriamente essere acceso il colore Rosso. Per questa ragione prendiamo in considerazione solo le sequenze di accensione dei colori Verde e Giallo, il Rosso opposto sarà acceso di conseguenza.

Le temporizzazioni richieste, inizialmente, sono di 5 secondi per il Verde e di 2 secondi per il Giallo. In seguito verrà chiesto di differenziare la tempistica per una delle due direzioni.

Il funzionamento richiesto è il seguente:

  1. Si accende il Verde nella direzione NS per 5 secondi (e quindi il Rosso EW)
  2. Si accende il Giallo nella direzione NS per 2 secondi (e quindi rimane acceso il Rosso EW)
  3. Si accende il Verde nella direzione EW per 5 secondi (e quindi anche il Rosso NS)
  4. Si accende il Giallo nella direzione EW per 2 secondi (e quindi rimane acceso il Rosso NS)
  5. Si ripete la sequenza dall’inizio

Nota: Le luci non indicate dovranno essere spente in ogni singolo punto, consiglio quindi di pilotare TUTTE le volte TUTTE le uscite, alcune saranno accese mentre altre spente.

Il codice completo lo trovate qui (utilizzatelo solo dopo aver provato da soli).

Esercitazione 3: Lampeggio “Real Time”

Come ultima prova di questa lezione propongo questo circuito

La funzione richiesta questa volta sembra molto semplice:

  1. Il Led Verde deve lampeggiare con un ritmo di 2 sec. ON / 2 sec. OFF
  2. Il Led Rosso deve lampeggiare con un ritmo di 0,5 sec. ON / 0,5 sec. OFF
  3. Il tutto ripetuto all’infinito

A prima vista, ripeto, potrebbe sembrare molto semplice da realizzare. In realtà è impossibile (o quasi) da ottenere con le tecniche viste finora, cioè con semplici sequenze lineari di istruzioni. Impossibile no, perchè prendendo il programma della prima esercitazione e modificandolo, con un numero di righe di istruzione circa 4-5 volte più grande si può ottenere il risultato richiesto. Ma se vi dicessi che va aggiunto un terzo Led, lampeggiante anch’esso e magari con un numero di volte che sta in rapporto di numero primo con gli altri ?

Il codice completo lo trovate qui (utilizzatelo solo dopo aver provato da soli).

I più attenti fra voi avranno notato un terzo Led di colore Blù che non è stato citato nel testo e non è utilizzato. A cosa serve? A complicare ancora di più le richieste:

  1. Ad ogni 5 lampeggi del Led Rosso il Led Blu si deve accendere per 1 secondo e quindi spengersi.

Il codice completo lo trovate qui (utilizzatelo solo dopo aver provato da soli).

Riepilogo dei contenuti della lezione:

  1. Le righe che iniziano con il simbolo // sono commenti e sono ignorate dal compilatore in linguaggio C. Usatele per chiarire i punti critici.
  2. Nel software della piattaforma Arduino la funzione setup() viene eseguita per prima ed una sola volta. Usatela per impostare le condizioni iniziali della macchina.
  3. Nel software della piattaforma Arduino la funzione loop() viene richiamata in continuo (in loop appunto) dopo la funzione setup() e non ha mai termine (solo con lo spengimento della macchina).
  4. La funzione pinMode() serve per impostare la modalità di funzionamento del piedino del microcontrollore della scheda di Arduino: INPUT o OUTPUT. Abbiamo visto per adesso solo la seconda possibilità.
  5. La funzione digitalWrite() serve per impostare un valore digitale su di un piedino di Arduino. Scrivendo HIGH o 1 sul pin saranno presenti 5 volt ed eventuali componenti connessi verranno “accesi”, mentre scrivendo LOW o 0 sul pin saranno presenti 0 volt ed eventuali componenti connessi verrano “spenti”. Il piedino deve essere definito come OUTPUT in precedenza.
  6. La dichiarazione #define non è una funzione del linguaggio C (manca infatti della coppia di parentesi tonde), ma bensì una direttiva o comando del preprocessore del linguaggio C. In pratica si può utilizzare per definire delle costanti utilizzate nel nostro programma. In realtà è molto più potente.
  7. La funzione if() esegue un controllo, in genere fra variabili utilizzate nel programma, per determinare se eseguire un pezzo di codice oppure (else) un altro pezzo di codice. La parte che segue subito la funzione if(), contenuta nella prima coppia di parentesi graffe, viene eseguita se il risultato del controllo è vero (true), altrimenti (else) viene eseguita la parte contenuta nella seconda coppia di parentesi graffe. Notare che, mentre la prima parte è obbligatoria la parte con else e seconda coppia di parentesi può anche mancare.

Alla prossima lezione

Corso Microcontrollori (Arduino)

By lapinig,

Queste pagine saranno utilizzate per fornire i materiali necessari per poter seguire il modulo 11.2 Microcontrollori (Arduino) del Corso AUTOMA20 di ITS PRIME, tenuto dal sottoscritto.

A causa delle ormai note ragioni questo modulo si terrà, almeno in questa parte iniziale, con didattica a distanza e, pertanto, utilizzeremo supporti di virtualizzazione delle esercitazioni di laboratorio per poter comprendere meglio la programmazione dei microcontrollori.

Verrà utilizzata la piattaforma TinkerCad (TM) fornita gratuitamente da AutoDesk (TM) sul sito https://www.tinkercad.com.

Qui potete trovare i primi consigli per registrarvi e poter così accedere a questa piattaforma.

Per comprendere i circuiti che verranno di volta in volta realizzati (virtualmente per adesso) occorre sapere che cos’è una BreadBoard.

Corso ITS – AUTOMA20

Gualtiero Lapini

Led Bianchi per illuminazione

By lapinig,

Progetto per illuminazione interni


In questo progetto proviamo ad utilizzare i LED bianchi di alta potenza…

Visto le grandi correnti in gioco, a volte maggiori di 100 mA, non possiamo utilizzare il classico metodo di collegamento: sorgente di alimentazione, resistenza in serie di limitazione di corrente, diodo led, ritorno verso massa. In questo caso avremmo una enorme dissipazione di potenza sulla resistenza in serie, inoltre una piccola variazione della tensione di alimentazione potrebbe provocare una variazione di corrente nel circuito oltre i limiti del LED, causandone quindi la distruzione.DX1 W3 865 L30

I LED di alta potenza devono essere pilotati a corrente costante: cioè decidiamo quanta corrente far circolare in essi in base alla emissione luminosa desiderata.

Prendiamo un componente disponibile sul mercato vicino a noi per comodità. Io ho trovato questo LED in un negozio di elettronica vicino a me:  DX1-W3-865-L30 prodotto dalla OSRAM.

copertina_datasheet_dx1

Dal datasheet fornito dal produttore ricaviamo tutte le informazioni che ci necessitano per il progetto.

Intanto visualizziamo la copertina contenente un veloce riepilogo delle caratteristiche del prodotto. In questo caso nella serie DX1 sono presenti quattro varianti principali che si diversificano per la quantità di luce emessa e per il raggio di ampiezza di illuminazione (in realtà si dovrebbe più propriamente parlare di “cono” visto che siamo nel mondo reale in 3 dimensioni).

dati_caratteristici_dx1

Il modello da me acquistato (865-L30) è composto da un unico elemento LED della potenza di 1,2 W a cui corrisponde una corrente di funzionamento normale di 350 mA con un angolo di emissione di 30° (quindi molto direzionale), per una intensità luminosa di 210 cd (candele) che corrisponde ad una luce molto forte. La tensione tipica ai capi del LED non è indicata poiché questo componente va pilotato a corrente costante.

maximum_ratings_dx1

Nel datasheet fornito dal produttore sono indicati anche i valori massimi (Maximum Ratings) da NON superare per evitare il danneggiamento del componente stesso. In questo caso ci serve conoscere il range di temperatura ambiente entro cui far lavorare il componente e la corrente massima che può circolare. Nell’esempio riportato la corrente massima è di 500 mA.