ARDUINO Gestione Allarmi

di il
8 risposte

ARDUINO Gestione Allarmi

Buongiorno, so sviluppando un progetto con Arduino Mega + Display Grafico Nextion, solo a premessa.

Il sistema deve gestire un sistema di Automazione basico, con alcuni sensori ed utenze(Motori/Riscaldatori/Compressori ecc)… diciamo che sulla parte automazione il problema è relativamente sotto controllo, dico relativamente per la mia scarsa conoscenza del C/C++ approfondita, funzionicchia anche se il codice sarà scritto male… su questo però ci sto lavorando essendo ipercritico(non parlo di pressoine e temperatura, battuta termodinamica).

Ora mi serve prima un suggerimento sulla LOGICA della gestione Allarmi poi su come orientare lo sviluppo codice.

In sostanza l'automazione può generare N allarmi, nel mio caso sono limitati ad una quindicina, ovviamente possono essere attivi più di 1 alla volta, e rientrare uno alla volta.

La segnalazione di Allarme visivo è solo 1, quindi riassuntiva, nei sistemi integrati industriali viene attivato l'OR ripetitivo degli allarmi con il Lampeggio ad ogni Nuova Causa, va bene questo potrei anche farlo, tuttavia il problema non è tanto sulla segnalazione quanto sul ripristino parziale e non totale… 

Pensavo di creare un Array di Allarmi, tipo Libreria con i miei 15 allarmi codificati, uno per causa chiaramente con Indice e Descrizione ed un Array Vuoto nel quale registro/inserisco l'Indice degli allarmi Usciti, ogni nuovo inserimento attiva il lampeggio fino al riconoscimento della nuova causa che rende fissa la segnalazione, ovviamente quando l'array è vuoto resetto la segnalazione…

Quanto descritto sarebbe la LOGICA funzionale a cui pensavo di dare seguito.

In VB6 avrei usato una Collection in quanto usando la KEY non sarei stato influenzato dall'indice di Array che scala quando si rimuovono gli Items, con gli Array serve sempre ciclare tutto ad ogni Rientro per individuare il Valore dell'allarme e rimuoverlo, mentre con la Collection andrei a Rimuovere senza Ciclare quello rientrato passando la KEY al metodo Remove…, chiaramente il mio è un LIMITE di conoscenza che mi vede sempre ragionare con il VB6, anzichè con questo linguaggio, spero tuttavia mi possa aiutare a capire i suggerimenti.

Mi serve qualche spunto per partire, prima sulla LOGICA poi sull'idea di come affrontare il codice.

Grazie

8 Risposte

  • Re: ARDUINO Gestione Allarmi

    12/03/2024 - @Alex ha scritto:


    Ora mi serve prima un suggerimento sulla LOGICA della gestione Allarmi poi su come orientare lo sviluppo codice.

    non è chiaro (secondo me) cosa devi realizzare (parlo della parte logica).

    l'allarme (suppongo una spia led) deve avviarsi in funzione di cosa? Hai un controllo che non fa scattare l'allarme? 

    Per ipotesi, se devi controllare l'apertura di un cancello, hai due sensori: uno all'apertura massima e uno alla chiusura. hai un tempo di apertura e di chiusura con i relativi ritardi e se dopo il tempo T non scatta il sensore generi l'allarme (un loop).

    12/03/2024 - @Alex ha scritto:


    La segnalazione di Allarme visivo è solo 1, quindi riassuntiva, nei sistemi integrati industriali viene attivato l'OR ripetitivo degli allarmi con il Lampeggio ad ogni Nuova Causa, va bene questo potrei anche farlo, tuttavia il problema non è tanto sulla segnalazione quanto sul ripristino parziale e non totale… 

    in questi casi, va bene l'array ma all'errore leggi un codice e mandi una sequenza di lampeggi per ogni errore (tipo alfabeto morse). interrotto da un lampeggio lungo. errore1: 1 lampeggio breve 1 lampeggio lungo; errore2 2 lampeggi brevi 1 lampeggio lungo. ma questo lo decidi tu.

    il solo lampeggio lungo indicherebbe sia il meccanismo in funzione che l'assenza di allarmi.

    il ripristino cosa intendi? 

    nell'esempio del cancello, trascorso il tempo di chiusura (apertura) senza che l'interruttore di controllo mandi un segnale di allarme (che sia del tipo normalmente chiuso o normalmente aperto), dopo un ulteriore tempo stacchi il motore, pur mantenendo l'allarme di anomalia.

    sempre nell'esempio del cancello, se il motore non parte, il controllo lo rilevi dall'interruttore (a monte o a valle della corsa del braccio) che non cambia lo stato da chiuso ad aperto o viceversa, generando l'allarme motore.

    la logica vale per tutto cio' che devi controllare, cambiano i segnali del tipo di errore.

  • Re: ARDUINO Gestione Allarmi

    Non ha importanza quale sia l'Allarme… un allarme è una qualsiasi causa a cui io ritenga di Attribuire il sesno di Allarme quindi deve essere visivamente annunciato, non sottiliziamo sul cancello o motore… non penso siano discriminanti.

    Quando esce un nuovo allarme si deve Accendere la Lampada Lampeggiante sul quadro.
    Ogni volta che esce una “nuova” causa Allarme genera il Blink finchè l'operatore non riconosce “Acknoledge”, quidi poi rimane fissa se almeno 1 causa presente.
    Se al riconoscimento nessuna casua è in Lista si spegne, è un classico sistema di segnalazione generico.

    Io ho 15 cause, che identifico con un Indice 0÷14, ed ho una Lista di questi 15 Allarmi un catalogo, quando uno cambia stato/attiva se non già presente lo inserisco in un Array, quando cambia di stato/ripristina se è presente lo rimuovo, la lista pertanto è una sorta di DataLogger degli Allarmi.

    Ipotiziamo quindi io voglia per il momento memorizzare solo un valore [Int] relativo all'indice dell'allarme in catalogo, poi in realtà ogni allarme avrà il TimeStamp/Stato di Acknoledge ecc…, ma per ora lasciamo stare, starei sul semplice, Catalogo Allarmi e Lista Eventi.

    Aggiungo:

    Alla fine forse, per semplificare mi basta un Array statico Boolean di 15 Items, e lo ciclo sempre, sono 15 penso non sia un carico inspopportabile… così semplifico ulteriormente la gestione di array dinamici.

  • Re: ARDUINO Gestione Allarmi

    Ok, sempre per la parte logica, prenderei spunto dalle centraline dell'auto…

    Ogni volta che si presenta l'allarme la centralina registra, se rientra l'allarme (sostituzione lampadina, filo staccato riattaccato ecc…) la centralina registra ok.

    Per ogni ko hai l'allarme, per ok no.

    L' array è sempre 15 i valori vanno da ok a ko.

    Non so se potrebbe andare bene.

    Non devi far altro che registrare i valori e leggerli.

    In fondo anche nell'auto si accende solo una spia…;))

  • Re: ARDUINO Gestione Allarmi

    Al momento ho provato una cosa simile:

    struct dataAlarm
    {
      int idx;
      bool State;
      bool Ack;
      char Desc[16];
    };
    
    dataAlarm data[10] //an array of 10 structs of type dataAlarm
    {
      {0, 0, 0, "1° Allarme"},
      {1, 0, 0, "2° Allarme"},
      {2, 0, 0, "3° Allarme"},
      {3, 0, 0, "4° Allarme"},
      {4, 0, 0, "5° Allarme"},
      {5, 0, 0, "6° Allarme"},
      {6, 0, 0, "7° Allarme"},
      {7, 0, 0, "8° Allarme"},
      {8, 0, 0, "9° Allarme"},
      {9, 0, 0, "10° Allarme"}
    };

    il Type [idx] non serve a nulla… ma per ora è li.

    La funzione da chiamare 

    void SetAlarm(byte IndexArray, bool State, bool Ack){
    
    };

    All'interno aggiorno lo stato dell'Indice di Allarme, se Attivo/Riconosciuto o altro, poi ciclo l'array e determino se ho Allarmi e se ne ho Non riconosciuti in quel caso gestico la Lampada Spenta/Fissa/Accesa…

    Forse funziona…

  • Re: ARDUINO Gestione Allarmi

    Ciao Alex,

    io utilizzerei una variabile UINT (16 bit) come memoria dei 15 stati di allarme (quindi la variabile viene gestita come un array di 16 bit), ad ogni bit corrisponde un allarme specifico.

    Poi utilizzerei una variabile UINT per memorizzare il riconoscimento (o tacitazione) dell'allarme (ovviamente è sempre un array di 16 bit ‘posizionale’ rispetto all'array degli allarmi) : quindi bit 0 = allarme alta pressione (UINT Allarmi), bit 0 = riconoscimento allarme alta pressione (UINT ACK).

    Utilizzerei quindi una terza variabile UINT per memorizzare il comportamento in caso di allarme/ACK. La variabile viene calcolata come XOR dei bit delle 2 variabili precedenti (quindi 0/0 e 1/1 = 0 altrimenti ottengo 1). 

    Sequenza logica (spannometricamente) :

    • verifico le condizioni di allarme e imposto i bit della variabile (iAlarms), se un bit passa da Allarme (1) ad Assenza Allarme (0) resetto anche il corrispondente bit di tacitazione
    • verifico e imposto gli eventuali bit di riconoscimento/tacitazione della variabile (iAck) in arrivo dai pulsanti/pannello operatore
    • calcolo la variabile per il comportamento in caso di allarme/ACK (iBehaviour) facendo uno XOR dei 16 bit delle 2 precedenti variabili
    • se IAlarms > 0 e iBehaviour > 0  ? Spia Allarme Fissa, se iAlarms > 0 e iBehaviours = 0 ? Spia Allarme Lampeggiante, se iAlarms = 0 ovviamente ? Spia Allarme spenta

    Salvo errori ed omissioni …

  • Re: ARDUINO Gestione Allarmi

    Ciao Max, chiarissimo basta usare la Mascheratura dei Bit, AND/OR/XOR per Rilevare/Forzare tutte le variabili si il concetto è molto semplice.

    Diventa un po più rigido se dovessi implementare cause rispetto all'array ma sicuramente è snello.

    Resta poi la parte della Descrizione nella pagina Allarmi del Display… su cui devo usare in ogni caso un Array Char, per questo ho pensato che tanto valeva orientarsi su un Array Struct.

    In ogni caso provo anche la tua soluzione, i DCS sono molto più facili da programmare con linguaggio strutturato ed oggetti… ;-)

    Grazie.

  • Re: ARDUINO Gestione Allarmi

    12/03/2024 - @Alex ha scritto:


    In ogni caso provo anche la tua soluzione, i DCS sono molto più facili da programmare con linguaggio strutturato ed oggetti… ;-)

    Ti ho proposto un approccio stile PLC alla vecchia maniera (e credo che sia facilmente adattabile al mondo Arduino), io i DCS li vedo solo in cartolina :)

  • Re: ARDUINO Gestione Allarmi

    Si chiaramente funziona, è pura logica booleana, ho fatto un test veloce pur con diverse difficoltà sulla sintassi per il ciclo di shift dei bit, e per la mia poca pratica con il C mi sembra più complicata che questo nella mia testa:

    void SetAlarm(int idx, bool value, bool ack){
      bool bAlarm=0;
      data[idx].State=value;
      data[idx].Ack=ack;
    
      for (byte i = 0; i < 15; i = i + 1) {
        bAlarm=bAlarm || (data[i].State && !data[i].Ack);
        if (data[i].State && !data[i].Ack) {Serial.println(data[i].Desc);}
      }
      if (AlarmState!=bAlarm) {
        AlarmState=bAlarm;
        digitalWrite(ALARM_PIN, AlarmState && AlarmENABLED);
      }  
      // SET ICON ON DISPLAY
      // ....
    }
    
    void AckAlarms(){
      for (byte i = 0; i < 15; i = i + 1) {
        if (data[i].State && !data[i].Ack){data[i].Ack=1;}
      }
      digitalWrite(ALARM_PIN, LOW);
    }  

    Per ora il riconoscimento è ALL_IN_ONE, poi ci penso se vale la pena differenziare.

    Non ho idea in termini di impatto sulla memoria… tra i 2 metodi, ma a buonsenso il tuo suggerimento penso sia più compatto, ma la realizzazione per me più rognosa.

Devi accedere o registrarti per scrivere nel forum
8 risposte