Feb 102016
 

Oggi titolo criptico per un articolo decisamente diverso dal solito. Ovviamente tutti quanti voi che mi seguite non potete sapere che ho una casa dove non vivo abitualmente che ho cominciato a ristrutturare anni addietro, gli ho prima rifatto il tetto, e poi il piano di sopra che era al grezzo e che  è stato fatto da zero, dall’impianto elettrico, a quello idraulico, riscaldamento, serramenti, muri interni isolamento e quant’altro, tutto fatto da me in prima persona. Come potete immaginare ho progettato l’impianto elettrico per essere “domotico”. Quando ho cominciato questo lavoro, ormai oltre 10 anni fa, non sapevo assolutamente nulla di elettronica, la domotica era agli albori e non si trovavano prodotti commerciali se non a prezzi stratosferici e non adatti alla mia idea di impianto. A quei tempi comprai alcune schede della QFP  engineering, una con ingressi ed uscite digitali, una con ingressi digitali ed uscite a relè ed una con ingressi analogici. Schede comunque molto costose (ma estremamente affidabili!) e che non facevano del tutto al caso mio in quanto non erano “autonome”, ma necessitavano di un controllo esterno via rs232 o rs485 per operate. Ho sfruttato le mie abilità di programmatore per cui ho creato un ambiente software che girava sotto Windows e che controllava il mio impianto elettrico. Ciò comportava la necessità di avere un PC sempre acceso per il quale avevo usato un vecchio portatile in disuso. Bene perché vi dico tutto questo? Perché mi hanno svaligiato la casa, i ladri dopo aver sfondato la porta-finestra sul terrazzo hanno fatto razzia dei miei attrezzi per cui oltre al pesante danno economico non posso nemmeno proseguire con i lavori. Fra le cose che mi hanno rubato c’è anche il portatile che controllava l’impianto elettrico, certo dal punto di vista economico non valeva assolutamente nulla ma ora mi trovo in una situazione di quasi emergenza visto che non posso nemmeno accendere le luci. Ho deciso perciò in tutta fretta di prendere il materiale che ho in casa e creare al volo un prototipo per sostituire le schede che non sono più in grado di controllare e da qui partiamo per l’articolo di oggi.

Caratteristiche del sistema

Attualmente il sistema di fatto non faceva altro che accendere e spegnere le luci. Al piano di sotto c’è un Arduino collegato alla rete di sensori DS18B20 e alla caldaia, infatti ogni stanza del piano da me ristrutturato ha un suo sensore di temperatura, inoltre ve ne sono altri attaccati ai tubi del riscaldamento a pavimento e uno all’esterno. Dovendoci mettere mano tanto vale riunire tutto su una singola scheda e cablare alcune cose già previste ma mai completate come ad esempio i due sensori infrarossi che sono già installati in due stanze ma mai collegati. Dando uno sguardo alla vecchia scheda, che potete vedere nella foto sotto

IMG_1234 IMAG0563

si nota l’utilizzo di circa 6 ingressi digitali e 7 uscite a relè, dobbiamo quindi prevedere un minimo di ingressi e uscite coerenti con la scheda già esistente più prevedere alcune funzionalità aggiuntive che, come detto, potrebbero essere gli ingressi dei due sensori infrarossi e della rete di sensori DS18B20. A tutto ciò vorrei aggiungere il modulo ethernet per inviare tutti i dati raccolti in rete e permettere di attuare un rudimentale controllo remoto.

Senza nemmeno fare un conteggio preciso ci rendiamo conto che non possediamo sufficienti ingressi ed uscite per controllare tutto ciò che ci serve per cui non possiamo far altro che affidarci a catene di shift registers. L’altra cosa da decidere è: uso un Arduino già pronto e ci faccio una sorta di shield con tutto ciò che mi serve, oppure parto da zero? In quest’ultimo caso mi toccherà risparmiare sull’interfaccia USB e sulla sezione di alimentazione, anche se a dirla tutto un regolatore di tensione c’è l’avrei pronto. Ero combattuto nella scelta ma ho pensato di tenere le schede Arduino che ho per i prototipi da fare a casa mentre per questo progetto più o meno definitivo è forse meglio creare tutto da zero anche se per programmare la scheda dovrò prevedere un connettore FTDI.

Arduino stand-alone

atmega328_con_cristallo_e_resetLa parte principale è ovviamente l’Atmega328P con il suo quarzo e i due condensatori. Se ricordate, ai pin 9 e 10 (XTAL 1 e 2) dobbiamo connettere il quarzo da 16MHz e su ognuno dei due pin un condensatore ceramico da 22pF. Ricordo anche che come per ogni integrato è buona regola usare un condensatore da 100nF sulla linea di alimentazione dell’integrato stesso e fisicamente il più vicino possibile a quest’ultimo. Ricordiamo che il suo scopo è quello di limitare principalmente le fluttuazioni sulla linea di alimentazioni causate dai vari picchi di assorbimento dell’integrato in base ai diversi stati operativi in cui si trova in un instante piuttosto che un altro. Attenzione che con questo genere di connessioni si da per scontato che la linea di alimentazione sia già stabilizzata 5V. Nel mio caso utilizzerò un alimentatore per PC già presente, per cui non mi interesserò ulteriormente delle linea di alimentazione.  A questo punto andiamo ad aggiungere  il pulsante di reset che ci permette di riavviare Arduino all’occorrenza.  Il pin di reset deve essere collegato a vcc con interposto un resistore da 10KΩ, cosa che lo mantiene allo “stato alto” durante tutto il normale funzionamento. Il pulsante di reset andrà a cortocircuitare il pin stesso a massa, cosa che porta lo stato a “basso” e determina il reset dell’Atmega. Dopo aver inserito anche questi due componenti dovremmo aver raggiunto un risultato come quello qui di seguito e che di fatto è già un sistema funzionante anche se non è ancora programmabile e non è in grado di svolgere nulla di particolare visto che non è connesso in nessun modo con l’ambiente esterno. Per rendermi le cose più semplici nel caso qualcosa vada storto, ho aggiunto anche un led rosso sulla linea di alimentazione in modo da poter capire in qualunque istante se la scheda è correttamente alimentata. Possiamo usare il classico led rosso con un resistore da 330Ω o in alterativa usate McMajan Assistant per Android per calcolare il resistore da applicare in base al led che avete. Il prossimo passo è rappresentato dal connettore FTDI che è indispensabile per collegarci il relativo adattatore e programmare l’ATMega senza aver bisogno di hardware aggiuntivo per la porta USB. Se ricordate l’interfaccia FTDI utilizza 5 pin il cui ordine non è standard e può essere diverso a seconda degli adattatori in vostro possesso. atmega328_con_cristallo_reset_ftdiI pin sono VCC, GND, RX, TX e reset. Vcc si collegherà alla linea 5V, GND all’omonima linea, RX del convertitore FTDI alla linea TX dell’Atmega e viceversa la TX del convertitore alla RX dell’Atmega. Resta il reset che si collega al reset dell’Atmega attraverso un condensatore ceramico da 100nF. Aggiungiamo anche un resistore da 1KΩ sulla linea RX dell’Atmega, cosa che permette di programmare il chip via FTDI senza dover escludere eventuali altri adattatori seriali che utilizzano la medesima linea, mi viene in mente ad esempio l’esp8266 di cui parleremo in un prossimo articolo oppure una rs485. Nella prossima figura potete vedere lo schema aggiornato anche con il connettore FTDI. Spero che questo approccio a piccoli passi possa farvi capire che tutto sommato non è nulla di particolarmente complesso, è sufficiente concentrarsi su un pezzo alla volta senza farsi prendere dal panico da tutta questa apparente complessità.

Gli ingressi (74HC165)

Ora che il nostro Arduino fatto in casa è pronto, dobbiamo pensare ad interfacciare l’Atmega con il mondo esterno per svolgere le funzioni di cui abbiamo bisogno. Se ricordate ci interessavano ingressi digitali, uscite digitali, e interfaccia 1-wire per collegare la rete di sensori DS18B20. Per quanto riguarda gli ingressi digitali abbiamo detto che Arduino non ne possiede a sufficienza per il nostro scopo per cui abbiamo deciso di usare una catena di shift registers. Ricorderete che a parte VCC e GND per l’alimentazione, abbiamo bisogno di altri tre pin, uno per il clock (CLK), un pin QH per il trasferimento dei bit verso Arduino ed il pin SH/LD (Shift Load) che “legge” gli ingressi in un determinato momento e prepara i dati per il trasferimento verso Arduino. I collegamenti sono stati fatti seguendo la seguente tabella:

Arduino 74HC165
CLK 11 2
Data 10 9
SH/LD 9 1

atmega328_con_cristallo_reset_ftdi_165Ricordo inoltre che per collegare in cascata questi shif register, il pin 10 del primo 74HC165 si collega al 9 del successivo e così via. Anche se tendo a scordarmi di ribadirlo ogni volta, come per tutti i circuiti integrati anche in questo caso è buona norma applicare il condensatore di disaccoppiamento da 100nF il più vicino possibile, sulla linea di alimentazione. Nella porzione di schema che vi propongo qui sotto ho aggiunto due connettori a vite per mostrare come devono essere collegate le uscite. Non ho collegato le altre altrimenti lo schema diventa troppo confuso, ma si procede allo stesso modo con tutti gli altri pin, ad esclusione del 7 e 10 che non sono degli ingressi, quindi pin 11,12,13,14,3,4,5,6 che ho messo in ordine di ingresso, ossia l’11 è l’ingresso numero uno ed il 6 sarà il numero 8.

Le uscite (74HC595 e ULN2803A)

Per quanto riguarda le uscite useremo i 74HC595. Anche questi hanno bisogno di soli tre pin, il clock (SH_CP, SHift ClockPin), il pin per il transito dei dati seriali da Arduino alle uscite (DS – Data Serial) ed un pin che copia lo stato delle celle di memoria precedentemente riempite sulle effettive uscite (latch pin – ST_CP – STorage ClockPin). Se non ricordate questo concetto potere ripassare il 74HC595 che avevo scritto su questi chip. Come abbiamo spiegato in un precedente articolo, inoltre, possiamo utilizzare un singolo pin di clock sia per i 74HC595 che i 74HC165 andando a risparmiare un pin digitale che altrimenti sarebbe sprecato per nulla. I collegamenti saranno perciò fatti seguendo la seguente tabella:

Arduino 74HC595
SH_CP 11 11
Data (DS) 13 14
ST_CP 12 12

Ricordo brevemente che ci sono altri due pin da collegare, il MR (Master reset) da connettere alla linea 5V e l’OE (Output Enable) da connetere a GND. atmega328_con_cristallo_reset_ftdi_165_595Per ultimo ricordo che, come nel nostro caso, se abbiamo più di un 74HC595 in catena, l’uscita Q7′ dell’integrato a monte si collegherà al DS di quello a valle mentre i pin SH_CP e ST_CP saranno uniti in comune.
I collegamenti dovrebbero essere come quelli nella figura qui accanto. Vi ricordo che se fate un click sull’immagine vi si aprirà in dimensioni reali per osservare meglio tutti i dettagli dello schema. Ora siamo arrivati ad un punto in cui abbiamo moltiplicato sia gli ingressi digitali che le uscite. Inoltre gli ingressi sono stati dotati di resistore di pullup in modo da poterci collegare direttamente i pulsanti esterni. Per quanto riguarda però le uscite è come se avessimo incrementato quelle originali di Arduino, ma sappiamo bene che non possiamo collegarci un relè in modo diretto. Con l’ULN2803A non è necessario necessario per ogni uscita aggiungere resistore, transistor e diodo, due di essi infatti sostituiranno egregiamente i nostri 16 resistori, 16 transistor e 16 diodi peraltro dandoci libertà di scelta sul voltaggio dei relè che può variare da 5 a 50V con un assorbimento massimo per ogni linea di 500mA. Il collegamento di questo integrato è quasi banale, abbiamo gli ingressi da una parte e le uscite dall’altra, inoltre restano solo due pin che come logico aspettarsi vanno uno a GND e uno all’alimentazione. Attenzione che l’alimentazione deve essere quella necessaria per i relè che nel mio caso è di 12v, quindi non confondiamo l’alimentazione di questo integrato con quella di Arduino. Nel caso avessimo avuto dei relè a 5V avremmo potuto invece usare la stessa linea di alimentazione di Arduino. Per quanto riguarda il collegamento dell’ULN2803A vi ripropongo un vecchio schema qui sotto:

out darliDa quanto detto ne deriva che saranno necessarie due linee di alimentazione con voltaggi diversi. Nel mio caso non è un problema perché il tutto è alimentato da un alimentatore per PC che fornisce linee a 12V,5V e 3.3V per cui non mi occorre modificare null’altro.

E’ tempo di stagnare

Avendo una certa fretta ho preparato il prototipo su una basetta millefori pensando di risparmiare tempo, poi a conti fatti tra lavoro figli e stagnatore mi sono rapidamente ricreduto. Peraltro il lavoro è cominciato con un problema tecnico con i connettori a vite in quanto i pin non entravano nei fori che ho quindi dovuto allargare. Negli schemi che ho disegnato qui sopra ho collegato gli shift registers nei pin dal 9 al 13 per semplicità di disegno, nel prototipo però li ho cambiati perché i pin dal 10 al 13 preferisco lasciarli liberi per avere a disposizione l’interfaccia SPI che potrei utilizzare per collegarci una scheda ethernet, un nrf24, un rtc o quant’altro mi venga in mente, anche a posteriori. Nello sketch che vi propongo ho utilizzato comunque gli stessi pin degli schemi qui sopra così vi sarà più facile modificare il tutto a vostro piacimento. Prima di vedere rapidamente la parte software vi volevo però far vedere com’è venuta la scheda dopo tanto lavoro

Contenuti cloud-10745390-1454775386000

Come avrete capito dalle immagini qui sopra ho deciso di abbandonare la millefori,, ho deciso di utilizzare Fritzing per disegnarmi il pcb e mandarlo in stampa. Lo so non è un programma professionale, ma attualmente non ho ancora dimestichezza con programmi di caratura superiore, è mia intenzione imparare ad usare KiCad, ma per ora non sono in grado di fare di meglio, non in tempi brevi almeno. Tra le altre stampandone solo una con Fritzing Lab mi sarebbe costata quasi 50 euro per cui ho optato per OSH Park che per 52$ me ne ha inviate 3, anche se l’attesa è stata di un buon mesetto.

E’ tempo di programmare

Per quanto riguarda la parte software ci limitiamo a qualcosa di molto semplice, lasciamo l’Atmega in ascolto continuo sullo stato dei pulsanti e appena identifica una variazione la riporta sulle rispettive uscite. Faccio notare che per ora non ho neanche pensato alla rete 1-wire, questo perché ho una perplessità da risolvere. Ricorderete che la misura delle temperatura porta via diverso tempo e in quel tempo la lettura dei pulsanti non sarebbe possibile cosa che determinerebbe un malfunzionamento del sistema. Devo perciò pensare ad una buona strategia software per eliminare ogni problema, per cui per ora ci limitiamo ad un software molto rudimentale che gestisce unicamente gli ingressi e le uscita. Per non crearvi confusione, nel listato qui sotto ho utilizzato i pin del progetto che vi ho esposto sopra anche se poi nel progetto finale li ho modificati per tenere libera l’interfaccia SPI.

Di fatto ho ripreso quanto abbiamo già visto in precedenti articoli, ma c’è una piccola grossa modifica da fare. In precedenza riportavamo su display o tramite led lo stato di pulsanti in ingresso. Ora invece vogliamo che alla pressione di un pulsante avvenga l’inversione dello stato del corrispettivo relè perciò premendo il pulsante se il relè era spento verrà eccitato e viceversa. Istintivamente potremmo pensare che dobbiamo andare a valutare tutti i singoli bit degli ingressi ed in base a ciò che otteniamo decidere se invertire o meno i singoli bit dell’uscita. Strada percorribile, neanche troppo complessa, ma non è la via migliore. Esiste invece un’operazione booleana che fa esattamente quel che ci serve e che si chiama XOR (OR esclusivo). Vediamo rapidamente la tabella qui sotto:

bit1 1 bit 2 AND OR XOR
0 0 0 0 0
0 1 0 1 1
1 0 0 1 1
1 1 1 1 0

Vediamo come verrebbe applicato l’XOR nelle diverse situazioni. Associamo il bit 1 allo stato del pulsante ed il bit 2 a quello del relè. Nella prima riga vediamo che se il pulsante NON è premuto (bit 1=0) ed il relè corrispondente è spento (bit2=0), l’applicazione dell’XOR setterebbe il relè a 0, ossia lo lascerebbe spento. Quindi se non tocco il pulsante ed il relè era spento, resterà spento, pare ovvio ma è necessario testare tutte le possibili combinazioni. Se passiamo alla seconda condizione vediamo che non toccando il pulsante, se il relè è acceso resterà acceso, anche questa apparentemente ovvia ma ci garantisce che l’operazione di XOR non interferirà mai quando un determinato ingresso non è premuto.

Ora analizziamo allo stesso modo le ultime due condizioni, ossia quelle in cui un determinato pulsante è stato premuto (bit1=1). In questo caso se il relè era spento (bit2=0) l’operazione di XOR lo accenderà (XOR=1), viceversa se era già acceso (bit2=1) lo spegnerà (XOR=0), ossia abbiamo ottenuto l’effetto desiderato, cioè ad ogni pressione di un pulsante otteniamo l’inversione dello stato della relativa uscita.

In definitiva per utilizzare questa tecnica abbiamo bisogno di tre dati, ossia lo stato dei relè e quindi in definitiva delle uscite, quello dei pulsanti, ossia degli ingressi, e quello dei pulsanti PRIMA della pressione o rilascio di un pulsante. Se abbiamo a disposizione questi dati, cosa che ottenevamo già con il vecchio listato, siamo in grado di gestire tutto con un semplice XOR. Qui di seguito potete vedere il listato opportunamente modificato per funzionare con i pulsanti.

#include <Ss_hc595.h>

hc595 My595(7,6,8,2); // latch,clock,data,number of 74hc595
#define NUM_CHIP 2
#define IN_PL 4
#define IN_Data 5
#define MIX_Clock 6
int attuale[NUM_CHIP]; // array per tenere le letture attuali
int lettura[NUM_CHIP]; // array per tenere l’ultima lettura fatta.
int uscite[NUM_CHIP];
 
void setup()
{
  pinMode(IN_PL,OUTPUT);
  pinMode(IN_Data,INPUT);
  pinMode(MIX_Clock,OUTPUT);
  for(int i=0;i<NUM_CHIP;i++) {attuale[i]=0;lettura[i]=0,uscite[i]=0;} // inizializzo gli array a 0
  Serial.begin(9600);
}
 
void loop()
{
  delay(50);
  digitalWrite(MIX_Clock, HIGH);
  digitalWrite(IN_PL, LOW);
  //delayMicroseconds(5);
  digitalWrite(IN_PL, HIGH);
  for(int i=0;i<NUM_CHIP;i++) lettura[i]=shiftIn(IN_Data, MIX_Clock, MSBFIRST ); // faccio tutte le letture
 
  for(int i=0;i<NUM_CHIP;i++) // controllo se ci sono modificazioni
  {
   
   if(attuale[i]!=lettura[i])
   {
    attuale[i]=lettura[i];
    uscite[i]=uscite[i]^attuale[i];
    My595.Send595Pin(uscite[i],1-i);
    Serial.print(“IC “);
    Serial.print(i);
    Serial.print(” – “);
    Serial.println (lettura[i]);
   }
  } // chiusura for
}

Con questo il progetto è completato anche se sono possibili numerosi spunti per ulteriori sviluppi, sia software che hardware, ad esempio non è presente nessun meccanismo di debounc degli ingressi. Inoltre se notate la foto qui sotto,  sono presenti alcuni connettori a cui non ho fatto cenno per non appesantire troppo l’articolo ma che permettono a questa scheda di fare molto più di quel che vi ho raccontato sinora. Ora non mi resta che togliere la vecchia scheda e sostituirla con la mia, ma farò questo lavoro nei prossimi giorni con un po’ di calma.IMAG0680

Prima di chiudere con l’articolo vorrei però condividere con voi cosa è “andato storto”, non tutto è andato infatti come previsto, diffidate dei blog in cui tutto è perfetto e tutto funziona al primo colpo.

Il primo problema che si è verificato è stato con i connettori a vite, colpa mia che avrei dovuto capire che se non entravano nella millefori non sarebbero entrati nemmeno nello stampato con i “fori standard”, per cui mi sono limitato a limare i pin dei connettori per farceli entrare. Il secondo problema che si è verificato è stato alla prima alimentazione, infatti il led non si è acceso cosa che ha fatto scattare tutta una serie di test prudenziali che mi hanno fatto perdere un sacco di tempo. Fatti tutti i test del caso e, sorpresa, era bruciato il led, è bastato sostituirlo perché si accendesse. Il terzo problema è stato nell’impossibilità ad inviare il software attraverso l’intefaccia FTDI, infatti ottenevo un timeout e la programmazione non andava a buon fine. Ho perciò programmato l’Atmega su una scheda Arduino esterna, ho messo il classico esempio “blink” che determina il lampeggio del led interno, solo che la mia scheda non ha un led interno per cui ho provveduto a mettere un resistore e led “volanti” sul rispettivo pin. Una volta verificato che tutto funzionava ho indagato sull’ftdi ed ho scoperto che semplicemente avevo invertito i cavi di collegamento RX – TX, o meglio non li ho invertiti, io ho correttamente collegato l’RX della mia scheda con il TX dell’FTDI ma ho dovuto invertirli perchè il tutto funzionasse, suppongo ci sia un errore nella serigrafia del mio convertitore FTDI, ma non ha una gran importanza, la cosa utile è sapere che se il trasferimento non funziona può essere necessario invertire RX e TX. Il quarto problema, è un accidentale errore nel disegno, probabilmente un colpo di mouse scivolato ed i pin 6 e 7 del secondo HC165 sono stati involontariamente collegati insieme. Il 7 peraltro non dovrebbe essere collegato a nulla ma il problema mi dava delle erronee letture che avrei potuto ignorare via software perdendo la possibilità di usare l’ultimo ingresso ma non sono riuscito ad accontentarmi per cui ho dissaldato l’integrato per “piegare” il pin non necessario e risolvere il problema. Purtroppo però non ho l’attrezzatura adeguata e, oltre al tempo perso, ho distrutto l’HC165. Oltre a questo ho rovinato tre piste ramate che ho sostituito con dei cavetti saldati direttamente sui pin del nuovo integrato. Tutto a posto? Si finalmente gli ingressi funzionavano a meraviglia per cui mi mancava un nuovo controllo sulle uscite. Ho dato corrente e sento “stok!”, spengo subito tutto ma ormai è tardi, ho inavvertitamente invertito la polarità della 12V. Si umiliatemi pure, anche perchè sulla serigrafia della scheda è scritto tutto, è impossibile sbagliare. Sta di fatto che un ULN si è bruciato per cui ….. ho preso un secondo pcb ed ho rifatto tutto, la foto qui sopra infatti è la seconda scheda, la prima l’ho abbandonata dopo aver recuperato più componenti possibile. Questo cosa mi insegna? Beh, potevo mettercelo un diodo di protezione, un componente da pochi centesimi mi avrebbe salvato la scheda e tanto lavoro per cui se deciderò di aggiornare il progetto il diodo comparirà di sicuro. Se posso aggiungere una cosa ulteriore, non ho previsto nulla per fissare la scheda, non ci sono fori, ma sinceramente il pcb è bello denso e non ci sarebbe stato posto per prevedere dei fori di fissaggio.

Spero di non avervi annoiati con quest’ultima parte dell’articolo, ma credo che dagli sbagli si può imparare molto, e non vedo perchè debba nascondere i miei