Vai al contenuto
PLC Forum


Da Puntatori A Db


Frank681

Messaggi consigliati

Non ho a disposizione l'hardware per provarlo.

Inoltre si tratta di un esempio molto grezzo (non c'è controllo dettagliato sugli errori, per esempio) e basato sulle esigenze specifiche di Frank681.

Se pensi possa essere interessante lo stesso, nessun problema a renderlo pubblico.

Magari dopo la conferma da Frank681 che funziona ;)

Link al commento
Condividi su altri siti


Ciao Ragazzi per ne non è un problema postarlo , se mi dite come si fa , oppure se Batta può farlo lui.

E' un semplice esempio di lettura dati da un gateway / convertitore MOdbus RTU / TCP per acquisire dati energetici da strumenti di analisi , correnti , tensioni , cosf , KW , KVar , contatori e altro ,l e portarli poi in un 1200 che li rende disponibili ad uno SCADA WinCC.

Grazie di nuovo a Batta , sempre disponibile per una discussione in merito.

:thumb_yello::smile::worthy:

Link al commento
Condividi su altri siti

Domani vedo di convertirlo in testo strutturato (secondo me più adatto del KOP per queste cose), elimino le istruzioni particolari del caso in questione, in modo da fare qualcosa di generico, e posto il codice.

Link al commento
Condividi su altri siti

Ecco qui il codice in SCL.

Da tenere presente che si tratta solo di un esempio, con alcune particolarità dettate dalle attuali necessità di Frank681 (vedi modo impostazione numero nodo) e senza diagnostica dello stato della comunicazione.

Si deve creare il DB "MOD_TCP_PARK" (non ottimizzato) con la struttura "PRK" che deve essere abbastanza grande da contenere il numero di registri letto (nell'esempio, 50 registri a 16 bit).

Si deve creare il DB "MOD_TCP_RDATA" con un array di strutture "Device" identiche a "PRK".

Risulta comodo a tale scopo creare un "Tipo di dati" da dichiarare nelle strutture.

//Controllo limiti step comunicazione
IF "MB_TCP_STATUS".STEP_TCP < 1 OR "MB_TCP_STATUS".STEP_TCP > "MB_TCP_STATUS".STEP_TCP_MAX THEN
    "MB_TCP_STATUS".STEP_TCP := 1;
END_IF;

//Imposta nodo dispositivo
//N.B.: in questo esempio si stanno leggendo dati utilizzando un gateway Modbus TCP --> Modbus RTU.
//L'indirizzo IP rimane quindi invariato (quello del gateway), e si deve impostare
//il parametro MB_UNIT_ID col numero di nodo del dispositivo Modbus RTU.
//In caso di normale utilizzo di Modbus TCP, MB_UNIT_ID non va usato. Si deve invece
//impostare il quarto ottetto dell'indirizzo IP del dispositivo.
CASE "MB_TCP_STATUS".STEP_TCP OF
    1:
        "MB_CLIENT_DB".MB_UNIT_ID := 18;
    2:
        "MB_CLIENT_DB".MB_UNIT_ID := 20;
    3:
        "MB_CLIENT_DB".MB_UNIT_ID := 50;
    4:
        "MB_CLIENT_DB".MB_UNIT_ID := 30;
END_CASE;


//Lettura dati
//I dati letti vengono sempre depositati in un'area di "parcheggio" PRK.
//Quest'area deve essere una struttura o un array di un DB "non ottimizzato".
//Se la lettura è terminata in modo corretto, i dati vengono successivamente
//trasferiti nella loro destinazione definitiva.
//La destinazione deve essere una struttura o un array identico a quello di "parcheggio".
//In questo esempio, la destinazione è un array di strutture identiche a PRK.
//In alternativa, si potrebbero depositare i dati direttamente nella destinazione
//definitiva. In questo caso, il DB ""MOD_TCP_RDATA" dovrebbe essere "non ottimizzato".
//
"MB_CLIENT_DB"(REQ := "MB_TCP_STATUS".REQ,
               DISCONNECT := false,
               CONNECT_ID := 1,
               IP_OCTET_1 := 192,
               IP_OCTET_2 := 168,
               IP_OCTET_3 := 1,
               IP_OCTET_4 := 110,
               IP_PORT := 502,
               MB_MODE := 0,
               MB_DATA_ADDR := 40001,
               MB_DATA_LEN := 50,
               DONE => "MB_TCP_STATUS".DONE,
               BUSY => "MB_TCP_STATUS".BUSY,
               ERROR => "MB_TCP_STATUS".ERROR,
               STATUS => "MB_TCP_STATUS".STATUS,
               MB_DATA_PTR := "MOD_TCP_PARK".PRK);

//SET richiesta lettura
//Attivare la richiesta lettura dopo il richiamo di MB_CLIENT, in modo che
//MB_CLIENT legga per una scansione lo stato FALSE di REQ
"MB_TCP_STATUS".REQ := TRUE;

//Lettura andata a buon fine: copia dati da "Parcheggio" a destinazione definitiva
IF "MB_TCP_STATUS".DONE THEN
    "MOD_TCP_RDATA".Device["MB_TCP_STATUS".STEP_TCP] := "MOD_TCP_PARK".PRK;
END_IF;

//Lettura andata a buon fine o terminata con errore: incrementare Step e resettare REQ
IF "MB_TCP_STATUS".DONE OR "MB_TCP_STATUS".ERROR THEN
    "MB_TCP_STATUS".STEP_TCP := "MB_TCP_STATUS".STEP_TCP + 1;
    "MB_TCP_STATUS".REQ := FALSE;
END_IF;
Modificato: da batta
Link al commento
Condividi su altri siti

Giuseppe Signorella

Ottimo lavoro come al solito. :thumb_yello:

Ho inserito il link tra gli esempi di programmazione.

Modificato: da Giuseppe Signorella
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...