Risposte nei forum create
-
AutorePost
-
Febbraio 15, 2019 alle 3:40 pm in risposta a: Definizione di costanti utilizzabili nel programma #46674
Sergio Bertana
Amministratore del forumAnche se è possibile dichiarare una variabile mappata in memoria accessibile da Modbus come costante, non sarebbe comunque impedita la scrittura della stessa da Modbus.
Siccome il protocollo Modbus viene gestito in Back prima di iniziare l’esecuzione dei programmi utente, se non vuoi che l’eventuale modifica da modbus sia vista dal programma (Ma questo vale solo per i programmi eseguiti in Back) puoi eseguire come prima operazione la valorizzazione della variabile con il valore costante che deve avere.
Sergio Bertana
Amministratore del forumQuesto programma può essere un suggerimento
VAR EpochTime : UDINT; (* Epoch time *) TimeBf : UDINT; (* Time buffer (uS) *) Milliseconds : UDINT; (* Tempo in mS *) TimeDf : UDINT; (* Time difference (uS) *) TimeSetup : BOOL; (* Setup time *) END_VAR IF (TimeSetup) THEN TimeSetup:=FALSE; //Setup time EpochTime:=SysDateTime; //Time reference (Epoch) TimeBf:=SysGetSysTime(TRUE); //Time buffer (uS) Milliseconds:=0; //Tempo in mS END_IF; TimeDf:=SysGetSysTime(TRUE)-TimeBf; //Time difference (uS) IF (TimeDf >= 1000) THEN TimeBf:=SysGetSysTime(FALSE)-(TimeDf-1000); //Time buffer (uS) Milliseconds:=Milliseconds+1; //Tempo in mS IF (Milliseconds >= 1000) THEN Milliseconds:=Milliseconds-1000; //Tempo in mS EpochTime:=EpochTime+1; //Time reference (Epoch) END_IF; END_IF;Su comando TimeSetup setto EpochTime con tempo di sistema (Ma potrei sincronizzarlo ad esempio con un server NTP) e poi ogni 1 mS incremento il valore di Milliseconds ed ogni secondo il valore di EpochTime. Nota la riga:
TimeBf:=SysGetSysTime(FALSE)-(TimeDf-1000);
La chiamata SysGetSysTime(FALSE) ritorna lo stesso valore ritornato alla precedente chiamata SysGetSysTime(TRUE), eseguendo la differenza (TimeDf-1000) tengo conto dell’errore sul controllo del tempo per compensare il tempo di jitter sulla esecuzione del programma (Download programma mSecTime).
Sergio Bertana
Amministratore del forumLo scenario descritto funziona senza problemi, puoi acquisire in task Fast il blocco degli ingressi (Senza debouncing) ed utilizzare i due ingressi in immagine di processo con il debouncing.
Naturalmente nell’immagine di processo saranno trasferiti tutti i 16 ingressi e potresti leggerli tutti con il debouncing in immagine di processo e senza debouncing in task Fast. Ma se non ti servono puoi assegnare uno mnemonico solo ai 2 che ti interessano.
Sergio Bertana
Amministratore del forumSi lo puoi fare, ecco un suggerimento, nella lista allarmi nel menu messaggio puoi associare un valore ad ogni allarme (o gruppi se uguale), quindi associare una variabile anche locale del pannello all’indirizzo riconoscimento nel visualizza allarmi e/o eventi.
A questa variabile puoi quindi associare un Oggetto->Pagina->Pagina indiretta, cosi facendo quando l’operatore preme su una riga del display dove è presente un allarme viene preso il valore associato a tale allarme e quindi scritto nella variabile di riconoscimento attivando la pagina indiretta con tutto quello che ti può servire di aggiuntivo. Per chiuderla basta rimettere a 0 la word di riconoscimento. Sperando di essere più chiaro ti allego alcuni screenshots.
Sergio Bertana
Amministratore del forumIn questo topic trovi alcune informazioni e links verso altri topics utili. Ma in merito al tuo problema, ipotizzando di salvare ogni 100 mS un record del tipo HH/MM/SS,m VV.VVV; avresti una 20 di caratteri ad ogni salvataggio che ammontano a 200 al secondo 720Kbytes all’ora oltre 17Mb al giorno.
Per evitare di avere file troppo grandi ti consiglierei di creare un file per ogni ora e magari di mettere nel file solo i dati nominando il file con il valore di ora. Ad esempio nel programma SimplyLogger (Stampa) è stato fatto qualcosa di molto simile a quello che ti serve (Download programma).
Sergio Bertana
Amministratore del forumPurtroppo la porta LAN2 del pannello non può far transitare dati verso la porta LAN1, ora se vuoi che il PLC possa connettersi ad Internet ed eventualmente collegarsi lui stesso ad un server NTP lo dovresti connettere alla stessa rete connessa alla porta LAN1 (Utilizzando uno switch).
In alternativa puoi utilizzando l’oggetto DataTransfer a base tempo del pannello trasferire i valore di data/ora dal pannello al PLC proprio come indicato nei posts precedenti di questo topic.
Sergio Bertana
Amministratore del forumRedando il manuale abbiamo utlizzato il file di descrizione della nuova versione del sistema operativo, versione a cui stiamo lavorando da un pò…
Così per errore ci siamo ritrovati con un manuale che riporta informazioni più nuove rispetto a quelle atttualmente disponibili. Purtroppo non ho ancora una previsione sulla data di rilascio della nuova versione del sistema opearativo.
Sergio Bertana
Amministratore del forumNon ho l’inverter ma utilizzo un nostro sistema SlimLine connesso in ethernet con protocollo Modbus TCP, ed ho fatto la stessa tua prova. Ecco la mia macro
macro_command main()
unsigned int Hzinverter
float HZGetData(Hzinverter, “SlimLine”, 3x, 40008, 1)
HZ=Hzinverter
HZ = HZ/100
SetData(HZ, “Local HMI”, LW, 210, 1)
end macro_commandCome vedi unica differenza è l’indirizzo di lettura della variabile Hzinverter.
Però nota che ho appoggiato il valore Hzinverter nella variabile HZ (Di tipo float) prima della divisione in questo modo considero anche i decimali. Se eseguo subito la divisione per 10o sul valore intero come hai fatto tu si perdono i decimali. Ecco lo screenshot del programma MacroTest simulato, ti allego anche il progetto con i sorgenti.
Sergio Bertana
Amministratore del forumIn effetti in Toolly viene detto di rimuovere il jumper e non di posizionarlo in OFF. Ma la posizione di OFF in realtà consiste in due pin non connessi ad alcun segnale che sono stati posti solo come magazzino di appoggio del jumper.
Quindi il rimuoverlo o il posizionarlo su OFF si equvalgono funzionalmente.
Febbraio 4, 2019 alle 2:18 pm in risposta a: Inviare dati JSON in GET o POST ad un servizio REST #46559Sergio Bertana
Amministratore del forumLa domanda è un pò fuori topic, qui stiamo parlando di inviare e ricevere stringe JSON dal PLC che agisce come client (Agisce come un browser) verso un servizio REST che è un server HTTP.
A te invece serve che il PLC agisca da server HTTP ed il tuo SCADA è un client, in questo caso puoi utilizzare la tecnica delle pagine dinamiche vedi questo topic.
Anche se solitamente gli SCADA dialogano con i PLC con protocolli di comunicazione diversi, e noi a questo scopo gestiamo standard il protocollo Modbus.
Sergio Bertana
Amministratore del forumSul manuale di EasyBuilder sono riportate tutte le possibilità offerte dal linguaggio macro (Estratto manuale). Nel tuo caso la funzione POW esegue quello che ti serve, ecco l’estratto del manuale.
POW(source1, source2, result)
Calculate source1 to the power of source2.
source1 and source2 can be a constant or a variable.
result must be a variable.
source1 and source2 must be a nonnegative value.Sergio Bertana
Amministratore del forumLa funzione SysRMAlloc è disponibile sia sui sistemi basati su ARM che sui sistemi basati su Cortex.
Sui sistemi ARM (Software SFW184****) si hanno a disposizione 16KBytes di memoria, sui sistemi Cortex (Software SFW198****) si hanno a disposizione 32KBytes di memoria. Ricordo che l’area di memoria è utilizata anche dal sistema operativo quindi la dimensione disponibile per il programma utente è una parte della memoria totale.
Sui sistemi ARM dalla versione SFW184B090, e sui sistemi Cortex dalla versione SFW198C000 la funzione SysRMalloc provvede automaticamente ad inizializzare a 0 la memoria allocata.
Sergio Bertana
Amministratore del forumLa visualizzazione delle cifre decimali non è dinamica, quindi la soluzione più veloce è usare una macro, leggere i 2 valori e poi in base al valore di scala dividere per 10-100-1000 ecc… quindi visualizzare il risultato.
Sergio Bertana
Amministratore del forumUn’idea che mi viene in mente è gestire un ricettario per ogni sottoprogramma e poi nel ricettario di commessa andranno caricati i riferimenti ai vari sottoprogrammi.
Però per fare questo devi operare con le macro, non c’è la possibilità di farlo direttamente dalla gestione del ricettario.
Gennaio 28, 2019 alle 1:10 pm in risposta a: Inviare dati JSON in GET o POST ad un servizio REST #46516Sergio Bertana
Amministratore del forumIl FB RESTClient non è trasparente, il FB aggiunge ai dati delle ulteriori informazioni che sono utilizzate per controllare il dialogo con il server. In pratica viene aggiunto un identificativo di messaggio una versione di messaggio ed il numero di reinvio in caso di errore.
Ma quello che ti serve lo puoi tranquillamente realizzare utilizzando il FB HTPClient che può gestire sia richieste GET che PUT e POST. Ma attenzione al momento non è gestito l’https, quindi se il server REST accetta anche richieste HTTP lo puoi sicuramente gestire. Ecco un esempio di richiesta GET:
HTTPRq.Method:=0; (* Request method, GET *) HTTPRq.HostAddress:=ADR('webhook-service.photoforse.online'); (* Main coordinator *) HTTPRq.HostName:=HTTPRq.HostAddress; (* Hostname *) HTTPRq.HostPort:=80; (* Server port *) HTTPRq.Page:=ADR('webhooks/custom/6eb07212-b85c-4ca1-866f-0521e3af07b9'); (* Web page *) HTTPRq.Request:=ADR('idAzienda=1$26idOrdine=12345'); (* Request string *) HTTPRq.DBSize:=256; (* Data buffer size *) HTTPRq.Timeout:=10000; (* Execution timeout *) -
AutorePost