Sergio Bertana
Risposte nei forum create
-
AutorePost
-
Sergio Bertana
Amministratore del forumMolte volte abbiamo pensato di realizzare un FB temporizzatore, ma sono talmente tante e varie le opzioni richieste che è impossibile soddisfarle tutte, così è più facile risolvere il problema scrivendo un programma ad-hoc. Ecco allora un semplice blocco funzione che gestisce una temporizzazione con orario di attivazione e disattivazione.
FUNCTION_BLOCK FB_DailyTimer VAR SysDTime : UDINT; (* Ora corrente del giorno *) END_VAR VAR_INPUT StartTime : TIME_OF_DAY; (* Ora inizio (es. T#8h10m20s) *) EndTime : TIME_OF_DAY; (* Ora fine (es. T#10h30m15s) *) END_VAR VAR_OUTPUT Output : BOOL; (* TRUE se attivo *) CurrentTime : TIME_OF_DAY; (* Ora corrente del giorno (es. T#15h10m5s *) END_VAR // Calcolo valore TIME_OF_DAY da orologio di sistema. SysDTime:=(MOD(SysDateLocalize(SysDateGetS(), +1, 1), 86400))*1000; eTO_JUNK(SwapData(ADR(CurrentTime), ADR(SysDTime), UDINT_TYPE, SWAP_COPY)); // Gestisco fascia oraria nello stesso giorno. IF (StartTime < EndTime) THEN Output:=(CurrentTime >= StartTime) AND (CurrentTime < EndTime); RETURN; END_IF; // Gestisco fascia oraria a cavallo della mezzanotte. Output:=(CurrentTime >= StartTime) OR (CurrentTime < EndTime); // [End of file]
Come puoi vedere dalla variabile di sistema SysDateTime che ritorna la data ora in epoch time ricavo CurrentTime di tipo TIME_OF_DAY, viene poi eseguita la comparazione con i valori di set ed attivata l’uscita di conseguenza. La funzione SwapData esegue unicamente la copia tra un valore UDINT ed un valore TIME_OF_DAY, l’uguglianza “:=” produce errore in quanto sono due tipi di dato disomogenei.
Avendo definito nella funzione SysDateLocalize di generazione tempo attuale il valore di TimeZone:=+1 e la DaylightZone:=1, si ha il tempo localizzato con il cambio automatico tra ora solare e legale, ma attenzione se gli orari sono impostati a cavallo del cambio ora si può accorciare o allungare la temporizzazione di un’ora. In alternativa si può impostare DaylightZone:=0.
Se occorrono più temporizzazioni nella giornata basterà istanziare più FB con tempi diversi ed eseguire il comando con la OR tra le uscite di tutte le FB.
Sergio Bertana
Amministratore del forumLa soluzione migliore è definire già nel progetto HMI gli stessi limiti limiti del PLC, impostandoli fissi o dinamici nelle varie introduzioni numeriche. Se utilizzi i limiti dinamici è il PLC stesso a definirli.
Se invece vuoi lasciare liberi ilimiti nella ricetta (Non è la soluzione che sceglierei) nel controllo effettuato dal PLC in caso di valore non coretto puoi attivare una variabile BOOL che forza il trasferimento della ricetta dal PLC al pannello.
Giugno 13, 2025 alle 10:37 am in risposta a: Trasferire al PLC il numero della ricetta in uso #82775Sergio Bertana
Amministratore del forumIl selection si può trasferire con una macro. Esempio leggo selection e trasferisco su LW50 del pannello:
macro_command main() short sel GetData(sel, "Local HMI", RECIPE, "aa.Selection") SetData(sel, "Local HMI", LW, 50, 1) end macro_command
Dovendolo trasferire sul PLC nella istruzione SetData al posto di Local HMI dovrai definire il PLC con i relativi parametri.
Sergio Bertana
Amministratore del forumI meters di energia come SDM120 e SDM630 sono accessibili tramite protocollo Modbus, se guardi nella pagina del prodotto troverai il link per il download elenco registri Modbus. Ti riporto per comodità i link, SDM120, SDM630.
Il protocollo Modbus è standard e ben documentato quindi utilizzando un qualsiasi programma di comunicazione Modbus puoi interrogare i registri del meters. Il problema è nel formato dati, come vedi dalla documentazione tutti i dati sono di tipo float a 32 bits (IEE754) quindi per poterli interpretare devi convertire i dati letti da Modbus. Ulteriore complicazione è nell’endianness, il protocollo Modbus non specifica l’endianness dei dati di grandezza superiore ai 16 bits, quindi acquisendo un valore a 32 bits occorre sapere chi dei due registri a 16 bit rappresenta l’MSW e chi l’LSW.
Se vedi l’esempio di questo articolo, dove utilizzando l’utility Modbus Master di Toolly vedi le operazioni da effettuare. Nell’esempio si imposta il Baud rate, che come vedi dalla tabella dei registri è indicato con indirizzo 40029. Tralascia il 4 iniziale che confonde, l’indirizzo del parametro baud rate è quindi 0029. Ma se vedi nel’indirizzo Hex da inviare è indicato 0x001C (Cioè 28). Questo perchè normalmente il Modbus ha offset 1 quindi và sottratto dall’indirizzo indicato.
Per accedere a questa serie di registri devi utilizzare i codici Modbus 0x03 e 0x10, Nell’esempio con Toolly, infatti vedi che per leggere il valore di baud rate ho utilizzato il comando 0x03. Il valore è indicato in float 32 bits e come vedi ho eseguito lo swap tra MSW e LSW.
Tutti i registri con i valori di energia invece sono accessibili solo in lettura anche qui tralascia il 3 iniziale, ma come vedi devi utilizzare il comando Modbus 0x04.
Tutto il lavoro sopra descritto viene realizzato utilizzando i nostri prodotti SlimLine dai FB EastronSDM120 e EastronSDM630.
Sergio Bertana
Amministratore del forumLa soluzione più semplice che possiamo proporre è di utilizzare
- Nr 1 HWPATC8731 ATC-873-S1 RS232 868MHz Radiomodem, da connettere al PLC
- Nr 1 HWPATC8732 ATC-873-S2 RS485 868MHz Radiomodem, da connettere al modulo I/O remoto.
- Nr 1 MPS056B110 Modulo PLC Compatto SlimLine, per la comunicazione col il modulo di I/O remoto e la gestione I/O logici.
- Nr 1 HWPYTC1055 A-1055S Modulo I/O remoto RS485 8DI/8DO, per gestione I/O logici.
In questa configurazione il PLC SlimLine utilizzando il FB YottaA1MMng può gestire in Modbus via radio il modulo di I/O remoto acquisendone gli ingressi e trasferendone lo stato sulle sue uscite e pilotando le uscite del modulo di I/O remoto con lo stato dei suoi ingressi.
Il vantaggio di avere una unità intelligente come il PLC per la gestione della comunicazione permette di gestire il controllo sullo scambio dati tra i due sistemi attivando procedure di errore nel caso di problemi nella comunicazione.
Nota: I due radiomodem vanno configurati come master e slave, per la configurazione eseguire il download del programma dal ns sito. Siccome la configurazione và eseguita collegando la porta seriale al PC occorre disporre sul PC di una porta seriale RS232 (Eventualmente un adapter USB) e di una porta seriale RS485 (Eventualmente un adapter USB). Se si vuole evitare di avere due radiomodem diversi è possibile utilizzare solo quello in RS232 ed un convertitore come questo.
Giugno 9, 2025 alle 10:34 am in risposta a: Connessione con inverter PowerFlex 525 Allen Bradley #82652Sergio Bertana
Amministratore del forumPer la connessione con protocollo Ethernet IP devi usare il protocollo ODVA, da verificare con l’inverter se in modalità implicita o esplicita.
Mentre per la connessione in RS485 ecco un estratto del manuale:
I convertitori di frequenza PowerFlex 520 possono essere collegati in multidrop su una rete RS485 utilizzando il protocollo Modbus in modalità RTU.
Quindi hai anche la possibilità di connetterli in seriale RS485 sia direttamente con il pannello Weintek che con un PLC SlimLine. Dipende dalla tua applicazione, collegandolo al PLC puoi con il FB ModbusMaster gestire completamente l’inverter dal PLC, il pannello potrà quindi essere connesso al solo PLC.
Giugno 5, 2025 alle 11:02 am in risposta a: Limite dimensione messaggi in ricezione e trasmissione con HTTPClient #82629Sergio Bertana
Amministratore del forumLa spiegazione magari è più chiara con un programma di esempio. Partendo dal programma ST_HTTPClient ho estratto la parte di comunicazione evidenziando come sia possibile tramite la funzione SysRMAlloc allocare un buffer da 4KBytes per i dati da inviare al server in POST ed un altro buffer da 4KBytes per contenere i dati ricevuti dal server.
La variabile Page da stringa è stata modificata in puntatore a stringa in modo da poter esserre utilizzata per definire l’indirizzo del buffer di ricezione dati di pagina dal server.
- CaseNr=0: Se i buffers sono allocati vengono disallocati e si inizializza il tempo di attesa.
- CaseNr=1: Si attende l’invio dei dati, e si allocano i due buffers di memoria. Siccome potrebbe non esserci memoria disponibile occoe attendere che si liberi memoria per l’allocazione dei buffers. Quando i due buffers sono allocati è possibile compilare la stringa da inviare al server. I buffers allocati sono sempre azzerati.
- CaseNr=2: Si controlla la ricezione di caratteri dal server e i caratteri ricevuti sono trasferiti nel buffer di pagina. Al termine della ricezione si ritorna al Case 0.
Ecco l’estratto del programma da sostituire nel programma ST_HTTPClient di questo articolo.
VAR Page : @STRING; (* Page string *) END_VAR // ------------------------------------------------------------------------- // PROGRAM SEQUENCIES // ------------------------------------------------------------------------- // Program sequencies. CASE (CaseNr) OF // --------------------------------------------------------------------- // Initialize the time to manage acquisition delay. 0: HTTPRq.Send:=FALSE; //Send request IF (HTTPRq.Request <> eNULL) THEN eTO_JUNK(SysRMFree(ADR(HTTPRq.Request))); END_IF; IF (Page <> eNULL) THEN eTO_JUNK(SysRMFree(ADR(Page))); END_IF; TimeBf:=SysTimeGetMs(); //Time buffer (mS) CaseNr:=CaseNr+1; //Program case // --------------------------------------------------------------------- // Wait delay time then initialize buffers and enable client. 1: IF ((SysTimeGetMs()-TimeBf) < TO_UDINT(T#5s)) THEN RETURN; END_IF; IF (HTTPRq.Request = eNULL) THEN IF NOT(SysRMAlloc(4096, ADR(HTTPRq.Request))) THEN RETURN; END_IF; END_IF; IF (Page = eNULL) THEN IF NOT(SysRMAlloc(4096, ADR(Page))) THEN RETURN; END_IF; END_IF; eTO_JUNK(SysVsnprintf(HTTPRq.Request, 4096, ADR('%s'), STRING_TYPE, ADR('Some text'))); eTO_JUNK(SysCVsnprintf(HTTPRq.Request, 4096, ADR('%s'), STRING_TYPE, ADR('More text'))); // ... More SysCVsnprintf to add data eTO_JUNK(SysCVsnprintf(HTTPRq.Request, 4096, ADR('%s'), STRING_TYPE, ADR('More text'))); HTTPRq.Send:=TRUE; //Send request CaseNr:=CaseNr+1; //Program case // --------------------------------------------------------------------- // Header/Page data are received from server by chunked. When a chunk // has been received DBChars returns its length. 2: IF ((HTTPRq.DBChars <> 0) AND HTTPRq.HPSelector) THEN IF ((Sysstrlen(Page)+HTTPRq.DBChars) < 4096) THEN eTO_JUNK(Sysmemmove(eTO_POINTER(Page)+Sysstrlen(Page), HTTPRq.DBAddress, HTTPRq.DBChars)); END_IF; END_IF; // The received page content could be used. IF (HTTPRq.Done) THEN CaseNr:=0; END_IF; END_CASE; // [End of file]
Giugno 5, 2025 alle 8:48 am in risposta a: Limite dimensione messaggi in ricezione e trasmissione con HTTPClient #82615Sergio Bertana
Amministratore del forumIniziamo con il dire che non c’è limite sulla dimensione dei dati che si possono inviare e/o ricevere in una comunicazione HTTP con il FB HTTPClient. Visto che per i dati in ricezione ti è chiaro come procedere e penso che il programma ST_HTTPClient_ToFile ne sia un esauriente esempio, vediamo come procedere per i dati da inviare al server.
Premesso che si si hanno molti dati da inviare è preferibile utilizzare una richiesta POST in cui i dati vengono inviati nel body senza limiti di lunghezza. Nelle richieste in GET i dati vengono passati nell’URL, che ha una lunghezza definita per ogni server, solitamente mi limito ai 256 caratteri. Ora vediamo il valore 512 a cui penso ti riferissi, negli esempi del FB HTTPClient vedi questo valore ripetuto più volte.
TCPClient.RxSize:=512; //Rx buffer size TCPClient.TxSize:=512; //Tx buffer size HTTPRq.DBSize:=512; //Data buffer size
Nel TCPClient, è definita la dimensione dei buffers Rx e Tx, un pacchetto TCP tipico trasporta fino a 1460 byte di dati, quindi si potrebbero definire questi buffer pari a questa dimensione. Solitamente utilizzo la dimensione 512 per non allocare troppa memoria RAM, il protocollo TCP negozia la quantità dei dati da trasferire in ogni pacchetto dimensionandola alla dimensione buffer. Quindi i dati da ricevere/trasmettere su protocollo TCP saranno frazionati in tanti pacchetti pari alla dimensione definita.
Nel HTTPClient è definita la dimensione del buffer di appoggio per trasmissione/ricezione dati verso stream di comunicazione (TCPClient) l’indirizzo è trasferito in DBAddress. Il FB compone i dati da inviare in questo buffer e poi li invia allo stream definito in File. I dati ricevuti dallo stream sono trasferiti nel buffer e la dimensione dei dati ricevuti è trasferita in DBChars in modo da permettere al programma utente di leggerli.
I dati da inviare al server vanno scritti in un buffer di memoria il cui indirizzo và definito in Request, attivando Send il FB provvederà ad inviare la richiesta inviando la stringa presente nel buffer. Siccome i sistemi SlimLine non hanno molta memoria RAM ipotizzando di dover inviare 4kBytes di dati conviene utilizzare la funzione SysRMAlloc per allocare il buffer, memoria che sarà disallocata al termine dell’invio. L’invio verrà sudiviso in pacchetti di dimensione pari al valore più piccolo tra quelli definiti in DBSize e TxSize.
Sergio Bertana
Amministratore del forumAggiungo una foto in cui evidenzio il ponticello da rimuovere per escludere il filtro EMC presente nell’inverter della famiglia GD270.
Sergio Bertana
Amministratore del forumNon tutte le ciambelle escono con il buco…
Con l’ultima versione di LogicLab il termine STEP è diventato un termine riservato quindi non è più possibile utilizzarlo negli oggetti di libreria, purtroppo nella raccolta di librerie versione Pck055A040 nel FB AESDecryption vi è proprio un parametro nominato Step, l’argomento è stato trattato in questo topic.
E se il tuo progetto non ha attivata la distinzione tra i termini scritti in minuscolo da quelli scritti in maiuscolo Step è uguale a STEP, ed ecco che si genera l’errore:
AESDECRYPTION(H:13) - error C4113: Step => Invalid name
Per eliminare l’errore puoi attivare la distinzione tra minuscole e maiuscole nel tuo progetto, ma se non hai definito correttamente tutte le variabili questo potrebbe generarti altri errori. In alternativa puoi eseguire il download della nuova versione beta del package PCK055a05_ in cui è stato corretto il problema e sostituirlo alla raccolta librerie definita nel tuo progetto.
Sergio Bertana
Amministratore del forumPurtroppo c’è un BUG nella distribuzione del LogicLab ci siamo dimenticati di inserire nell’elenco delle compatibilità tra i prodotti il modulo MPS056.
Per fortuna il workaround è molto semplice, aperto il progetto dal menù Project->Select target puoi selezionare il modulo SlimLine MPS054 XUnified.
Confermata la richiesta il progetto verrà convertito per la nuova architettura XUnified. A questo punto è possibile nuovamente dal menù Project->Select target selezionare il target desiderato (Screenshot).
Eseguita la conversione consiglio di rimuovere tutte le librerie standard incluse nel progetto tranne le librerie di tua realizzazione (Nell’esempio è stata eliminata la libreria eLLabUtyLib_C040), nella conversione viene già automaticamente inclusa l’ultima versione del package di librerie. Siccome si tratta di un progetto XTarget che deve essere eseguito su di un sistema XUnified come indicato in questo articolo occorre anche includere la libreria eLLabXUnifiedAdjLib (Screenshot). Nel caso in cui nella finestra di output compaiano voci del tipo:
warning P2086: eLLabStdLib: CTD => Object is already defined in the project and will be unloaded
Significa che nel tuo progetto avevi incluso oltre a librerie standard anche degli oggetti come si vede dallo screenshot, quindi la warning stà ad indicare che verrà utilizzato l’oggetto incluso nel progetto e scartato l’oggetto presente nella raccolta librerie. Se vuoi utilizzare quello presente nella raccolta librerie puoi eliminare gli oggetti dal tuo progetto ed eseguire il comando Project->Refresh all libraries.
Ora puoi ricompilare il progetto e trasferirlo sul tuo nuovo sistema target.
Sergio Bertana
Amministratore del forumSe c’è connessione Internet allora non ci sono problemi.
Se si utilizza il dispositivo STE2 è possibile definire il nome dell’ingresso ed il messaggio per la condizione di aperto e di chiuso (Screenshot).
SE si utilizza il sistema SlimLine l’unico limite è la fantasia, puoi comporre qualsiasi messaggio, magari anche allegando i dati da un file di log, vedi il programma ST_SendFileByEMail nella pagina di descrizione FB.
Sergio Bertana
Amministratore del forumL’acquisizione di temperatura da termocoppia è possibile con il Modulo di espansione I/O Analogici.
Come vedi dalla pagina del prodotto esistono 2 versioni di moduli uno che può acquisire fino a 4 termocoppie ed uno che ne può acquisire fino ad 8. Naturalmente se ti occorrono più ingressi puoi utilizzare più moduli.
Per l’acquisizione della temperatura si utilizza il FB SysGetAnInp, indicando in Mode il tipo di termocoppia da acquisire. Il FB ritorna una variabile REAL con l’indicazione della temperatura in gradi Celsius. Di seguito un esempio di acquisizione in gradi Celsius e Fahrenheit.
VAR Celsius : REAL; (* Celsius temperature (°C) *) Fahrenheit : REAL; (* Fahrenheit temperature (°F) *) AInp : SysGetAnInp; (* Analog input acquisition *) END_VAR AInp.Address:=0; //Module address AInp.Channel:=0; //Module channel AInp.Mode:=AI_MODE#AD_THERMOCOUPLE_J; //Acquisition mode AInp(); //Analog input acquisition IF (AInp.Done) THEN Celsius:=AInp.Value; //Celsius temperature (°C) Fahrenheit:=((AInp.Value*1.8)+32.0); //Fahrenheit temperature (°F) END_IF; // [End of file]
Sergio Bertana
Amministratore del forumAbbiamo due soluzioni…
- Dispositivo HWg-STE2 R2/Plus, il dispositivo oltre alla acquisizione di temperatura (Con sonda compresa) e di altre grandezze fisiche tramite sonde opzionali dispone di 2 ingressi digitali. Su attivazione/disattivazione ingresso è possibile inviare una eMail a fino 5 destinatari. Il messaggio della eMail è preconfezionato è possibile solo definire una stringa di definizione ingresso.
- Utilizzare un sistema SlimLine, questo è un dispositivo programmabile che dispone di 6 ingressi digitali, tramite LogicLab è possibile programmarlo per soddisfare le proprie esigenze. Il FB EMailSend permette di inviare la eMail secondo le proprie esigenze.
Sul sito c’è ethernet ma non specifichi se è presente una connessione Internet che è una condizione indispensabile per inviare l’eMail.
In questo topic una interesante discussione sull’invio di eMail da programma LogicLab.
Sergio Bertana
Amministratore del forumIl RUT14x è nato proprio per questa esigenza, in pratica per ottenere quello che desideri dovrai:
- Configurare l’interfaccia LAN con la classe di rete (IP, Mask) dei tuoi dispositivi di controllo (PLC, azionamenti, ecc). Dovrai definire come gateway dei tuoi dispostivi l’IP configurato sulla LAN del RUT14x.
- Configurare l’interfaccia WAN con la classe di rete (IP, Mask) su un indirizzo di rete libero del cliente. Consiglio di non utilizzare il client DHCP ma di definire un IP statico.
- Abilitare forwarding tra WAN->LAN per permettere alle connessioni in ingresso da rete aziendale di raggiungere i dispositivi sul’limpianto
- Abilitare forwarding tra LAN->WAN per permettere ai dispositivi sull’impianto di raggiungere i dispositivi IP della rete aziendale e di conseguenza Internet. Non abilitarlo se il cliente non vuole che i dispositivi su impianto raggiungano la rete.
Con questa soluzione se setti un route map sui PC connessi alla WAN potrai raggiungere direttamente i dispositivi di controllo con i loro indirizi IP. Esempio la rete del cliente ha classe 192.168.0.1/24, i tuoi dispositivi di controllo hanno classe 10.0.0.1/24, l’indirizzo IP settato sulla rete WAN è 192.168.0.10, basterà sul PC definire un route map del tipo:
route add 10.0.0.0 mask 255.255.255.0 192.168.0.10
Ora dal PC potrai pingare tutti i tuoi dispositivi direttamente con il loro indirizzo IP. Questa soluzione sicuramente funziona con tutte le comunicazioni ethernet non sono sicuro funzioni con Profinet.
Il router inoltre supporta ZeroTier oltre a altre VPN come OpenVPN in questo modo se è connesso ad Internet potrai raggiungere da Internet tutti i dipositivi per la teleassistenza.
-
AutorePost