In un precedente post avevo mostrato come installare un motore elettrico per tapparelle dove il circuito elettrico era questo
Circuito tapparella a pulsantiCircuito tapparella a pulsanti

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 è questo
Grafico sequenze temporaliGrafico sequenze temporali
Dove 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.
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 è questo
Schema elettricoSchema elettrico
Dove 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)

Codice

Il codice per programmare Arduino è questo
Arduino
/*
   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.
Potrebbe interessarti anche: