Comando tapparelle temporizzato con Arduino
In un precedente post avevo mostrato come installare un motore elettrico per tapparelle dove il circuito elettrico era questo
Il vantaggio di questo circuito è la semplicità di realizzazione, lo svantaggio è che bisogna tenere premuti i pulsanti fino a che la tapparella non è completamente aperta o chiusa.
Il comando permetterà di mantenere attivi il relè di uscita (sali o scendi), che comanda la tapparella, per un tempo prefissato sufficiente alla completa apertura o chiusura.
In pratica un temporizzatore ritardato alla diseccitazione, con in più la possibilità, tramite un ulteriore pressione di uno dei due pulsanti, di fermare immediatamente la tapparella quando si vuole senza attendere il tempo preimpostato.
Il grafico temporale è questoDove vediamo rappresentati i casi tipici:
Il motore è collegato ai contatti dei relè comandati da Arduino.
Il vantaggio di questo circuito è la semplicità di realizzazione, lo svantaggio è che bisogna tenere premuti i pulsanti fino a che la tapparella non è completamente aperta o chiusa.
Miglioramento
Tramite Arduino e possibile utilizzare i pulsanti solo per dare il comando iniziale di apertura o chiusura.Il comando permetterà di mantenere attivi il relè di uscita (sali o scendi), che comanda la tapparella, per un tempo prefissato sufficiente alla completa apertura o chiusura.
In pratica un temporizzatore ritardato alla diseccitazione, con in più la possibilità, tramite un ulteriore pressione di uno dei due pulsanti, di fermare immediatamente la tapparella quando si vuole senza attendere il tempo preimpostato.
Il grafico temporale è questoDove vediamo rappresentati i casi tipici:
- Premendo il pulsante il relè corrispondente si eccita e rimane in questo stato fino allo scadere del tempo impostato
- Premendo il pulsante il relè corrispondente si eccita, premendo ancora lo stesso pulsante, prima dello scadere del tempo, il relè si diseccita, stop immediato
- Premendo il pulsante il relè corrispondente si eccita, premendo l'latro' pulsante, prima dello scadere del tempo, il relè si diseccita, stop immediato
- Identico al caso 1 ma sulla discesa, dopo lo stop va rilasciato e ri-premuto il pulsante per eccitare il relè
Il ritardo del relè va determinato misurando il tempo in cui la tapparella (o tenda), impiega a passare dallo stato completamente abbassato a quello completamente alzato e viceversa.
Si prende il tempo maggiore tra i due incrementandolo di qualche secondo, questo perché in base alle condizioni meteo caldo/freddo potrebbero variare leggermente i tempi.
Si prende il tempo maggiore tra i due incrementandolo di qualche secondo, questo perché in base alle condizioni meteo caldo/freddo potrebbero variare leggermente i tempi.
Va precisato che il motore ha internamente ha dei finecorsa che bloccano il motore quando la tapparella è completamente abbassata o alzata... previo regolazione.
Schema elettrico
Il circuito che va realizzato è questoDove i pulsanti, anzichè essere collegati direttamente al motore, sono collegati agli ingressi di Arduino in bassa tensione a 5V dc.Il motore è collegato ai contatti dei relè comandati da Arduino.
Fai attenzione alla parte compresa nel tratteggio rosso, si tratta della parte collegata alla tensione di rete a 230 V ac e va tenuta separata dalla parte in bassa tensione a 5V dc.
ATTENZIONE: La corrente è molto pericolosa e non si vede, quindi se non sai bene cosa stai facendo, EVITA di mettere mano all'impianto elettrico.
Comunque quando lavori su un impianto elettrico stacca sempre la corrente dall'interruttore generale sul contatore Enel.
In ogni caso non mi assumo nessuna responsabilità per eventuali inesattezze riportate, ogni modifica all'impianto la fai a tuo rischio e pericolo.
Se i comandi sono invertiti (sali / scendi) scambia i fili sui pulsanti (viola con verde) oppure sul comando dei relè (rosso con marrone) oppure in uscita dal relè (nero con marrone)Comunque quando lavori su un impianto elettrico stacca sempre la corrente dall'interruttore generale sul contatore Enel.
In ogni caso non mi assumo nessuna responsabilità per eventuali inesattezze riportate, ogni modifica all'impianto la fai a tuo rischio e pericolo.
Codice
Il codice per programmare Arduino è questoArduino
/*
Comando Tapparelle
Version 1.0 2021
Copyright 2021 Sgart.it
https://www.sgart.it/
Board: 'Arduino UNO'
Port: COM7
*/
#include <arduino-timer.h>
const String VERSION_STR = "Comando Tapparelle Manuale v. 1.2021-07-10 - Sgart.it";
/*
* Definizione IO
*/
const byte RELE_UP = 2; // relè salita - Arduino GPIO pin to use. (D2).
const byte RELE_DOWN = 3; // relè discesa - Arduino GPIO pin to use. (D3).
const byte BUTTON_UP = 5; // pulsante salita - Arduino GPIO pin to use. (D5).
const byte BUTTON_DOWN = 6; // pulsante discesa - Arduino GPIO pin to use. (D6).
/*
* variabili
*/
// memoria stato pulsanti, true = premuto
boolean buttonUp = false;
boolean buttonDown = false;
boolean buttonUpPrev = false;
boolean buttonDownPrev = false;
// memoria autoritenuta relè
boolean timerReleUp = false;
boolean timerReleDown = false;
boolean timerButtonDisabled = false;
// coando relè
boolean releUp = false;
boolean releDown = false;
/*
* Timer
*/
const int TIMER_RELE_ON_MILLISEC = 30000; // 30 sec, timer tapparella
const int TIMER_BUNTTON_DISABLED_MILLISEC = 200; // 0,2 sec const int TIMER_BUNTTON_DISABLED_MILLISEC = 250; // 0.25 sec, antirimbalzo pulsanti
Timer<2, millis> timer; // inizializzo i 2 timer
auto timerOut = timer.in(1, [](void*) -> bool { return false; });
auto timerButton = timer.in(1, [](void*) -> bool { return false; });
bool handleTimerOut(void *argument) {
Serial.println("Timer timerOut fine");
// timer.cancel(timerOut);
timerReleUp = false;
timerReleDown = false;
setRele();
return false;
}
bool handleTimerButton(void *argument) {
Serial.println("Timer timerButton fine");
// timer.cancel(timerButton);
timerButtonDisabled = false;
return false;
}
/*
* Setup
*/
void setup() {
Serial.begin(115200);
Serial.println("\nSet pin ...");
// conigurazione output
pinMode(RELE_UP, OUTPUT);
digitalWrite(RELE_UP, HIGH);
pinMode(RELE_DOWN, OUTPUT);
digitalWrite(RELE_DOWN, HIGH);
// configurazione input con resistenza di pullup
pinMode(BUTTON_UP, INPUT_PULLUP);
pinMode(BUTTON_DOWN, INPUT_PULLUP);
Serial.println(VERSION_STR);
}
/*
* Loop
*/
void loop() {
// gestione timer
timer.tick();
// lettura diretta ingressi/pulsanti
bool pinUp = digitalRead(BUTTON_UP) == LOW;
bool pinDown = digitalRead(BUTTON_DOWN) == LOW;
// impulso / fronte di salita pulsanti
bool pulseUp = pinUp == true && buttonUpPrev == false;
bool pulseDown = pinDown == true && buttonDownPrev == false;
// logica pulsanti
buttonUp = timerButtonDisabled == false && pulseUp;
buttonDown = timerButtonDisabled == false && pulseDown;
if(pulseUp || pulseDown) {
Serial.print("Pulse up: ");
Serial.print(pulseUp);
Serial.print(", down: ");
Serial.println(pulseDown);
if( timerButtonDisabled == false) {
Serial.println("Start timerButtonDisabled");
timerButtonDisabled = true;
timer.cancel(timerOut);
timer.cancel(timerButton);
timerButton = timer.in(TIMER_BUNTTON_DISABLED_MILLISEC, handleTimerButton);
}
auto active_tasks = timer.size();
Serial.print("Task nr: ");
Serial.println(active_tasks);
}
// se premo entrambi i pulsanti (PIN), oppure ho entrambe le ritenute, spengo tutto (sicurezza)
if((pinUp && pinDown) || (timerReleUp && timerReleDown)) {
Serial.println("Entrambi i pulsanti, reset");
resetAll();
}
// se premo uno dei i pulsanti durante l'autoritenuta, spengo tutto (sicurezza)
if((buttonUp || buttonDown) && (timerReleUp || timerReleDown)) {
Serial.println("Autoritenuta e pulsanti, reset");
resetAll();
}
// se ho il pulsante premuto attivo l'autoritenuta (timer alla diseccitazione)
if(buttonUp || buttonDown) {
if(timerReleUp == true || timerReleDown == true) {
Serial.println("Timer già attivo");
} else {
timerOut = timer.in(TIMER_RELE_ON_MILLISEC, handleTimerOut);
timerReleUp = buttonUp == true;
timerReleDown = buttonUp == false;
}
}
// attivazione relè
releUp = (buttonUp || timerReleUp) && releDown == false;
releDown = (buttonDown || timerReleDown) && releUp == false;
setRele();
// memorizzo stato precedente pulsanti
buttonUpPrev = pinUp;
buttonDownPrev = pinDown;
}
void resetAll(){
Serial.println("Reset");
// spengo il timer
timer.cancel(timerOut);
timerReleUp = false;
timerReleDown = false;
buttonUp = false;
buttonDown = false;
releUp = false;
releDown = false;
setRele();
}
void setRele(){
digitalWrite(RELE_UP,releUp ? LOW : HIGH);
digitalWrite(RELE_DOWN, releDown ? LOW : HIGH);
}
Note
Lo stesso circuto va bene anche per comandare le tende esterne motorizzate, il principio è identico in quanto usano lo stesso tipo di motore usato nelle tapparelle motorizzate.Attenzione, per le tende esterne, come sicurezza in caso di forte vento con tenda aperta, sarebbe meglio avere anche un 'anemometro, con relativa centralina, che chiuda in automatico la tenda.