Molto spesso, e i progettisti di sistemi lo sanno, è necessario pilotare in “modo astabile” e a diverse frequenze di commutazione, tante tipologie di carichi. Lampade, scaldabagni, motori, spie luminose e ventole, allarmi e quant’altro possono essere accesi e spenti in diverse momenti temporali, con frequenze promiscue. La problematica è risolvibile con qualsiasi linguaggio di programmazione, con alcune piccole difficoltà, specialmente per i programmatori alle prime armi. Nell’articolo vedremo come sia possibile semplificare al massimo la scrittura del codice, scrivendo un firmware che possa attivare ciclicamente diversi carichi, a differenti frequenze, in maniera estremamente facile e indolore.
Obiettivo
Lo scopo dell’articolo è quello di predisporre un automatismo per cadenzare, in modo costante, l’accensione e lo spegnimento di diversi carichi elettrici casalinghi. Nella fattispecie Il nostro scopo è quello di realizzare, nel modo più semplice possibile, la logica di un circuito che possa comandare le utenze domestiche secondo un ritmo ben definito, senza programmare il codice con un linguaggio di programmazione. L’articolo è, pertanto, dedicato soprattutto a chi si occupa di manutenzione e domotica senza conoscere a fondo gli elementi della programmazione. Il sistema utilizza, come esempio, il microcontrollore PIC 16F876 della Microchip ma la filosofia di funzionamento può, ovviamente, essere estesa a qualsiasi altra MCU.
Quale strategia si dovrebbe adottare con un linguaggio di programmazione tradizionale?
La programmazione di un sistema elettrico che commuti gli stati logici di diversi carichi indipendenti, con un normale e tradizionale linguaggio di programmazione, è spesso complicata. Occorrerebbe predisporre degli opportuni cicli di attesa che non congelino, tuttavia, il verificarsi degli eventi. Ricordiamo, infatti, che le funzioni di attesa, come pause(), delay(), wait(), e altri bloccano il programma per tutto il loro ciclo di lavoro. Con un microcontrollore, infatti, raramente si ci trova in un sistema multitasking. Se le temporizzazioni e i tempi di attesa risultano multipli di uno stesso numero, il problema è risolvibile più facilmente ma se gli stati e i tempi di attesa sono alquanto diversi tra loro e non hanno nessuna correlazione, allora la problematica è più complicata. Una soluzione semplice consiste nel creare un ciclo infinito all’interno del quale una minima pausa di attesa, pari a quella del massimo comune divisore dei tempi di tutti gli eventi, cadenzi il programma. Inoltre, con degli opportuni contatori e relativi controlli e condizioni si potranno modificare gli stati logici dei vari carichi collegati al sistema. Per un circuito composto da sei carichi, come quelli del presente articolo, la formula per conoscere la minima ampiezza temporale d’intervallo d’attesa è mostrata in figura 1.
Un esempio pratico chiarisce ogni dubbio. Per otto utenze che si attivino per un tempo, espresso in secondi, di:
T=[1200,3600,35000,12500,14000,600,3000,80]
il minimo tempo di attesa del ciclo di codice è di:
GCD(1200,3600,35000,12500,14000,600,3000,80) = 20 secondi.
Per fortuna nel linguaggio Ladder non c’è bisogno di eseguire tali calcoli.
Il sistema da realizzare
Il sistema da realizzare, molto generico, dovrebbe prevedere i classici carichi domestici utilizzati, di norma, in una normale abitazione. Essi si dovrebbero attivare e disattivare ciclicamente, secondo le più svariate esigenze. Il nostro sistema di esempio è, ovviamente, espandibile e modificabile per qualsiasi altra casistica. Esso prevede le seguenti utenze, come anche mostrato nello schema di principio di cui alla figura 2:
- luce all’ingresso;
- luce giardino;
- pompa di calore;
- purificatore;
- scaldabagno;
- spia lampeggiante che attesti il funzionamento del sistema.
Si supponga, inoltre, che l’utente decida di attribuire le seguenti temporizzazioni ai dispositivi appena elencati:
- luce all’ingresso: (3 minuti in ON e 3 minuti in OFF, e così via);
- luce giardino: (4 minuti in ON e 4 minuti in OFF, e così via);
- pompa di calore: (7 minuti in ON e 7 minuti in OFF, e così via);
- purificatore (10 minuti in ON e 10 minuti in OFF, e così via);
- scaldabagno (30 minuti in ON e 30 minuti in OFF, e così via);
- spia lampeggiante che attesti il funzionamento (500 mS in ON e 500 mS in OFF, e così via).
Per le apparecchiature che non necessitano di alimentazione elettrica nelle ore diurne e, comunque, con la luce solare, è possibile prevedere un sistema crepuscolare. Come si nota, tutte queste apparecchiature funzionano con un duty-cycle pari al 50%. Questo vuol dire che il loro funzionamento prevede un tempo di attivazione pari a quello di disattivazione. Il sistema progettato nell’articolo prevede solo questa funzionalità. Per diversi rapporti di duty-cycle è necessario utilizzare differenti soluzioni che, probabilmente, vedremo in uno dei prossimi articoli. Il tempo specificato nelle istruzioni è espresso in millisecondi (ms).
La procedura con il Ladder Logic
Per queste tipologie di applicazioni, semplici dal punto di vista logico e funzionale ma complicate da quello informatico e della programmazione, risulta ideale il Ladder Logic. Si tratta di un linguaggio grafico, molto utile per scrivere semplici programmi senza digitare una sola riga di codice operativo. Con la definizione di pochi passaggi grafici e il disegno di uno “pseudo” schema elettrico, è possibile implementare un completo sistema funzionante, in modo che i sei carichi previsti dal nostro progetto seguano un funzionamento ciclico e indipendente, senza che le attivazioni influiscano negativamente sulle varie utenze domestiche. Il tutto viene realizzato con molta semplicità. Per quanto riguarda i dettagli sul linguaggio di programmazione Ladder Logic rimandiamo il lettore alle documentazioni reperibili anche su Internet.
Il nostro progetto grafico è realizzato attraverso il programma LDmicro, un compilatore per linguaggio Ladder che prevede la realizzazione di progetti, l’esportazione e la compilazione dei programmi anche per i microcontrollori Atmel AVR, Microchip e Arm. Come possibile vedere in figura 3, il diagramma si compone di diversi “rungs”, nei quali sono inserite i “coil”, ossia gli utilizzatori relativi alle utenze domestiche. Si può osservare sulla destra, infatti, i carichi relativi alla spia luminosa, alla pompa di calore, alla luce del giardino, allo scaldabagno, al purificatore e alla luce dell’ingresso.
Sulla sinistra del diagramma è possibile, invece, osservare altrettanti sistemi di clock. Si tratta di generatori di onda quadra, completamente indipendenti tra loro, che provvedono a generare diversi segnali rettangolari capace di attivare o disattivare le relative porte del microcontrollore. Ogni generatore di clock può essere liberamente programmato temporalmente e il parametro inserito equivale al tempo nel quale il segnale resta a un livello logico alto o, in altre parole, il semi-periodo attivo. Si capisce bene che il duty-cycle di tali istruzioni è pari al 50%. Per ottenere diversi valori di duty-cycle, come detto in precedenza, esistono altre tipologie di istruzioni, che non sono contemplate nel presente articolo.
Il primo rung genera la cadenza per il lampeggio di un diodo Led, utilizzato quale spia di controllo per monitorare il funzionamento del sistema. Il suo periodo di attivazione è stato posto a 500 mS in stato di ON e 500 ms in stato di OFF. La sua frequenza è, dunque, di 1 Hz. Il secondo rung genera la cadenza per lo scaldabagno. Il suo periodo di attivazione è di 1800 secondi (pari a 30 minuti), così pure quello di disattivazione, per un totale di 60 minuti. Il terzo rung genera la cadenza per il purificatore. Il suo periodo di attivazione è di 600 secondi (pari a 10 minuti), così pure quello di disattivazione, per un totale di 20 minuti. Il quarto rung genera la cadenza per la pompa di calore. Il suo periodo di attivazione è di 420 secondi (pari a 7 minuti), così pure quello di disattivazione, per un totale di 14 minuti. Il quinto rung genera la cadenza per la luce del giardino. Il suo periodo di attivazione è di 240 secondi (pari a 4 minuti), così pure quello di disattivazione, per un totale di 8 minuti. Il sesto rung genera la cadenza per la luce dell’ingresso. Il suo periodo di attivazione è di 180 secondi (pari a 3 minuti), così pure quello di disattivazione, per un totale di 6 minuti. Si può utilizzare anche come simulatore di presenza. Ovviamente questo costituisce un esempio e può essere adattato secondo le più svariate esigenze. Si raccomanda di prestare la massima attenzione al nome delle variabili utilizzate. Inoltre si devono associare, con molta precisione, i contatti con le varie porte del PIC.
Consigli per lo schema elettrico
Parlando dello schema elettrico è necessario fare alcune considerazioni. Il microcontrollore PIC è semplicemente il cervello del sistema, che coordina le varie operazioni di temporizzazione e di attivazione delle porte logiche. Per questo motivo la corrente di funzionamento è estremamente bassa e, ovviamente, non è in grado di pilotare direttamente i carichi ad alta potenza. Per eseguire tale compito occorre prevedere un sistema di conversione della potenza affinché il debole segnale generato dal PIC possa comandare carichi molto più robusti. E’ opportuno, pertanto, utilizzare relè, transistor, Mosfet e Igbt che ben si prestano a tali funzioni. La figura 4 ne mostra uno schema generico.
Funzionamento
Il circuito in funzione pilota le sei porte del PIC in modo alternato, a frequenze diverse e, soprattutto, indipendenti tra loro. Il sistema, almeno per quanto riguarda la parte logica, è molto semplice è può essere provato in simulazione oppure realizzando un veloce prototipo con la MCU e qualche diodo Led. Può anche essere utilizzata una demoboard allo scopo. La simulazione, a livello operativo, deve prevedere esclusivamente la registrazione dei segnali logici alle uscite, mediante degli oscillogrammi nello stile di un analizzatore logico, come mostrato in figura 5.
File eseguibile HEX
:020000040000FA
:1000000083018A01000008280900000000000000A8
:100010008B12831681126400F030010503388100D1
:100020008312833081005F30A00021308400800182
:10003000840AA00B17281930B300831687309F005D
:100040008312003085000030860000308700831660
:10005000FF308500C0308600FF3087008113831297
:1000600003130B19A0170B1DA01383300B1D36288B
:1000700081070B116400A01F4028B3030319422815
:10008000B30B35281930B3002014201C6F28340816
:10009000A2003230A600351022082606A10026084C
:1000A000A202A11F592822082606A100A11B592837
:1000B0003514351C5E28A21B35106028A21B351490
:1000C000351863286528B40A6B28B401A0186A287B
:1000D000A0146B28A010A0186E2820107028B4015E
:1000E00083102018831483180614831C0610201410
:1000F000201CB8283608A2003708A3003808A4003E
:100100002030A600BF30A7000230A8003510240818
:100110002806A1002608A2022708031C270FA30215
:100120002808031C280FA402A11F9C2824082806C5
:10013000A100A11B9C283514351CA128A41B351037
:10014000A328A41B35143518A628AC28B60A031911
:10015000B70A0319B80AB428B601B701B8012019C3
:10016000B3282015B42820112019B7282010BB2847
:10017000B601B701B80183102018831483188614C0
:10018000831C86102014201C02293908A2003A087A
:10019000A3003B08A4006030A600EA30A700A80135
:1001A000351024082806A1002608A2022708031CEF
:1001B000270FA3022808031C280FA402A11FE6286A
:1001C00024082806A100A11BE6283514351CEB28BD
:1001D000A41B3510ED28A41B35143518F028F6287B
:1001E000B90A0319BA0A0319BB0AFE28B901BA01F0
:1001F000BB01A019FD28A015FE28A011A0190129F6
:1002000020100529B901BA01BB01831020188314FD
:1002100083180615831C06112014201C4C293C0849
:10022000A2003D08A3003E08A4001030A600A430A0
:10023000A700A801351024082806A1002608A2025C
:100240002708031C270FA3022808031C280FA40259
:10025000A11F302924082806A100A11B302935142C
:10026000351C3529A41B35103729A41B3514351826
:100270003A294029BC0A0319BD0A0319BE0A4829B4
:10028000BC01BD01BE01201A4729201648292012B1
:10029000201A4B2920104F29BC01BD01BE0183103B
:1002A0002018831483188615831C86112014201CA3
:1002B0008C293F08A2004008A300C030A6005D3092
:1002C000A700351023082706A1002608A202270848
:1002D000031C270FA302A11F732923082706A100CF
:1002E000A11B73293514351C7829A31B35107A29D5
:1002F000A31B351435187D298129BF0A0319C00AAB
:100300008829BF01C001A01A8729A0168829A01238
:10031000A01A8B2920108E29BF01C001831020183C
:10032000831483180616831C06122014201CCB2964
:100330004108A2004208A3005030A6004630A700A2
:10034000351023082706A1002608A2022708031C4F
:10035000270FA302A11FB22923082706A100A11B72
:10036000B2293514351CB729A31B3510B929A31B95
:1003700035143518BC29C029C10A0319C20AC72976
:10038000C101C201201BC6292017C7292013201B29
:10039000CA292010CD29C101C2018310201883145D
:0C03A00083188616831C86122F28D5298E
:02400E00723FFF
:00000001FF
Conclusioni
La proposta in articolo è una delle tante soluzioni possibili. Con il linguaggio Ladder, ovviamente, si possono creare progettazioni più complicate, in quanto si tratta di un vero e proprio linguaggio di programmazione, seppur dalla sintassi grafica e visuale. Il ciclo di lavoro programmato per le utenze è pari al 50%, almeno nell’esempio fornito. Per diverse tempistiche o differenti duty cycle si devono adottare altre strategie.