Go Down

Topic: automazione tapparelle (Read 3760 times) previous topic - next topic

Claudio_FF

#15
Sep 11, 2018, 07:20 am Last Edit: Sep 11, 2018, 01:31 pm by Claudio_FF
Quote from: 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:

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

Stessa cosa per gli ingressi:
Code: [Select]
// definizione pin usati e livelli letti,
// dipendono dai collegamenti effettuati
#define BUTTONUP     2
#define PRESS_LEVEL  HIGH
Code: [Select]
// 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.


Quote from: 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.
* * * *    if non è un ciclo   * * * *
* * * Una domanda ben posta è già mezza risposta. * * *

nicolini2000

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

Claudio_FF

#17
Sep 14, 2018, 06:59 pm Last Edit: Sep 15, 2018, 09:47 am by Claudio_FF
Esempio con il minimo per il relè A:
Code: [Select]
//-------------------------------------------------------
//   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.
* * * *    if non è un ciclo   * * * *
* * * Una domanda ben posta è già mezza risposta. * * *

nicolini2000

#18
Sep 15, 2018, 12:59 pm Last Edit: Sep 15, 2018, 02:04 pm by nicolini2000
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

Code: [Select]
#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
 

Patrick_M

#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 ...
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

nicolini2000

#20
Sep 15, 2018, 02:19 pm Last Edit: Sep 15, 2018, 02:34 pm by nicolini2000
sono riuscita ad arrivare fin qui
Code: [Select]
                         // COMANDI SALITA

#define P_UP         2            // pulsante salita locale
#define PG_UP        4            // pulsante salita generale
#define RELEUP       11           // relè comando salita
#define PRESS_LEVELUP  HIGH       // livello ingressi premuti
#define ON_LEVELUP     LOW         // livello uscite accese
#define OFF_LEVELUP !ON_LEVELUP    // livello uscite spente

                         //COMANDI DISCESA

#define P_DW         3             // pulsante salita locale
#define PG_DW        5             // pulsante salita locale
#define RELEDW       12            // relè comando discesa
#define PRESS_LEVELDW  HIGH        // livello ingressi premuti
#define ON_LEVELDW     LOW         // livello uscite accese
#define OFF_LEVELDW !ON_LEVELDW   // livello uscite spente



void setup()
 {     
                  //DICHIARAZIONE PIN DI SALITA
 
  pinMode(P_UP, INPUT);
  pinMode(PG_UP, INPUT);
  pinMode(RELEUP, OUTPUT);
  digitalWrite(RELEUP, OFF_LEVELUP);
 
                 //DICHIARAZIONE PIN DI DISCESA
 
  pinMode(P_DW, INPUT);
  pinMode(PG_DW, INPUT);
  pinMode(RELEDW, OUTPUT);
  digitalWrite(RELEDW, OFF_LEVELDW);
  }

                //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_LEVELUP)
            | (digitalRead(PG_UP) == PRESS_LEVELUP);

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

  // Aggiornamento uscite con interblocco
  digitalWrite(RELEUP, (A & !B) ? ON_LEVELUP : OFF_LEVELUP);

//--------------------------------------------------------------------

 // Lettura ingressi (serve debounce hardware)
  byte dw = (digitalRead(P_DW) == PRESS_LEVELDW)
            | (digitalRead(PG_DW) == PRESS_LEVELDW);

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

  // Aggiornamento uscite con interblocco
  digitalWrite(RELEDW, (B & !A) ? ON_LEVELDW : OFF_LEVELDW);


si attiva un relè ma non si stacca e di conseguenza non si attiva l'altro

nicolini2000

#21
Sep 15, 2018, 02:37 pm Last Edit: Sep 15, 2018, 02:40 pm by nicolini2000
non riesco a decifrare (up | A)
nella stringa
Code: [Select]

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

significa autoritenuta di A?

Silente

Praticamente in qyella stringa dici che A vale 1 se (A vale 1 o up vale 1) e B, R e T valgono 0
Dove va un numero va una variabile o una funzione. E dove va una boolean va un insieme di test.

Se vuoi ottenere devi saper spiegare

In pochi capiscono l'importanza di formattare, sii tra di essi

Claudio_FF

#23
Sep 15, 2018, 07:01 pm Last Edit: Sep 15, 2018, 07:37 pm by Claudio_FF
Quote from: nicolini2000
pensavo che bastasse assegnare 4 ingressi e 2 uscite
In realtà non sono indispensabili neppure quelle. Come detto nel post #15 sono solo nomi di comodo da usare nel resto del programma per non confondersi (tra l'altro c'era già un esempio su cosa assegnare a PRESS_LEVEL).

Se leggo digitalWrite(12, HIGH) non so cosa c'è collegato al pin12, e non so se HIGH vuole dire acceso o spento.

Invece se leggo digitalWrite(RELE_VENTOLA, ACCESO) non ci sono dubbi.



Poi se tutti i pulsanti danno lo stesso livello quando premuti non serve (anche se nulla lo impedisce) fare distinzioni tra PRESS_LEVELUP e PRESS_LEVELDW, idem per le uscite.



Nell' espressione (A | up) si, la A è l'autoritenuta.

| -> or -> contatti in parallelo
& -> and -> contatti in serie
! -> contatto negato

Nel post #1 c'è anche l'esempio del temporizzatore.



Per quanto riguarda il codice meglio mettere tutte le letture assieme all'inizio della loop e gli aggiornamenti uscite alla fine.

In qualche caso l'ordine delle espressioni può essere importante (come accade anche nei programmi ladder), ma di solito se l'ordine delle espressioni segue l'ordine di attivazione dei relé non ci dovrebbero essere effetti collaterali (che si risolvono con un aggiornamento sincrono delle variabili, ma direi che inutile complicare per un caso come questo).
* * * *    if non è un ciclo   * * * *
* * * Una domanda ben posta è già mezza risposta. * * *

nicolini2000

#24
Sep 16, 2018, 02:26 pm Last Edit: Sep 16, 2018, 02:36 pm by nicolini2000
ho aggiunto ancora un pezzo allo sketch ma non funziona regolarmente
nel circuito ci sono anche antirimbalzi sui pulsante

premendo i pulsanti non sempre il relè si attiva subito, a volte rimane spento o si spegne al rilascio del pulsante
Code: [Select]


#define P_UP         2            // pulsante salita locale
#define PG_UP        4            // pulsante salita generale
#define RELEUP       11           // relè comando salita
#define PRESS_LEVELUP  HIGH       // livello ingressi premuti
#define ON_LEVELUP     LOW         // livello uscite accese
#define OFF_LEVELUP !ON_LEVELUP    // livello uscite spente

                         //COMANDI DISCESA

#define P_DW         3             // pulsante salita locale
#define PG_DW        5             // pulsante salita locale
#define RELEDW       12            // relè comando discesa
#define PRESS_LEVELDW  HIGH        // livello ingressi premuti
#define ON_LEVELDW     LOW         // livello uscite accese
#define OFF_LEVELDW !ON_LEVELDW   // livello uscite spente

------------------------------------------------------------------------------------

void setup()
 {     
                  //DICHIARAZIONE PIN DI SALITA
 
  pinMode(P_UP, INPUT);
  pinMode(PG_UP, INPUT);
  pinMode(RELEUP, OUTPUT);
  digitalWrite(RELEUP, OFF_LEVELUP);
 
                 //DICHIARAZIONE PIN DI DISCESA
 
  pinMode(P_DW, INPUT);
  pinMode(PG_DW, INPUT);
  pinMode(RELEDW, OUTPUT);
  digitalWrite(RELEDW, OFF_LEVELDW);
  }

                //Definizione variabili di lavoro globali

 byte A = 0;
 byte B = 0;
 byte R = 0;
 byte T = 0;
 byte X = 0;
 byte Y = 0;
 ---------------------------------------------------------------------------------------------------------
                    //Loop principale

 void loop()
 {
                     
  // Lettura ingressi per la salita (serve debounce hardware)
 
  byte up = (digitalRead(P_UP) == PRESS_LEVELUP)
            | (digitalRead(PG_UP) == PRESS_LEVELUP);
           
  // Rung
  A = (up | A) & !B & !R & !T;

  // Aggiornamento uscite con interblocco
  digitalWrite(RELEUP, (A & !B) ? ON_LEVELUP : OFF_LEVELUP);
 

  //--------------------------------------------------------------------

 // Lettura ingressi per la discesa (serve debounce hardware)
 
    byte dw = (digitalRead(P_DW) == PRESS_LEVELDW)
            | (digitalRead(PG_DW) == PRESS_LEVELDW);
           
  // Rung
  B = (dw | B) & !A & !R & !T;

  // Aggiornamento uscite con interblocco
  digitalWrite(RELEDW, (B & !A) ? ON_LEVELDW : OFF_LEVELDW);
 



  //------------COMANDO RESET DEI MOVIMENTO-------------------------------------

 
 
 // Lettura ingressi (serve debounce hardware)
   
     // qui memorizzzo che sono in salita per poi fermarla con un qualsiasi pulsante           
  X = ((A & !up) | X) & !B & !R & !T;
 
    // qui memorizzzo che sono in discesa per poi fermarla con un qualsiasi pulsante
  Y = ((B & !dw) | Y) & !A & !R & !T;
 
   // qui arresto i movimenti premendo un qualsiasi pulsante
  R = (up | dw) & ( X | Y | T | R);
}


ho iniziato programmare anche la temporizzazione ma l'esempio dello sketch #1 non sono ancora riuscito a farlo funzionare

Claudio_FF

Quote from: nicolini2000
nel circuito ci sono anche antirimbalzi sui pulsante
premendo i pulsanti non sempre il relè si attiva subito, a volte rimane spento o si spegne al rilascio del pulsante
I pulsanti non sono collegati correttamente.
* * * *    if non è un ciclo   * * * *
* * * Una domanda ben posta è già mezza risposta. * * *

nicolini2000

allego lo schema di cablaggio

Claudio_FF

#27
Sep 17, 2018, 06:05 pm Last Edit: Sep 18, 2018, 12:48 am by Claudio_FF
Nello schema non vedo i condensatori di filtro per i rimbalzi (in parallelo alle R pull-down), quindi non c'è il debounce.

Ma vedo invece molti disastri annunciati:

  • Alimentazione 5V distribuita (suscettibile ad ogni genere di disturbo irradiato, condotto e accoppiato)
  • Terminali del processore prolungati per metri (suscettibili ad ad ogni genere di disturbo irradiato, condotto e accoppiato)
  • Resistenze di pull-down lontane dalle masse locali degli Arduino (possibile captazione di alternate indotte oltre i limiti di rottura delle porte di ingresso)
  • Relé non ben chiaro se alimentati direttamente dalle porte o se è solo un'idea di principio (visto che così non possono funzionare per la scarsa corrente gestibile dalle porte e mancanza dei diodi soppressori delle extratensioni della bobina).

Dal punto di vista del cablaggio, idealmente l'elettronica è come l'elettrotecnica, però bisogna considerare molte cose che non influiscono sui normali circuiti "elettrotecnici" perché sono formati da componenti con bassa impedenza ed elevata inerzia.

Per le prove al banco quindi basta aggiungere dei condensatori in parallelo alle resistenze con costante di tempo R*C pari ad almeno 10ms.

Per l'uso reale cominciamo con alimentare a 12V, e ridurre la tensione localmente vicino ad ogni Arduino. Anche i pulsanti devono chiudere i 12V, e la tensione va ridotta vicino agli ingressi con un partitore a bassa impedenza (perfetto 150 + 100..120 ohm).
* * * *    if non è un ciclo   * * * *
* * * Una domanda ben posta è già mezza risposta. * * *

Puso

Scusate mi permetto una piccola CRITICA spero costruttiva.....(in quanto per mestiere ElettroTecnicoMeccanico di DUBBIE QUALITA'....e non Softwerista, a parte per hobby).

Ho notato che ci sono molti......#define...... e pochi boolean........in fondo un Relè , è o acceso oppure spento.



Claudio_FF

#29
Sep 18, 2018, 12:40 am Last Edit: Sep 18, 2018, 12:47 am by Claudio_FF
Quote from: Puso
ci sono molti......#define...... e pochi boolean........in fondo un Relè , è o acceso oppure spento.
Una variabile bool si usa per chiarezza al posto di un byte 1 o 0, ma affinché vi sia la chiarezza il suo nome deve essere una domanda, e la risposta deve essere true o false. I nomi dei relé simulati A B X ecc non sono domande, in questo programma che simula solo un circuito elettrico con una logica "a contatti" non serve controllare l'esecuzione tramite if e variabili booleane.
* * * *    if non è un ciclo   * * * *
* * * Una domanda ben posta è già mezza risposta. * * *

Go Up