Vai al contenuto
PLC Forum


Errore Di Lunghezza Di Campo Lettura/scrittura - Richiesta sul come poter gestire questo tipo di errore


Vito.M

Messaggi consigliati

Salve, sono uno studente di Ing. dell'Automazione .Sono in procinto di concludere la laurea triennale e come tesi ho scelto una tesi sullo sviluppo di un software per un prototipo di magazzino automatico industriale.

Il Plc,come da sezione,è della serie S7-300(Step7 5.5).Per quanto riguarda l'HW non penso di dovermi dilungare più di tanto,vista la natura della mia richiesta.

In pratica devo sviluppare un progetto per gestire questo magazzino automatico.

Ho scelto di scrivere quasi tutto in SCL,ed in particolare,utilizzare una programmazione "SFC-like".In poche parole è come se avessi realizzato in fase di progetto una serie di SFC e poi li avessi "tradotti" in SCL.

Veniamo al punto:

questa è la struttura dati che ho utilizzato per gestire il magazzino:

mag.jpeg

qui ci sono le altre strutture:

rul

core_lif

lif

liv

Quanto tento di chiamare nell'OB1 un certo FB (che dovrebbe inserire un pallet in una locazione del magazzino) tramite una "CALL",arrivato ad un certo punto il PLC va in fault e nel buffer risulta prendere "errore di lunghezza di campo lettura/scrittura".

Ecco l'FB:

FUNCTION_BLOCK FB107




VAR_INPUT
    
    ld: INT;

END_VAR




VAR
    s :INT:=1;
    my_l2r :FB103;
    my_r2l :FB102;
    my_align :FB100;
    my_r2r   :r2r;
    my_calll  :calll;
    

END_VAR



    

BEGIN


    
    CASE s OF
        1 : 
            IF NOT mag.q[ld].r[1].full  THEN
            my_l2r.s:=1;
            s:=2;
        END_IF;
        
        2:   
                my_l2r(ls:=mag.lc ,rd:=mag.q[ld].r[1],d:=false);
                  IF my_l2r.s=0 THEN
                        my_align.s:=1;            
                    s:=3;
                 END_IF;   
        3:      
        
                my_align(r:=mag.q[ld].r[1],d:=false);
                IF my_align.s=0 THEN
                    s:=4;
                END_IF;
          ;
        4 :
            IF NOT mag.q[ld].r[2].full THEN
               my_calll.s:=1;
               s:=5;
        ELSE s:=0;
            END_IF;
        5:
        
                my_calll(lift:=mag.lb,ld:=ld);
                IF my_calll.s=0 THEN
                        my_r2l.s:=1;
                        s:=6;
                END_IF;
        6:            
                        my_r2l(rs:=mag.q[ld].r[1],ld:=mag.lb,d:=false);
                    IF my_r2l.s=0 THEN
                        my_align.s:=1;
                        s:=7;
                END_IF;
        7:           
                    my_align(r:=mag.lb.r,d:=false);
                    IF my_align.s=0 THEN    
                        my_l2r.s:=1;
                        s:=8;
                END_IF;
        8:            
                   my_l2r(ls:=mag.lb,rd:=mag.q[ld].r[2],d:=false);
                    IF my_l2r.s=0 THEN                        
                        my_align.s:=1;
                        s:=9;
                END_IF;
        9:        
                    my_align(r:=mag.q[ld].r[2],d:=false);
                    IF my_align.s=0 THEN    
                        s:=0;
                    END_IF;

          ;
    END_CASE;

  ;
END_FUNCTION_BLOCK
Il fault si verifica subito dopo la prima chiamata di my_l2r,più precisamente non appena my_l2r termina il proprio flusso di esecuzione. per completezze posto anche l2r ed align: align :
// Funzione che si occupa di allineare un pallet a destra
// o a sinistra su una rulliera




FUNCTION_BLOCK FB100


//parametri

VAR_INPUT
    d : BOOL;      //d=TRUE destra
                   //d=FALSE sinistra 

END_VAR

VAR_IN_OUT
    r : rul;
END_VAR



VAR
    s : INT;
END_VAR


//istruzioni
BEGIN

    CASE s OF
        1 :
         // IF NOT r.busy THEN
            r.busy:=TRUE;  
            IF NOT d AND r.fs THEN   //sinistra
                s:=11;
            ELSIF  d AND  r.fd THEN //destra
                s:=21;
            END_IF;
        //  END_IF;  
          ;
        11 :
        
        r.ms:=TRUE;    
        
        IF NOT r.fs THEN 
            s:=3;
        END_IF;   
    ;
         
        21 :
        
        r.md:=TRUE;
        IF NOT r.fd THEN
            s:=3;
        END_IF;
      ;
        
        3 : 
        
        
        IF r.ms THEN
            r.ms:=FALSE;
            s:=4;
          ;
        ELSIF r.md THEN
            r.md:=FALSE;
            s:=4;
          ;
        END_IF;
      ;
        
        4: 
        
        r.busy:=FALSE;
        s:=0;
              
    
            
    END_CASE;


   

END_FUNCTION_BLOCK
l2r
FUNCTION_BLOCK FB103

// Parametri del blocco
VAR_INPUT
   
   d :BOOL;

END_VAR

VAR_IN_OUT
  ls : LIF;
  rd : RUL;
END_VAR

VAR
    s : INT :=1;

END_VAR

    // Parte istruzioni
    
    
    
BEGIN

  
    
    CASE s OF
       1 :
            IF ls.r.full AND NOT rd.full  THEN
            

                rd.busy:=TRUE;
                ls.r.busy:=TRUE;
                s:=2;
           
            END_IF;

          ;
        2 :
           
            IF d THEN
              
            ls.r.md:=TRUE;
            s:=31;
        ELSIF NOT d THEN
              ls.r.ms:=TRUE;
              s:=41;
            END_IF;
        
        31:
        

            IF NOT ls.r.fd THEN
                rd.md:=TRUE;
                s:=32;
            END_IF;
          ;
            
        32 :
        
            IF ls.r.fd THEN
                 ls.r.ms:=FALSE;
                 s:=33;

            END_IF;
          ;
         33 :
            IF rd.fs THEN
                 rd.md:=FALSE;
                 ls.r.full:=FALSE;
                 rd.full:=TRUE;
                 rd.busy:=FALSE;
                 ls.r.busy:=FALSE;
                 flag:=TRUE;
                 s:=0;
            END_IF;
          
        41  :
        
          
            IF  NOT ls.r.fs THEN
                rd.ms:=TRUE;
                s:=42;
            END_IF;
          ;
        42  :
            IF ls.r.fs THEN
                ls.r.ms:=FALSE;
                s:=43;
            END_IF;
          ;
            
        43  :
             IF rd.fd THEN
                 rd.ms:=FALSE;
                 ls.r.full:=FALSE;
                 rd.full:=TRUE;
                 rd.busy:=FALSE;
                 ls.r.busy:=FALSE;
                 s:=0;
            END_IF;
         
                 
        
         
                        
    END_CASE;

    

    
   
END_FUNCTION_BLOCK

vi ringrazio in anticipo.

Modificato: da Vito.M
Link al commento
Condividi su altri siti


Se il PLC va in stop per un errore in lettura o scrittura vuol dire che indicizza qualcosa che non esiste.

Visto che sei ancora studente e pieno di brio e voglia di imparare, impara a commentare maniacalmente il codice, altrimenti chi poi lo deve fare i salti mortali

Prova a imparare inoltre a debuggare un applicativo sezionando le varie chiamate e verificando i valori intermedi

Buon divertimento, detto da uno che per 6 anni i magazzini automatici li ha fatti per davvero (oramai 15 anni or sono)

pigroplc

Link al commento
Condividi su altri siti

ok,proverò con un debug dei valori intermedi.

Per quanto riguarda i commenti,di solito commento sempre il codice,queasta volta non l'ho fatto e sono stato castigato!

Link al commento
Condividi su altri siti

Aggiungo: non capisco cosa può indicizzare di "sbagliato".

Da quel che vedo l'errore sembra essere presente qui:

              my_l2r(ls:=mag.lc ,rd:=mag.q[ld].r[1],d:=false);
                  IF my_l2r.s=0 THEN
                        my_align.s:=1;            
                    s:=3;
                 END_IF;  
        3:      
        
                my_align(r:=mag.q[ld].r[1],d:=false);
                IF my_align.s=0 THEN
                    s:=4;
                END_IF;

in particolare alla fine di my_l2r.

Link al commento
Condividi su altri siti

  • 2 weeks later...

questo tipo di problema esiste quando si va a puntare ad una variabile che non e' caricata nel plc .

Il problema e' che non e' semplic etrovare il blocco dove c'e' l'errore , online col plc.

Ti consiglio di utilizzare il simulatore e caricarci il programmino , e poi andare sulla cpu online e nel buffer di diagnostica far scorrere tutti gli errori entranti e capire da li se ti dice il blocco esatto.

COl simulatore da piu informazioni , sembrerà strano ma e' cosi.

Poi con SCL, che uso spesso , devi iniziare a tagliare pezzi di codice per capire se qualche indice ti scappa .... sezionatore e rimettere insieme i pezzi

ciao

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...