Vai al contenuto

Problemi con memorie ritentive PLC SlimLine MPS5054C110

Home Forum Controllori SlimLine e Netsyst (LogicLab) Problemi con memorie ritentive PLC SlimLine MPS5054C110

Stai visualizzando 5 post - dal 1 a 5 (di 5 totali)
  • Autore
    Post
  • #83403
    PLP
    Partecipante

    Facendo delle prove ho notato che le variabili che ho utilizzato per registrare le ore di funzionamento di alcuni dispositivi, allo spegnimento e riavvio del PLC si azzerano, come mai?

    La dichiarazione delle variabili in linguaggio ST che ho usato:

    HMI_ORE_ASP1 AT %MW100.2048: INT; (* Word di registrazione ore funzionamento aspiratore 1*)
    HMI_ORE_ASP2 AT %MW100.2050: INT; (* Word di registrazione ore funzionamento aspiratore 2*)
    HMI_IMP_ORE_A1 AT %MW100.2052: INT:=3600; (* Word di impostazione ore max funzionamento aspiratore 1*)
    HMI_IMP_ORE_A2 AT %MW100.2054: INT:=3600; (* Word di impostazione ore max funzionamento aspiratore 1*)
    HMI_num_cest AT %MW100.2056: INT; (* Word di registrazione numero max di cestelli utilizzati *)
    #83408
    Sergio Bertana
    Amministratore del forum

    Il backup dei dati è effettuato in una memoria FRAM che non necessita di batterie. Alla accensione viene eseguita una verifica sul CRC dei valori memorizzati allo spegnimento, se il controllo è in errore tutte la variabili sono azzerate e viene settata la variabile SysRestoreFault.

    Se il controllo è corretto le variabili vengono valorizzate con i valori allo spegnimento poi viene eseguita la funzione che assegna alle variabili i valori di inizializzazione. Nel tuo caso vedo che hai inizializzato alcune variabili in area ritentiva, queste naturalmente assumeranno sempre il valore definito nella inizializzazione.

    Il fatto che le variabili ritentive si azzerino è molto strano, per evitare che sia il programma a sporcarle, ti consiglio di realizzare un nuovo programma LogicLab con solo il programma MyProgram, poi definire le variabili ritentive così come hai indicato e da debug impostare valori casuali nelle variabili. Spegnere ed accendere il sistema e verificare se il valore viene mantenuto.

    Nel caso siano azzerate puoi collegarti verificare da debug lo stato della variabile SysRestoreFault, ed eventualmente collegarti in telnet, eseguire il comando SysLog e postare il risultato del comando.

     

    #83440
    PLP
    Partecipante

    Le memorie cosi dichiarate funzionano bene, è il “CounterUp” che ho usato che deve essere a ritenzione.

    Ho fatto delle prove e ho assegnato all’oggetto CTU che mi serviva l’area di memoria DB100.2048 e il tutto funziona bene.

    #83467
    Sergio Bertana
    Amministratore del forum

    Colgo l’occasione della discussione per trattare lo spinoso argomento del rendere ritentivi i blocchi funzione. I FB utilizzano al loro interno svariate variabili e non è noto il loro impegno di memoria, quindi sconsiglio la loro allocazione in area indirizzabile come la DB100. Perchè dovendo definire gli indirizzi di allocazione non è possibile sapere a priori a che indirizzo allocare la variabile successiva alla allocazione del FB. Quindi se proprio si desidera rendere ritentivo un FB è preferibile definirlo in area automatica con l’attributo RETAIN.

    Rendere retain un FB potrebbe nascondere insidie, chi sviluppa i FB solitamente non li struttura per essere tamponati, per esempio potrebbe alllocare al loro interno memoria rilocabile ed in questo caso il mantenere retain l’indirizzo di allocazione potrebbe portare a gravi errori di funzionamento del programma. Nel tuo caso quindi puoi allocare il tuo FB CTU in area automatica con l’attributo RETAIN.

    Nel caso ti occorra accedere da Modbus il valore di conteggio, non utilizzare più il FB CTU ma alloca ad esempio in DB100.2048 una variabili UINT o UDINT e gestisci il conteggio da programma, ecco un esempio:

    VAR
        Pulse : BOOL; (* Clock pulse *)
        Di00CPU AT %IX255.0 : BOOL; (* Digital input *)
        Counter AT %MD100.2048 : UDINT; (* Counter value *)
    END_VAR
    
        IF (Di00CPU <> Pulse) THEN
            Pulse:=Di00CPU; //Clock pulse
            IF (Di00CPU) THEN Counter:=Counter+1; END_IF;
        END_IF;
    #83475
    PLP
    Partecipante

    Grazie dell’informazione, in effetti mi era sorto questo dubbio, ora ho modificato il codice secondo il tuo ultimo esempio, ecco il programma di test:

    PROGRAM MyProgram

    VAR

    Start AT %IX255.0 : BOOL; (* Pulsante di marcia motore *)

    Stop AT %IX255.1 : BOOL; (* Pulsante di stop motore *)

    Km AT %QX255.0 : BOOL; (* Comando di  avvio e stop motore *)

    N_AVVII AT %MW100.2048 : INT; (* Numero di avvi motore *)

    Reset AT %MX100.0 : BOOL;

    Seg AT %MX100.1 : BOOL; (* segnalazione max numero avvii raggiunto*)

    TP_Trig : R_TRIG;

    END_VAR

     

     

    Km:= (Start OR Km) AND NOT Stop;

    TP_Trig(CLK := Km);

    IF (TP_Trig.Q) THEN

    N_AVVII := N_AVVII+1;

    END_IF;

    IF(N_AVVII >= 15)THEN

    Seg:=TRUE;

    END_IF;

    IF(Reset= TRUE)THEN

    N_AVVII:=0;

    Seg:= FALSE;

    END_IF;

    cosi ho tutte le variabili sotto controllo.

Stai visualizzando 5 post - dal 1 a 5 (di 5 totali)
  • Devi essere connesso per rispondere a questo topic.