Vai al contenuto
PLC Forum


Somma Byte Di Un Db In Scl


Fabio Gaeta

Messaggi consigliati

Salve a tutto. Essendo un nuovo utente vi ringrazio per tutti gli aiuti che potete fornirmi.

Ho la necessità in SCL, di cui non sono molto pratico, di eseguire la somma in byte di un'area di memoria di un DB. Mi serve per costruire un CRC di tipo somma.

Ho quindi la necessità, sapendo la lunghezza dell'area nel db della parola da scrivere di eseguire la somma.

Vorrei eseguire una funzione SCL parametrizzata con due valori in ingresso: un puntatore all'area di memoria da cui iniziare e numero (la grandezza dell'area di memoria). Quindi, a partire dall'area di memoria puntata eseguire la somma di N byte.

Sembra banale fatta in C, oppure altri linguaggi che conosco. In SCL, di cui non sono molto pratico, mi viene un pò difficile.

Vi ringrazio per l'aiuto

function int sum (*pointer char data, int number) {

int i;

int sum;

for (i=0, i<=number, i++) {

sum=data+sum;

}

return sum;

}

Link al commento
Condividi su altri siti


in SCL non ti conviene lavorare con i puntatori .lo scopo per cui e' stato progettato e quello di rendere la vita meno dura al programmatore quando deve eseguire calcoli o lavorare con strutture dati abbastanza complesse

Pur essendo un linguaggio struturato tendente al pascal , per come e' la sitnassi , o al C , non e' niente di tutot ciò. La libreria e le funzioni built_in sono abbastanza limitate per quanto si po ssa fare in ambito automazione di quel tipico ambiente di plc.

Puoi lavorare con array piu o meno complessi composti da dati definiti , array di array di strutture e/o strutture di array di array di strutture di array , tramite indici che sono in qualche modo puntatori mascherati

Non e' possibile usare le funzioni del C come malloc o creare locazioni di memoria dinamicamente

Pero' ci sono istruzioni , in scl , che ti permettono di lavorare con i puntatori a tipi di dati tipo byte , ANY , pointer ect

Per quanto riguarda la tua funzione che accetta come parametro in ingresso un puntatore a caratteri dovresti rivedere un po la sitnassi , ti consiglio di lavorare con varaibili globali definite si DB globali oppure locali .Nel secondo caso lo stack dei dati e' limitato e rischi che ti escan dei pasticci .Se vuoi lavorare con scl dichiari un db globale con array di caratteri o stringhe all'interno di esse .COn il tipo dati stringa stai attento perche il formato che usa siemens si mangia due byte alla fine di ogni stringa per cui creati una VAT , tabela delle variabili ed inizia a giocare con array di caratteri e stringhe e vedi cosa succede altrimenti rischi di perdere giornate inutilmente .....esperienza personale ;)

Per cui se usci scl , dimentica il C o altri linguaggi di programmazione e interpreta scl piu come un linguaggio di scripting per plc

Link al commento
Condividi su altri siti

ho eseguito il seguente programma scl e restituisce quello che volevo. In pratica ho costruito un CHECKSUM

Vi fornisco il codice così ne possiamo discutere

FUNCTION_BLOCK FB30
TITLE = 'CRCSUM'  
AUTHOR : 'GAETA'

VAR_INPUT
    nData   : ANY;  
    iLenght : INT;  
END_VAR
  
VAR_OUTPUT
    wCrcSum : WORD;  
END_VAR

VAR_TEMP
    I                   : INT;      // Contatore
    pDB                 : ANY;      // Puntatore al blocco dati
    DBAny AT pDB        : STRUCT    // Definizione struttura per il tipo di dati ANY
        S7Code          : BYTE;     // Codice per S7 = 0x10
        DataType        : BYTE;     // Codice per il tipo DB (0x02 = byte)
        Length          : INT;      // Fattore di ripetizione = Lunghezza send/receive
        DBNumber        : INT;      // Numero DB
        MemoryArea      : BYTE;     // Specifica l'area di memoria (0x84 = DB)
        ByteAddressMSB  : BYTE;     // Bits più significativo del byte
        ByteAddressLSB  : WORD;     // Bits meno significativo del byte  
    END_STRUCT;
    uAddr               : DWORD;    // Unione del puntatore per calcolare l'offset dell'indirizzo del byte
    union AT uAddr      : STRUCT    // Equivale a fare una unione in C
        ByteAddrLSBPad  : BYTE;     // Non usato 
        ByteAddrMSB     : BYTE;     // Bits più significativo del byte  
        WordAddr        : WORD;     // Bits meno significativo del byte   
    END_STRUCT;
    CRCData             : BYTE;     // Appoggio byte letto
    RetVal              : INT;      // Valore di ritorno della funzione BLKMOV
END_VAR

pDB := nData;
DBAny.DataType := B#16#02;
// Azzero le variabili
union.ByteAddrLSBPad := 0;
union.ByteAddrMSB := DBAny.ByteAddressMSB;
union.WordAddr := DBAny.ByteAddressLSB;
wCrcSum := 0;

FOR I := 0 TO iLenght DO
    // Punto al bit più significatico
    DBAny.ByteAddressMSB := union.ByteAddrMSB;
    // Punto al bit meno significativo
    DBAny.ByteAddressLSB := union.WordAddr;
    // Trasferisco il byte puntato nel DB alla variabile di appoggio
    RetVal := BLKMOV(SRCBLK := pDB, DSTBLK := CRCData);
    // Somma parziale
    wCrcSum := INT_TO_WORD(BYTE_TO_INT(CRCData) + WORD_TO_INT(wCrcSum));
    // Incremento di 8 bits per puntare al successivo byte
    uAddr := DINT_TO_DWORD(DWORD_TO_DINT(uAddr) + 8);  
END_FOR;

END_FUNCTION_BLOCK

Link al commento
Condividi su altri siti

se il tempo di esecuzione del programma , in generale , supera il tempo di watchdog specificato in configurazione hw allora il plc va in stop .Il plc deve elaborare dati provenienti da processi e impianti e rispondere entro un certo tempo ,

comunque in OB1 c'e' un parametro che ti dice quanto tempo ha impeigato il programma ad essere eseguito e se vedi che e' troppo alto (ovviamente fai un test dove fai girare solo la tua funzione ) puoi implementare una macchina a stati ed elaborare i tuoi dati a passi , uno o pu passi per ogni ciclo di scansione e sincronizzare il tutto al termine .

Bravo , finalmente qualcuno che lavora seriamente ed usa SCL ;)


comunque puoi sempre lavorare con un array di strutture dati , cioe tabelle .

Se poi il tipo di dato byte in SCL ti crea problemi usi gli interi e via

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