domenica 19 giugno 2022

La classe Relay (High/Low Level Trigger)

Moduli relay optoisolati

Il mercato offre moduli relay (o relè) di vario tipo, i più diffusi sono optoisolati con logica di comando negata.

La logica di comando negata vuole dire che quando il pin di comando è LOW, il relay risulta eccitato e ovviamente quando il comando è HIGH il relay risulta a riposo.

Normalmente siamo abituati a pensare all’inverso, cioè HIGH per eccitare il relay. Questa logica negata ci spiazza ed è un problema in più da gestire ed è bene risolverlo alla radice.

I moduli relay più diffusi ed economici sono a logica negata, nella loro descrizione commerciale dovreste trovare almeno la specifica seguente: Low Level Trigger.

Altri moduli si stanno diffondendo, ciò che li contraddistingue è la possibilità di configurarli tramite jumer per lavorare con High o Low trigger.

Se il nostro modulo relay è configurabile, possiamo selezionare High Level Trigger in modo che basti un semplice digitalWrite(13, HIGH) , per eccitare la sua bobina. Mentre con Low Level Trigger, siamo costretti ad una digitalWrite(13, HIGH) nel setup per averlo non eccitato e ovviamente scriveremo digitalWrite(13, LOW) per eccitarlo.

Ciò può portare a confusione specie se abbiamo diversi relay alcuni Low Level ed altri High Level. La piccola classe Relay mira a risolvere il problema alla radice.

Il costruttore della classe prende due argomenti, l’ultimo è opzionale ma ci permette di configurare il Level Trigger.

    // costruttore di Relay
    Relay(const byte pin, const bool lt = LOW) : m_relayPin(pin)
                                      , m_levelTrigger(lt) 

L’argomento lt di default è Low Level Trigger poiché sono i moduli più diffusi. La chiamata al costruttore avviene in ambito globale, si crea istanza in uno di questi modi:

    Relay relayOnD6(6, HIGH);  // logica non invertita
    Relay relayOnD6(6, LOW);   // logica invertita
    Relay relayOnD6(6);        // logica invertita

Dopo la creazione della istanza, per ognuna è necessario chiamare il metodo begin() all’interno della funzione setup(). Importante non dimenticare di chiamare questo metodo una sola volta per istanza.

    relayOnD6.begin();

Eccitare il relay o diseccitarlo è semplice, il metodo set() prende un bool come argomento. Di seguito vediamo tre modi equivalenti per eccitarlo:

    relayOnD6.set(HIGH);  // HIGH equivale a true.
    relayOnD6.set(ON);    // ON equivale ad HIGH
    relayOnD6.set(1);     // 1 equivale a ON

Per mettere a riposo il relay (non eccitato), scriviamo:

    relayOnD6.set(LOW);     // oppure
    relayOnD6.set(OFF);     // oppure
    relayOnD6.set(0);

Per leggere lo stato del relay, usiamo il metodo state():

    if (relayOnD6.state() == ON) {
        // ...
    }

L’applicazione dimostrativa (demo)

La demo è molto semplice, ci sono due relay, uno High Level Trigger e l’altro Low Level Trigger. Le istanze sono dichiarate così:

    Relay relayOnD6(6, HIGH);   // High Level Trigger on D6 pin
    Relay relayOnD5(5, LOW);    // Low Level Trigger on D5 pin

Il codice è talmente semplice che non serve commentarlo. Potete provarlo al simulatore seguendo questo link.

 

giovedì 16 giugno 2022

Termostato con arduino

Un termostato elettromeccanico si comporta da interruttore controllato dalla temperatura. Poiché fondamentalmente è un interruttore, i suoi contatti possono essere aperti o chiusi, quindi ci sono solo due stati l'uno opposto all'altro, similmente a LOW e HIGH. Questo tipo di termostato rientra tra i controlli di stato ON/OFF o semplicemente termostato ON/OFF. 

Figura 1: Termostato elettromeccanico bimetallo
Esistono anche dei termostati meccanici o meglio valvole termostatiche che regolano la portata della valvola in relazione alla temperatura rilevata dalla sonda. Questo tipo di termostati sono detti a regolazione continua o proporzionali. Un termostato di questo tipo può essere realizzato con circuiti analogici, noi con arduino siamo però nel dominio digitale discreto e allora ricorriamo all'algoritmo P.I.D. (Proporzionale Integrativo Derivativo).

Una precisazione su "digitale discreto",  per me vuole dire che, anche se il mio sketch venisse eseguito in un ciclo rapidissimo, diciamo ogni 100ns, nell'intervallo tra 100n e 200ns l'algoritmo non ha controllo su ciò che accade. 

Termostato bimetallo

Con riferimento alla Figura 1 vediamo di quali parti e composto il termostato:

  • REGOLAZIONE SETPOINT - Questo perno ci permette di regolare la temperatura di intervento. La rotazione deforma in modo controllato la lamina bimetallo.

  • CONTATTI - I contatti elettrici ci permettono di controllare l'elemento resistivo che produce calore quando percorso dalla corrente. Se i contatti sono chiusi circola corrente, la temperatura sale fino al momento in cui la lamina bimetallo muta forma aprendo il circuito.

  • LAMINA BIMETALLO - Essa svolge due compiti fondamentali, muta forma sia in relazione al calore che in relazione al perno di regolazione. Inoltre viene percorsa da corrente elettrica quando i contatti risultano chiusi.

Gli isolatori in ceramica sono un ottimo isolante elettrico e sono buoni conduttori di energia termica. Il perno di fissaggio permette di fissare meccanicamente il dispositivo e favorisce una diffusione del calore per contatto fino a raggiungere l'elemento sensibile (la lamina).
 

Controllo ON/OFF

Il nostro controllore digitale composto da hardware e software dovrà comportarsi allo stesso modo di un termostato elettromeccanico. Oltre al software ci serviranno delle componenti elettroniche o elettromeccaniche da collegare ad arduino, vediamole:

  • Sensore di temperatura - Può essere digitale o analogico. Quando il sensore è digitale spesso lo si collega a due pin nominati SDA e SCL facenti capo alla periferica interna TWI compatibile I2C. Quando il sensore è analogico lo si collega ad uno dei pin nominati A0, A1 ecc. Questi pin fanno capo alla periferica interna ADC (Analog to Digital Converter). In sostanza una periferica capace di convertire un valore analogico (differenza di potenziale elettrico) in un valore digitale nel range 0 to 1023.

  • Contatti elettrici - I relay sono ottimi attuatori elettromeccanici, essi sono composti da un elettromagnete, da un ancora di acciaio dolce e da lamine di metallo porta contatti. L'elettromagnete quando è percorso da corrente elettrica attira magneticamente l'ancora che spinge la lamina in modo che i contatti si chiudano permettendo il passaggio di corrente elettrica.

  • Regolazione setpoint - Possiamo realizzarla in tanti modi, se la nostra applicazione prevede un display e dei pulsanti li possiamo sfruttare per incrementare e decrementare il setpoint con risoluzione di 0.1°C. Se non c'è display potremmo usare un potenziometro per la regolazione e una decina di led per visualizzare il setpoint.

Un termostato elettromeccanico ha volutamente due soglie di intervento e questo evita il pendolamento frequente tra i due stati ON e OFF. Le due soglie differiscono di un delta T, comunemente conosciuto come isteresi. Molti fenomeni fisici sono afflitti da isteresi, per approfondimenti segui il link.

Noi possiamo attribuire un valore a piacere alla isteresi, questo potrebbe pure essere un parametro configurabile dall'utente oppure essere fisso tra 2÷5°C. 

Calcoliamo la soglia di accensione con la seguente formula:

SOGLIA_ON = SETPOINT - ISTERESI

Figura 2: Curva di isteresi

Nella Figura 2 si può apprezzare il setpoint, la curva di isteresi e le transizioni di stato ON/OFF e OFF/ON. Il setpoint = 65°C, isteresi  = 5°C. Quando i contatti sono aperti lo stato è OFF, la temperatura tende a scendere, quando è al di sotto della  temperatura di 65 - 5 = 60, avviene la transizione OFF/ON e i contatti risultano chiusi. Grazie ai contatti chiusi nell'elemento riscaldante circola corrente per cui la temperatura tende ad aumentare, superata la soglia di 65°C avviane la transizione ON/OFF. Avremmo pertanto una regolazione della temperatura che oscilla tra 60 e 65 °C. Ciò si ripeterà all'infinito. 

Qualora volessimo una minore oscillazione della temperatura potremmo regolare l'isteresi a 2°C o meno, tuttavia con valori di isteresi molto bassi avremo frequenti cambi di stato intollerabili. Se si volesse maggiore precisione si dovrà abbandonare il controllo ON/OFF per passare ad un controllo proporzionale, ma anche in questo caso avremo una oscillazione attorno al setpoint di circa 0.2°C.

Quanto descritto vale nel caso in cui i contatti del termostato sono impiegati per fare scorrere corrente nell'elemento riscaldante (resistenza). Ma ad esempio al posto dell'elemento riscaldante, potremmo alimentare un compressore frigorifero e allora il termostato appena descritto non è più adatto. Dobbiamo allora fare una distinzione tra, termostato modo caldo e modo freddo, il comportamento è simile ma la curva risulta invertita. La figura 3 riassume al solito, setpoint, soglia ON e isteresi. Calcoliamo come segue le transizioni di stato:

Figura 3: Curva termostato modo freddo.

ON/OFF
temp <= setpoint
 
OFF/ON
temp >= setpoint + isteresi

Dove temp è la temperatura rilevata dalla sonda.

Ad esempio, se i contatti del relay alimentano un compressore frigorifero, quando questo è in rotazione (stato ON) la serpentina, detta evaporatore, si raffredda, la temperatura tende a scendere fino al valore del setpoint, allora i contatti si aprono (stato OFF) e il compressore non ruota più. L'evaporatore ha accumulato energia termina e c'è ancora gas in circolo e ciò genera un sotto raffreddamento, cioè la temperatura letta dalla sonda risulta inferiore al setpoint di 1 grado ad esempio. La non perfetta coibentazione e le aperture della porta sono perdite che fanno aumentare la temperatura, quando la sonda legge una temperatura uguale o superiore a setpoint + isteresi, cioè a 15°C, avviene la transizione OFF/ON e il compressore inizia ad estrarre calore e la temperatura tende a diminuire. Il ciclo si ripete all'infinito.

Un altro modo di calcolare la soglia ON prevede di dividere il valore dell'isteresi per due, ad esempio 5 / 2 = 2.5°C. Quindi il setpoint si trova al centro delle due isteresi, così avremo le seguenti transizioni:

ON/OFF
temp <= setpoint - 2.5°C | con i parametri di Figura 3, avremo 10°C - 2.5°C=7.5°C.
 
OFF/ON
temp >= setpoint + 2.5°C | 10 + 2.5 = 12.5.

Comandare il relay

Un pin di arduino non può essere usato direttamente per eccitare la bobina dell'elettromagnete. Tra il pin di arduino è la bobina ci deve essere un circuito con funzione di adattamento, solitamente è composto da un bjt NPN, qualche resistore e un diodo. Non scendiamo nel dettaglio poiché in commercio si trovano moduli relay che contengono anche il circuito di comando. Essi offrono isolamento galvanico e sono più o meno configurabili. Nella descrizione della maggior parte dei moduli, compare la scritta "Low Level Trigger", ciò vuole dire che quando il pin di arduino è LOW il relay è eccitato. Si tratta di una logica negata che ci disorienta inizialmente, in questo caso potremmo cercare un modulo in cui compare la scritta "High/Low Level Trigger" che lascia intendere la possibilità di configurarlo tramite dei jumper.

La logica negata o meno dovrà essere prevista e gestita correttamente nel software, diversamente il comportamento risulta invertito e il termostato non funzionerà.

Il software

Sappiamo abbastanza per abbozzare qualche riga di codice,  inizialmente scriveremo una funzione che lavora correttamente quando la logica è NON negata, cioè il relay è eccitato (contatti chiusi) quando il pin è HIGH. La funzione gestirà solo il modo Hot, quindi avremo una resistenza per scaldare qualcosa. 

Se la nostra applicazione richiede un solo termostato la funzione che svilupperemo sarà sufficiente, mentre per più termostati (Hot/Cold) vedremo come sviluppare due classi HThermostat e CThermostat, configurabili per lavorare con logica negata o meno.

Vi lascio in anteprima la funzione abbozzata e rimando la spiegazione al prossimo post.

bool checkThermostat(bool state) {
switch (state) {
case LOW:
if (g_temperature <= g_setpoint - g_isteresi) {
state = HIGH;
}
break;
case HIGH:
if (g_temperature > g_setpoint) {
state = LOW;
}
break;
} // end switch (state)
return state;
} // end checkThermostat()

Termostato con arduino (2° puntata)  

Licenza Creative Commons
Quest'opera è distribuita con Licenza Creative Commons Attribuzione - Condividi allo stesso modo 4.0 Internazionale

venerdì 3 giugno 2022

Uso di millis() - esempio 1

Il breve sketch seguente è una semplice applicazione della funzione millis(), la quale viene usata per temporizzare lo stato del pin 13, a cui volendo potremmo collegare un led o un relay

Descrizione

All'avvio il pin 13 è in HIGH. Resta HIGH per 1 minuti. Trascorso 1 minuti pin 13 passa allo stato opposto LOW e permane per 5 minuti, trascorsi i quali il tutto si ripete.

Considerazioni

Lo sketch è "NoN Bloccante" e quindi può essere integrato in applicazioni che richiedono reattività, ad esempio per intercettare un evento come la pressione di un pulsante ecc.  Ho impiegato 4 variabili globali, come al solito il prefisso è g_nomevariabile. Per comodità ho usato la macro MIN_TO_MILLIS(m) che effettua l'operazione m x 60000 nel momento della compilazione. Il valore della variabile g_interval viene modificato in funzione dello stato della variabile g_relayState .



#define PIN_RELAY 13

#define MIN_TO_MILLIS(m) (m * 60000UL)

bool g_relayState = HIGH;
bool g_relayOldState = LOW;

uint32_t g_saveMillis;
uint32_t g_interval;

void setup()
{
Serial.begin(115200);
pinMode(PIN_RELAY, OUTPUT);
g_saveMillis = millis();
g_interval = MIN_TO_MILLIS(1);
Serial.println(MIN_TO_MILLIS(1));
Serial.println(MIN_TO_MILLIS(2));
} // end void setup()


void loop() {

if ( millis() - g_saveMillis > g_interval ) {
g_relayState = !g_relayState;
g_saveMillis = millis();
}

if (g_relayState != g_relayOldState) {
digitalWrite(PIN_RELAY, g_relayState);
g_relayOldState = g_relayState;
if (g_relayState) {
g_interval = MIN_TO_MILLIS(1);
} else {
g_interval = MIN_TO_MILLIS(5);

}
}
} // end void loop()

Licenza Creative Commons
Quest'opera è distribuita con Licenza Creative Commons Attribuzione - Condividi allo stesso modo 4.0 Internazionale.