problema automazione tapparella relè

Buongiorno a tutti
Sto realizzando per l’esame di maturità un progetto di automazione di una tapparella che ho realizzato sottoforma di campione di piccole dimensioni(lavoro come serramentista).
Praticamente ho realizzato due modalità tramite un interruttore a leva a tre stati: MODALITA’ AUTOMATICO con una fotoresistenza un interruttore crepuscolare fa si che di NOTTE la tapparella scenda e si accenda una luce esterna(simula una luce del giardino) di GIORNO la tapparella SALE e la luce si spegne. Nella modalità MANUALE invece è possibile comandare l’accensione della luce e la salita e la discesa della tapparella tramite degli interruttori nella posizione centrale invece è tutto spento.
Chiaramente un relè pilota la SALITA e la DISCESA della tapparella(220) un altro pilota la luce esterna(12v).
Il mio problema è il seguente: avendo il motore della tapparella i finecorsa implementati quando la salita o la discesa vengono azionati la tapparella si ferma al raggiungimento del finecorsa ma il relè mi rimane eccitato.
Pensavo di mettere dei delay ma il problema è che ogni volta che si ripete il ciclo nello stato AUTOMATICO il relè verrà comunque eccitato.
Dovrei quindi creare un if che faccia in modo di non azionare il motore se al controllo della fotoresistenza ci si trovi nella stessa condizione(giorno o notte)
posto di sotto il mio sketch così da farvi capire:

BOZZA_DEFINITIVO_SKETCH.ino (3.94 KB)

Ti invitiamo a presentarti qui: http://forum.arduino.cc/index.php?topic=113640.0 e a leggere il regolamento: http://forum.arduino.cc/index.php?topic=149082.0 - qui una serie di schede by xxxPighi per i collegamenti elettronici vari: http://forum.arduino.cc/index.php?topic=146152.0 - qui le pinout delle varie schede by xxxPighi: http://forum.arduino.cc/index.php?topic=151646.0 - qui una serie di link utili: http://forum.arduino.cc/index.php?topic=126861.0

grazie per le indicazione però purtroppo non c’entrano con la mia richiesta

ciao. devi fare quello che hai già fatto nel controllo manuale: memorizzare lo stato attuale e fare le varie azioni solo nel caso di un cambio di stato.

ciao pippo72

david15: grazie per le indicazione però purtroppo non c'entrano con la mia richiesta

invece centrano, dai una letta ai link e capisci perchè.

Comunque a me risulta che i relè che comandano salita e discesa siano sempre 2.

Posso capire se vivessimo su un pianeta invaso dai vampiri dopo il tramonto e allora è giusto che le serrande si chiudano da sole appena fa buio, ma vedo il progetto poco realistico in un futuro di automazione di una casa :) , tu vorresti mai essere blindato in casa da delle serrande che si chiudono al tramonto in automatico? a cosa serve accendere la luce del giardino se poi non posso andarci? XD

ciao

ma infatti ho specificato che è un progettino della maturità nulla di più che quello! comunque la domanda era un altra

La domanda era un altra si ho capito, ma tu non hai risposto ... quanti relè hai, capisci che leggendo lo sketch non so cosa vai a comandare fisicamente senza schema...

Chiaramente un relè pilota la SALITA e la DISCESA della tapparella(220) un altro pilota la luce esterna(12v).

sembra da come dici hai un relè solo usato come deviatore.

ma allora mi chiedo cosa comandi con queste 2 istruzioni?

digitalWrite(DISCESA,LOW);
        digitalWrite(SALITA,HIGH);

Pensavo di mettere dei delay ma il problema è che ogni volta che si ripete il ciclo nello stato AUTOMATICO il relè verrà comunque eccitato.

metti un flag giorno e un flag notte... una variabile che va a TRUE quando il processo di chiusura è stato eseguito, ogni ciclo loop vedrà che ha già chiuso e non ci andrà più fino a quando non sarà giorno, che farai un reset del flag con un FALSE stessa cosa per l'opposto.

pippo72:

devi fare quello che hai già fatto nel controllo manuale: memorizzare lo stato attuale e fare le varie azioni solo nel caso di un cambio di stato.

ciao

ciao, saresti così gentile da mandarmi il listato delle azioni che devo fare??

quelle le hai già scritte tu :slight_smile:

{  //INTERRUTTORE IN CONFIGURAZIONE AUTOMATICO
  valaut = digitalRead(AUTOMATICO);
  if(valaut == LOW)
  {  int val = analogRead(fotoresistenza); // salvo il valore fotoresistenza dentro alla variabile val
     
     Serial.println(val, DEC); // Scrivo il valore della fotoresistenza, espresso in numeri decimali
     if(val<300) //NOTTE
     {  lcd.setCursor(1, 0);
        lcd.print("AUTOMATICO ON   ");
        lcd.setCursor(1, 1);    
        lcd.print("MOD. NOTTE      ");
 ...

Io ti ho detto di aggiungere una variabile dello stato precedente e di valutare anche quella.
E come quello che hai scritto qui:

if ((valoreluce == HIGH) && (vecchio_val == LOW)){  
    stato = 1 - stato;  
    delay(50);                // attesa di 50 millisecondi

all’interno della configurazione manuale.

E lo stesso consigli di pablos:

metti un flag giorno e un flag notte… una variabile che va a TRUE quando il processo di chiusura è stato eseguito, ogni ciclo loop vedrà che ha già chiuso e non ci andrà più fino a quando non sarà giorno, che farai un reset del flag con un FALSE stessa cosa per l’opposto.

Ok grazie cmq per fare un po' di chiarezza sono un modulo relè con due relè che pilota uno la salita e uno la discesa e un ulteriore relè collegato ad un alimentatore che pilota la luce a 12 v. volevo chiedervi invece per quanto riguarda il problema del fatto che il relè rimanga eccitato ( al cambio di stato notte/giorno la tapparella scende il finecorsa la blocca ma il relè resta eccitato..) posso creare una specie di timer con un ciclo di while inserendo come condizione la funzione millis o mi consigliate qualcos altro?

david15:

posso creare una specie di timer con un ciclo di while inserendo come condizione la funzione millis o mi consigliate qualcos altro?

Dato che arduino non sa quando la tapparella ha finito di aprirsi (o di chiudersi) devi lasciare acceso il relè per il tempo che ti serve e poi spegnerlo; puoi usare delay, che però “blocca” arduino per tutto il tempo di attesa, oppure millis (soluzione migliore).
la logica potrebbe essere questa:

if(val<300) //NOTTE
     {  lcd.setCursor(1, 0);
        lcd.print("AUTOMATICO ON   ");
        lcd.setCursor(1, 1);    
        lcd.print("MOD. NOTTE      ");
        
        digitalWrite(SALITA,LOW); 
        
        digitalWrite(LUCE,HIGH); // accendi luce
        digitalWrite(DISCESA,HIGH); //accendi rele discesa
        delay(5000);   //<=== tempo necessario per chiudere la tapparella (anche un po' di più)
        digitalWrite(DISCESA,LOW);  //<=== spegni rele discesa
             }

Ricordati che devi fare queste cose solo se hai un passaggio da giorno a notte (e viceversa).

ciao
pippo72

potresti scrivermelo con la funzione millis? non so come utilizzarla

@ david15: non ho firmato nessun contratto di assistenza quindi per piacere non usare così facilmente la (o il) Personal Message. :0

Tornando al discorso millis ecc. vediamo cosa si può fare e cosa no.
Strutturalmente puoi togliere dall’ if il controllo per lo spegnimento del relè.

if(val<300) //NOTTE
     {  lcd.setCursor(1, 0);
        lcd.print("AUTOMATICO ON   ");
        lcd.setCursor(1, 1);    
        lcd.print("MOD. NOTTE      ");
        
        digitalWrite(SALITA,LOW); 
        
        digitalWrite(LUCE,HIGH); // accendi luce
        digitalWrite(DISCESA,HIGH); //accendi rele discesa
        //delay(5000);   //<=== riga tolta
        //digitalWrite(DISCESA,LOW);  //<=== riga tolta
             }

e gestire lo spegnimento del rele con un flag (termine usato spesso in questo tread :P)
prima del void setup() agguingi

boolean spegni_discesa = false;
long previousMillis = 0;
long interval = 5000;

poi quando accendi il rele discesa metti spegni_discesa a true:

if(val<300) //NOTTE
     {  lcd.setCursor(1, 0);
        lcd.print("AUTOMATICO ON   ");
        lcd.setCursor(1, 1);    
        lcd.print("MOD. NOTTE      ");
        
        digitalWrite(SALITA,LOW); 
        
        digitalWrite(LUCE,HIGH); // accendi luce
        digitalWrite(DISCESA,HIGH); //accendi rele discesa
        spegni_discesa = true; // <== riga aggiunta
        previousMillis = millis();  // <== riga aggiunta
             }

Bene, fino ad adesso cosa abbiamo ottenuto?? direi NULLA.
dobbiamo finalmente aggiungere il controllo che conta il passare del tempo da quando attivi il rele.
Tu dove lo metteresti???
All’interno dell’if che controlla che sei in automatico e prima di valutare se giorno o notte aggiungi:

valaut = digitalRead(AUTOMATICO);
    if(valaut == LOW)  {  
    unsigned long currentMillis = millis();    
        if ((spegni_discesa == true) && (currentMillis - previousMillis > interval)) {
           digitalWrite(DISCESA,HIGH);
           spegni_discesa = false;
        }

       int val = analogRead(fotoresistenza);

ovvero se spegni_discesa è vero (il rele discesa è acceso) e sono passati 5000 millisecondi spengo il relè e riporto spegni_discesa a false.

tutto il codice che ho postato NON lo ho provato quindi non ci metto la mano sul fuoco.
Le righe riguardanti la gestione di millis sono copiate dall’esempio BlinkWithoutDelay.

La stessa cosa la devi fare per il controllo del relè in apertura… quindo buon lavoro ]:smiley: ]:smiley: ]:smiley:

p.s. di solito dopo un if la graffa aperta è sulla stessa linea

ciao
pippo72