Vai al contenuto
PLC Forum


registro fifo


 ghismo1974

Messaggi consigliati

ciao. su un plc s7_300 dovrei creare un registro fifo per archiviare data ed ora nel momento in cui un bit si imposta.

nello screen allegato, l'ultima parola in lista e il valore date_time reale ; all'attivazione del mio bit specifico, data_ora devo passare nella prima parola, quello che era presente nella prima parola va nella seconda, quello che era presente nella seconda parola va nella terza etc.. sino ad arrivare in questo caso alla parola 24 ; quello che era nella parola 24 va perso.

Ho scritto un codice che sposta le parole una ad una, vorrei però perfezionare il tutto e scrivere il codice con i puntatori (di cui però non sono pratico). Chiede gentilemnte se qualcuno può aiutarmi con un'esempio. grazie mille a tutti. mandi.

2020-03-23 19_18_33-KOP_AWL_FUP  - [DB360 -- _DB BUFFER KW EVENTO_ -- CPU_317PN_HOME_20200117_CPU_31.png

Link al commento
Condividi su altri siti


Più che con AWL e puntatori, ti consiglierei di farlo in testo strutturato, e dichiarando un array di variabili.

A parte questo, c'è un modo più efficiente per gestire un registro FIFO. Col tuo metodo, ogni volta devi spostare tutti gli elementi. Nel tuo caso sono solo 24, ma pensa se dovessero essere molti  di più: il lavoro diventerebbe piuttosto pesante.
Molto meglio quindi gestire il registro tramite indici. Se parti con registro vuoto, l'indice vale 1 (o zero, a seconda di come dichiari l'array) ed andrai a scrivere il dato nel primo elemento dell'array. Ogni volta che devi scrivere un dato, incrementi l'indice e scrivi nell'elemento corrispondente. Quando arrivi all'ultimo elemento, riparti dal primo.
Cosa analoga per i dati che andrai ad estrarre dal registro.
In questo modo, non importa se il tuo registro è composto da 10 o da 1000 elementi: il lavoro da fare, sarà sempre il minimo indispensabile. 

Link al commento
Condividi su altri siti

Sì, SCL è come Siemens chiama il testo strutturato, come chiamano KOP il ladder, e FUP l'FBD. Cosa vuoi mai, sono tedeschi... ;-)
 

Link al commento
Condividi su altri siti

  • 2 weeks later...
Il 23/3/2020 alle 19:25 , battistella.roberto ha scritto:

ciao. su un plc s7_300 dovrei creare un registro fifo per archiviare data ed ora nel momento in cui un bit si imposta.

nello screen allegato, l'ultima parola in lista e il valore date_time reale ; all'attivazione del mio bit specifico, data_ora devo passare nella prima parola, quello che era presente nella prima parola va nella seconda, quello che era presente nella seconda parola va nella terza etc.. sino ad arrivare in questo caso alla parola 24 ; quello che era nella parola 24 va perso.

Ho scritto un codice che sposta le parole una ad una, vorrei però perfezionare il tutto e scrivere il codice con i puntatori (di cui però non sono pratico). Chiede gentilemnte se qualcuno può aiutarmi con un'esempio. grazie mille a tutti. mandi.

2020-03-23 19_18_33-KOP_AWL_FUP  - [DB360 -- _DB BUFFER KW EVENTO_ -- CPU_317PN_HOME_20200117_CPU_31.png

Se non ho capito male, ad ogni fronte di salita del bit desiderato, vorresti shiftare il contenuto della DB, inserendo il valore acquisito all'inizio?
Confermi?

Link al commento
Condividi su altri siti

Buongiorno.

 

Al link sottostante, trova un esempio stl come muovere i dati, che potrebbe fare al suo caso.

 

Appena trovo un po di tempo libero, farò anche la versione scl con any pointer.

 

Download

 

Saluti.

Modificato: da SHKODRAN
Link al commento
Condividi su altri siti

Buonasera.

 

Sotto la versione scl con any pointer.

Spero ti sia stato utile.

 

Saluti. 

FUNCTION_BLOCK FB601
TITLE =  'Shifiting 8 bytes data'
Name  :  'Shift'
AUTHOR : SHKODRAN
VERSION : '0.1'

   VAR_INPUT 
      Triger: BOOL;
      DB_SRC: INT;
      DB_DST: INT;
      IN_DT : DATE_AND_TIME;
   END_VAR

   VAR_OUTPUT    
   END_VAR

   VAR
     Trig_Old: BOOL;
     DT_TM   : ARRAY [0..23] OF DATE_AND_TIME;
   END_VAR

   VAR_TEMP
      PEdge  : BOOL;
      RETVAL : INT;
      LENGTH : INT;
      PNT_AR1: DINT;
      PNT_AR2: DINT;
      Source : ANY;
      Dest   : ANY;
      NEW_DT : ANY;
      
      IN AT NEW_DT :
   STRUCT                     // Diassembled ANY pointer structure
      INS7Code         : BYTE;   // Code for S7 (fixed at 16#10)
      INDataType       : BYTE;   // Code for data type
      INLength         : INT;    // Repetition factor = Send/receive length
      INDBNumber       : INT;    // Data block Number
      INMemoryArea     : BYTE;   // Specified memory area
      INByteAddressMSB : BYTE;   // Byte address most significant bits
      INByteAddressLSB : WORD;   // Byte address least significant bits
   END_STRUCT;
   
      Src AT Source :   
   STRUCT                     // Diassembled ANY pointer structure
      SrcS7Code         : BYTE;   // Code for S7 (fixed at 16#10)
      SrcDataType       : BYTE;   // Code for data type
      SrcLength         : INT;    // Repetition factor = Send/receive length
      SrcDBNumber       : INT;    // Data block Number
      SrcMemoryArea     : BYTE;   // Specified memory area
      SrcByteAddressMSB : BYTE;   // Byte address most significant bits
      SrcByteAddressLSB : WORD;   // Byte address least significant bits
   END_STRUCT;
   
      Dst AT Dest :   
   STRUCT                     // Diassembled ANY pointer structure
      DstS7Code         : BYTE;   // Code for S7 (fixed at 16#10)
      DstDataType       : BYTE;   // Code for data type
      DstLength         : INT;    // Repetition factor = Send/receive length
      DstDBNumber       : INT;    // Data block Number
      DstMemoryArea     : BYTE;   // Specified memory area
      DstByteAddressMSB : BYTE;   // Byte address most significant bits
      DstByteAddressLSB : WORD;   // Byte address least significant bits
   END_STRUCT;
   
   END_VAR


BEGIN
 
 // Positive edge detection
 
 PEdge := Triger AND NOT Trig_Old;
  Trig_Old := Triger;
   
   PNT_AR1 := 1536;   // Start offset * 8
    PNT_AR2 := 1600;  // End   offset * 8 
    
// Data shift from end to top  
      
    FOR LENGTH:= 0 TO 46 BY 1 DO
     IF PEdge THEN    
        Src.SrcS7Code := 16#10;
         Src.SrcDataType := 16#07;
          Src.SrcLength := 2;
           Src.SrcDBNumber := DB_SRC;
            Src.SrcMemoryArea := 16#85;
             Src.SrcByteAddressMSB := 0;
              Src.SrcByteAddressLSB := DINT_TO_WORD(PNT_AR1);
                
              
       Dst.DstS7Code := 16#10;
         Dst.DstDataType := 16#07;
          Dst.DstLength := 2;
           Dst.DstDBNumber := DB_DST;
            Dst.DstMemoryArea := 16#85;
             Dst.DstByteAddressMSB := 0;
              Dst.DstByteAddressLSB := DINT_TO_WORD(PNT_AR2); 
                 
       Retval := BLKMOV(SRCBLK:=Source, DSTBLK:=Dest);  
        PNT_AR1 := (PNT_AR1 - 32);
         PNT_AR2 := (PNT_AR2 - 32); 
   END_IF;           
  END_FOR;

// Write the new entry date&time  

   FOR LENGTH:= 0 TO 2 BY 1 DO 
    IF PEdge THEN      
        In.InS7Code := 16#10;
         In.InDataType := 16#07;
          In.InLength := 2;
           In.InDBNumber := DB_SRC;
            In.InMemoryArea := 16#85;
             In.InByteAddressMSB := 0;
              In.InByteAddressLSB := 48;
              
       Dst.DstS7Code := 16#10;
         Dst.DstDataType := 16#07;
          Dst.DstLength := 2;
           Dst.DstDBNumber := DB_DST;
            Dst.DstMemoryArea := 16#85;
             Dst.DstByteAddressMSB := 0;
              Dst.DstByteAddressLSB := 128; 
             
       Retval := BLKMOV(SRCBLK:=NEW_DT, DSTBLK:= Dest); 
       
       END_IF;
     END_FOR;  

END_FUNCTION_BLOCK

 

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...