automazione tapparelle

salve a tutti, ho modificato l'impianto elettrico di casa mia (sono elettricista) e voglio automatizzare le serrande. ho già cablato il tutto utilizzando dei relè a bassa tensione per comandare i motori, bassa tensione perché avevo già previsto di interfacciare qualche automazione

vorrei usare arduino nano, e non conoscendo la programmazione di arduino ho cercato in rete qualche spunto. Ho trovato diverse cose e spunti, ma nessuno funziona come vorrei. Ho cercato di modificare qualche programma ma senza risultati.

quello che vorrei realizzare è questo: 1 pulsante per la salita, 1 per la discesa, il tutto in autoritenuta
se premo uno dei 2 pulsanti arresto il motore

1 pulsante di salita generale che premuto arresta ogni movimento e la faccia salire con autoritenuta
1 pulsante di discesa generale che premuto arresta ogni movimento e la faccia scendere con autoritenuta

un tempo di lavoro in modo tale di diseccitare i relé

so che è chiedere troppo, potrei farlo con un PLC, conosco la programmazione in ladder ed ho realizzato diverse automazioni, ma dovendo nascondere il tutto dentro il cassettone della tapparella rimane comodo utilizzare arduino e un paio di relé dentro un contenitore

Grazie a tutti quelli che mi vorranno aiutare

nicolini2000:
potrei farlo con un PLC, conosco la programmazione in ladder ed ho realizzato diverse automazioni

Allora basta scrivere le stesse espressioni logiche in C.

Esempio di relé start/stop con autoritenuta. 'A' è il relé, 'sta' e 'sto' sono i livelli letti dai pulsanti start e stop (si assume che quando premuti forniscano un 1). Al posto dei puntini vanno i pin da usare.

byte A = 0;  // rele' inizialmente spento

void loop() {
    // lettura ingressi
    byte sta = digitalRead(...);
    byte sto = digitalRead(...);
    
    // rele' A
    A = (A | sta) & !sto;
    
    // aggiornamento uscite    
    digitalWrite(..., A);
}

Esempio come prima ma con disattivazione dopo 10 secondi. 't0' minuscolo è la variabile tempo, 'T0' maiuscolo è l'uscita del temporizzatore (va a 1 dopo 10 secondi che 'A' è a 1).

byte A = 0;   // rele' inizialmente spento
byte T0 = 0;  // temporizzatore inizialmente spento
uint32_t t0 = 0;

void loop() {
    // lettura ingressi
    byte sta = digitalRead(...);
    byte sto = digitalRead(...);
    
    // rele' A
    A = (A | sta) & !T0 & !sto;

    // temporizzatore T0
    if(!A) { t0 = millis(); T0 = 0; }
    else if(millis() - t0 >= 10000) T0 = 1;

    // aggiornamento uscite    
    digitalWrite(..., A);
}

Anche se si lavora in bassissima tensione, gli ingressi vanno filtrati contro i rimbalzi e optoisolati.

bello, pulito, semplice, salvato

+1

Claudio_FF:
Allora basta scrivere le stesse espressioni logiche in C.

Esempio di relé start/stop con autoritenuta. 'A' è il relé, 'sta' e 'sto' sono i livelli letti dai pulsanti start e stop (si assume che quando premuti forniscano un 1). Al posto dei puntini vanno i pin da usare.

byte A = 0;  // rele' inizialmente spento

void loop() {
    // lettura ingressi
    byte sta = digitalRead(...);
    byte sto = digitalRead(...);
   
    // rele' A
    A = (A | sta) & !sto;
   
    // aggiornamento uscite   
    digitalWrite(..., A);
}




Esempio come prima ma con disattivazione dopo 10 secondi. 't0' minuscolo è la variabile tempo, 'T0' maiuscolo è l'uscita del temporizzatore (va a 1 dopo 10 secondi che 'A' è a 1).


byte A = 0;  // rele' inizialmente spento
byte T0 = 0;  // temporizzatore inizialmente spento
uint32_t t0 = 0;

void loop() {
    // lettura ingressi
    byte sta = digitalRead(...);
    byte sto = digitalRead(...);
   
    // rele' A
    A = (A | sta) & !T0 & !sto;

// temporizzatore T0
    if(!A) { t0 = millis(); T0 = 0; }
    else if(millis() - t0 >= 10000) T0 = 1;

// aggiornamento uscite   
    digitalWrite(..., A);
}




Anche se si lavora in bassissima tensione, gli ingressi vanno filtrati contro i rimbalzi e optoisolati.

Fantastico!! Sono quasi più i commenti che il programma.

quello che vorrei realizzare è questo: 1 pulsante per la salita, 1 per la discesa, il tutto in autoritenuta
se premo uno dei 2 pulsanti arresto il motore
1 pulsante di salita generale che premuto arresta ogni movimento e la faccia salire con autoritenuta
1 pulsante di discesa generale che premuto arresta ogni movimento e la faccia scendere con autoritenuta
un tempo di lavoro in modo tale di diseccitare i relé

Cioè se non sbaglio questo (con doppio interblocco e protezione da pulsanti sempre premuti):

Un comando alternativo potrebbe essere il seguente. La realizzazione è più semplice e permette di fermare tutto anche dal generale (il comando generale sarebbe un semplice OR cablato sugli stessi ingressi dei comandi locali).

  • 1 pulsante per la salita, 1 per la discesa, il tutto in autoritenuta
  • Se premo il pulsante opposto al movimento attuale arresto il motore
  • 1 pulsante di salita generale che premuto arresta eventuali discese in corso e avvia le salite delle tapparelle ferme, se premuto una seconda volta iniziano a salire anche quelle che si sono fermate.
  • 1 pulsante di discesa generale che premuto arresta eventuali salite in corso e avvia le discese delle tapparelle ferme, se premuto una seconda volta iniziano a scendere anche quelle che si sono fermate.
  • Un tempo di lavoro in modo tale di diseccitare i relé

Ciao intervengo un po per gelosia,perchè anchio di lavoro (manutentore elettromeccanico di dubbie qualità), lhanno scorso ho comiciato ho cominciato i miei primi passi con Arduino.

Ed a me sai cosa mi hanno risposto?......STUDIA.

Poi in realtà hanno avuto una grandissima pazienza( e con me devo ammtere che ce n'è voluta davvero tanta) e mi hanno insegnato tutto quel poco che ora sò(perche programmare anche in hobbistica è un mondo vero e proprio).

Come consiglio ti dò inazitutto quello di scordarti del PLC ,le schedine Arduino parlano un altra lingua.

Secondo ricordati che che sta lavorando in bassissima tensione con Arduino, ed in bassa con le tapparelle quindi giustamente ti servono dei relè(ma consumano anche loro,soprattutto se eccitati).

Terzo attento ai pulsanti,in programmazione sono abbastanza difficili all'inizio.

Quarto se vuoi un consiglio tienti un paio di pin su Arduino liberi per un modulo Bluetooth.

Quinto e più importante prima cerca di impazzire un pò a banco con Arduino facendo cose semplici tipo accendere e spegnere un Led anche se il pulsante rimane premuto oppure se....ECT ECT.

Sto provando proprio in questi giorni dei TA perché sto realizzando una centralina di controllo carichi.
Costano 2 o 3euro e potresti usarli per far spegnere i tuoi motori a finecorsa senza usare finecorsa e senza usare salite o discese temporizzate (se parti da tutto aperto hai x secondi e va bene, ma se parti da quasi chiuso hai gli stessi secondi di motore acceso e rischi di rovinarlo...).
Misuri l'assorbimento usando un pin analogico di Arduino che controlli solo quando hai il relè del motore acceso: quando l'assorbimento, per esempio, raddoppia, aspetti un secondo e poi spegni...
Un po' come i finestrini elettrici delle auto.

steve-cr:
Sto provando proprio in questi giorni dei TA perché sto realizzando una centralina di controllo carichi.
Costano 2 o 3euro e potresti usarli per far spegnere i tuoi motori a finecorsa senza usare finecorsa e senza usare salite o discese temporizzate (se parti da tutto aperto hai x secondi e va bene, ma se parti da quasi chiuso hai gli stessi secondi di motore acceso e rischi di rovinarlo...).
Misuri l'assorbimento usando un pin analogico di Arduino che controlli solo quando hai il relè del motore acceso: quando l'assorbimento, per esempio, raddoppia, aspetti un secondo e poi spegni...
Un po' come i finestrini elettrici delle auto.

mi permetto di intromettermi dato che sono serramentista e taparelle motorizzate le metto su a palate.
i motori delle tapparelle hanno già dei finecorsa integrati (impensabile il contrario!).
nicolini2000 li vuole temporizzare solo per non tenere sempre "in tensione" l'impianto/eccitato il relè di arduino.
danni non se ne fanno se si ha l'effetto del pulsante sempre premuto.

ho iniziato provando a scrivere lo sketh per il solo rele di salita altri sketch ma prova riprova e modifica, non funziona nulla
posto quello che ho scritto

#define releup 4 // definisce i pin per il controllo dei rele
  
  int buttonup = 2;
  int timeup = 5000;  //definisce il tempo di risalita della tapparella
  int val = 0;
   
  void setup() {

  pinMode( buttonup, INPUT );
  pinMode( releup,OUTPUT );
  digitalWrite( releup,LOW );
  }
    
  void loop() {
  val = digitalRead(buttonup); // legge il valore dell'input e lo conserva  
   
  if (val == LOW) { // controlla che l'input sia HIGH (pulsante premuto)  
  digitalWrite(releup, LOW);        // attiva il relé di salita
  delay(timeup);     //aspetta il finecorsa
  digitalWrite(releup, HIGH); 
}
  if (releup, LOW)
  val = digitalRead(buttonup); // legge il valore dell'input e lo conserva
  digitalWrite(releup, LOW);   

 }

Per cominciare ti chiederei di chiarariti/ci il funzionamento del relay. Prima, nella setup() per spegnerlo (presumibilmente) lo mandi LOW (operazione omettibipe in quanto esso é lo stato normale dei pin). Poi, nella prima if di loop(), dove palesemente lo vuoi eccitare lo mandi LOW nuovamente, per poi mandarlo HIGH al fine operazione.
Inoltre mi chiariaci a cosa servono le righe successive alla chiusura della graffa della prima if()? Io le toglierei

ho fatto un po di confusione con LOW-HIGH
ora posto quello che doveva essere postato

non capisco perchè quando accendo arduino il rele è già attivo e
quando premo il pulsante si spegne e rimane spento per il tempo di timeup poi si riaccende
Se premo il pulsante entro il tempo di timeup dovrebbe  interromper l'operazione



#define releup 4 // definisce i pin per il controllo dei rele
  
  int buttonup = 2;
  int timeup = 5000;  //definisce il tempo di risalita della tapparella
  int val = 0;
   
  void setup() {
  Serial.begin(9600);
  pinMode( buttonup, INPUT );
  pinMode( releup,OUTPUT );
  
  }
    
  void loop() {
  val = digitalRead(buttonup); // legge il valore dell'input e lo conserva  
  if (val == HIGH) { // controlla che l'input sia HIGH (pulsante premuto)  
  digitalWrite(releup, HIGH);        // attiva il relé di salita
  delay(timeup);     //aspetta il finecorsa
   
}
  if (releup, HIGH)
  val = digitalRead(buttonup); // legge il valore dell'input e lo conserva
  digitalWrite(releup, LOW);   
  
 }[code]

i relè lavorano contrari.
HIGH = diseccitati
LOW = eccitati

il problema all'accensione io l'ho risolto definendo nel setup i relè su HIGH

io ho provato e riprovato ma non riesco a tener spento il led

ho cambiato if (val == LOW) con HIGH ora il led è spento

se premo il pulsante buttonup si accende il led e si spegne dopo timeup

se ripremo il pulsante entro il tempo timeup il led si dovrebbe spegnere ma non avviene perchè il timeup lo tiene acceso. dovrei interrompere il ciclo del timeup

#define releup 4 // definisce i pin per il controllo dei rele
  
  int buttonup = 2;
  int timeup = 5000;  //definisce il tempo di risalita della tapparella
  int val = 0;
   
  void setup() {
  Serial.begin(9600);
  pinMode( buttonup, INPUT );
  pinMode( releup,OUTPUT );
  
  }
    
  void loop() {
  val = digitalRead(buttonup); // legge il valore dell'input e lo conserva  
  if (val == HIGH) { // controlla che l'input sia HIGH (pulsante premuto)  
  digitalWrite(releup, HIGH);        // attiva il relé di salita
  delay(timeup);     //aspetta il finecorsa
   
}
  if (releup, HIGH)
  val = digitalRead(buttonup); // legge il valore dell'input e lo conserva
  digitalWrite(releup, LOW);   
  
 }

è questo che devi cambiare!

digitalWrite(releup, HIGH);        // attiva il relé di salita

per le schedine rele HIGH vuol dire spento e LOW acceso!

p.s.
nicolini2000 per favore edita il tuo post #10 e inserisci il codice tra i tag code
In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Patrick_M:
per le schedine rele HIGH vuol dire spento e LOW acceso!

Per questo io consiglio di definire tutto quello che riguarda l'hardware all'inizio, e nel programma usare solo nomi di comodo (per convenzione maiuscoli) che evitano ogni ambiguità nell'interpretazione e permettono di capire cosa si sta facendo anche senza avere lo schema dei collegamenti sotto mano:

// definizione pin usati e livelli di comando,
// dipendono dai collegamenti effettuati
#define RELEUP    4
#define ON_LEVEL  LOW
#define OFF_LEVEL HIGH
// nel programma si usano solo i nomi di comodo
void setup()
{
  pinMode(RELEUP, OUTPUT);
  digitalWrite(RELEUP, OFF_LEVEL)
}

Stessa cosa per gli ingressi:

// definizione pin usati e livelli letti,
// dipendono dai collegamenti effettuati
#define BUTTONUP     2
#define PRESS_LEVEL  HIGH
// nel programma si usano solo i nomi di comodo
void setup()
{
  pinMode(BUTTONUP, INPUT);
}
   
void loop()
{
  byte val = digitalRead(BUTTONUP);
  if (val == PRESS_LEVEL) { .... }
}

L'importante è appunto non cospargere il codice di numerini magici e HIGH/LOW, che senza vedere lo schema non dicono nulla, e anche con lo schema ci si può comunque confondere. Se si cambia un collegamento hardware basta modificare le define iniziali e tutto il resto del programma rimane invariato.

nicolini2000:
ma non avviene perchè il timeup lo tiene acceso. dovrei interrompere il ciclo
del timeup

Per quanto riguarda il delay bloccante la risposta non è semplice. Per questo motivo (per semplificare) nel post #1 avevo proposto l'esempio del programma a contatti che simula i relé (con un temporizzatore realizzato con la funzione millis). Se parli di PLC/ladder do per scontato che un'automazione a relé non abbia segreti.

Riconoscere una seconda pressione del pulsante significa aver già riconosciuto il primo rilascio (a questo servono i relé X e Y dello schema del post #4). Il primo rilascio potrebbe avvenire prima o dopo lo scadere del timer, e se il pulsante è ancora premuto non deve partire un'altra sequenza. Alla seconda pressione il relé deve cadere, ma, di nuovo, non deve ripartire tutto da capo se si tiene il pulsante premuto (per queste cose serve il relé R dello schema).

Il programma deve tenere conto di tutte queste possibilità/situazioni contemporaneamente, e il codice procedurale con delay che hai usato è la scelta più incasinata perché permette di fare una e una sola cosa alla volta.

Quindi la domanda è: lo schema del post #4 fa quello che chiedi?
Se si, allora basta tradurlo in espressioni logiche (le serie/paralleli di contatti), una decina di righe e finito.

grazie Claudio_FF il post #4 mi sembra funzionare benissimo. mettendo in parallelo 1 contatto di un relè ai pulsanti up-dn e comandati da un pulsante generale si ottiene la funzione desiderata, ma bisogna premere 2 volte per essere sicuri che la tapparella si muova nella direzione voluta. Questo avviene se si preme il pulsante generale mentre le tapparelle si stanno muovendo, perchè alla prima pressione si arresterebbero

E' pur vero che situazioni dove la tapparella si muova in una direzione e da un comando generale si voglia far muovere nella direzione opposto sono molto rare

Non ho preso in considerazione lo schema che hai postato perchè pensavo che era una soluzione a relé

anche se ci proverò non credo di essere in grado di trasformare questo schema in espressioni logiche, e se mi daresti una mano te ne sarei grato

Esempio con il minimo per il relè A:

//-------------------------------------------------------
//   Definizioni hardware, dipendono dai collegamenti
//-------------------------------------------------------
#define P_UP         ...    // pin ingressi uscite
#define PG_UP        ...
#define RELEUP       ...
#define PRESS_LEVEL  ...    // livello ingressi premuti
#define ON_LEVEL     ...    // livello uscite accese
#define OFF_LEVEL !ON_LEVEL // livello uscite spente
//-------------------------------------------------------
//             Impostazione hardware micro
//-------------------------------------------------------
void setup()
{
  pinMode(P_UP, INPUT);
  pinMode(PG_UP, INPUT);
  pinMode(RELEUP, OUTPUT);
  digitalWrite(RELEUP, OFF_LEVEL);
}
//-------------------------------------------------------
//        Definizione variabili di lavoro globali
//-------------------------------------------------------
byte A = 0;
byte B = 0;
byte R = 0;
byte T = 0;
//-------------------------------------------------------
//                    Loop principale
//-------------------------------------------------------
void loop()
{
  // Lettura ingressi (serve debounce hardware)
  byte up = (digitalRead(P_UP) == PRESS_LEVEL)
            | (digitalRead(PG_UP) == PRESS_LEVEL);

  // Rung
  A = (up | A) & !B & !R & !T;

  // Aggiornamento uscite con interblocco
  digitalWrite(RELEUP, (A & !B) ? ON_LEVEL : OFF_LEVEL);
}
//-------------------------------------------------------

Riguardo al fatto di premere il generale mentre qualche tapparella si sta già muovendo, il comando alternativo che avevo suggerito elimina il problema in partenza, perché con due click giù sicuramente tutte le tapparelle scendono, sia che siano ferme, sia che qualcuna stia già scendendo, sia che qualcuna stia salendo.

Grazie Claudio_FF

come dicevo non conosco la programmazione arduino e quindi mi risulta difficile lo sketch
già dalle prime righe non capisco cosa assegnare al PRESS_LEVEL o ON_LEVEL.

sto assegnando ingressi e uscite sto provando e riprovando, cerco su manuali il significato di quelle espressioni ma ancora sono troppo lontano per realizzare uno sketch del tipo

pensavo che bastasse assegnare 4 ingressi e 2 uscite

#define P_UP          2        // pulsante salita locale 
#define P_DW         3       // pulsante discesa locale 
#define PG_UP        4       // pulsante salita generale 
#define PG_DW       5       // pulsante discesa generale 
#define RELEUP       11     // relè salita 
#define RELEDW     12      // relè discesa 
#define PRESS_LEVEL  6    // livello ingressi premuti
#define ON_LEVEL     7     // livello uscite accese

Comunque cerco di andare avanti ma fin'ora nessun risultato

#define PRESS_LEVEL 6 // livello ingressi premuti
#define ON_LEVEL 7 // livello uscite accese

qui non ci va un numero, dipende da come hai collegato i pulsanti avrai che pulsante premuto è = HIGH oppure LOW, lo stesso per il livello uscite accese ...