Sergio Bertana
Risposte nei forum create
-
AutorePost
-
Sergio Bertana
Amministratore del forumDevi configurare come dispositivo server un dispositivo Modbus RTU, configurare la porta con i corretti parametri di comunicazione. Per al comunicazione multidrop dai una occhiata al capitolo Come definire nodo Modbus in comunicazioni RS485 e/o TCP multidrop ? nelle FAQs.
In pratica si indica il numero di nodo seguito dall’indirizzo della variabile, esempio 01#40016 (Nodo 1, variabile 40016), 02#40016 (Nodo 2, variabile 40016), …. Il numero di nodo và sempre indicato con 2 cifre.
Ora dovendo dare il comando di marcia e di stop contemporaneamente su più inverter credo che la soluzione più semplice sia realizzare una macro utilizzando la funzione SetData per trasferire il valore di una LW sull’inverter. Dovrai eseguire una SetData per ogni inverter. Ecco un esempio:
macro_command main() short Command GetData(Command, "Local HMI", LW, 10, 1) //Leggo valore LW 10 SetData(Command, "MODBUS RTU (Zero-based Addressing)", 3x, 01#8192, 1) //Comando inverter 1 SetData(Command, "MODBUS RTU (Zero-based Addressing)", 3x, 02#8192, 1) //Comando inverter 2 SetData(Command, "MODBUS RTU (Zero-based Addressing)", 3x, 03#8192, 1) //Comando inverter 3 SetData(Command, "MODBUS RTU (Zero-based Addressing)", 3x, 04#8192, 1) //Comando inverter 4 end macro_command
Se esgui la macro a tempo scrivendo nella LW 10 i valori di start e di stop gestisci tutti gli inverter. Nota che ho scelto il protocollo MODBUS RTU (Zero-based Addressing), che ha offsert 0 quindi l’indirizzo 2000H -> 8192 l’ho definito senza sommare 1. Ho scritto la macro senza testarla spero funzioni.
Sergio Bertana
Amministratore del forumPer gestire l’inverter da Modbus con i nostri PLC abbiamo realizzato il FB InvtGD20EU, che gestisce tutte le funzioni. Ma mi sembra di capire che tu vuoi gestirlo da un pannello operatore.
Al capitolo 7 del manuale inverter trovi tutte le informazioni sul protocollo Modbus e trovi anche la tabella con i registri su cui operare per gestire l’inverter da Modbus. Come puoi vedere nella tabella per comandare l’inverter in marcia devi impostare il valore 0001H nel registro Modbus 2000H il valore 0005H forza lo stop.
Per permettere la gestione da Modbus devi impostare alcuni registri ti rimando al capitolo Comando da Modbus di questo articolo. Naturalmente dovendo gestire più inverter dovrai realizzare una connessione multidrop in RS485 ed assegnare indirizzi di nodo diversi ad ogni inverter.
Poi sul pannello dovrai configurare la connessione ai singoli inverter e con un comando Modbus 16#06 Preset single register scrivere il valore desiderato nel registro 2000H di tutti gli inverter.
Attenzione all’offset sull’indirizzo gli indirizzi definiti sul manuale sono i reali indirizzi dei registri (Offset 0), il protocollo Modbus prevede l’offset di 1 sull’indirizzo, quindi se il pannello operatore gestisce correttamente l’offset per accedere al registro 2000H dovrai definire il registro 2001H.
Maggio 23, 2025 alle 8:16 am in risposta a: Come utilizzare gli I/O dei moduli CPU e di estensione #82407Sergio Bertana
Amministratore del forumNei ns sistemi come in tutti i PLC gli I/O sono gestiti in immagine di processo (Vedi articolo), quindi il sistema operativo riconosce i moduli presenti e provvede a gestire gli I/O mappandoli in datablock di memoria. Gli ingressi saranno indirizzabili con %IXaaa.bb e le uscite con QXaaa.bb dove
- aaa: Indica l’indirizzo del modulo da 0 a 15 (255 per il modulo CPU).
- bb: Indica l’I/O sul modulo.
Quindi il modo corretto è definire il nome dell’I/O mappandolo correttamente cone %IX o %QX. Esempio
- Start AT %IX0.1 : BOOL; (* Di 01 Module 0 *)
- Stop AT %IX0.2 : BOOL; (* Di 02 Module 0 *)
- Motor AT %QX255.0: BOOL; (* Do 00 CPU module *)
Esistono dei FB che permettono di gestire direttamente gli I/O sui moduli SysGetPhrDI e SysSetPhrDO, utilizzando questi FB lo stato dell’ingresso viene acquisito immediatamente e l’uscita viene settata immediatamente. Questi FB si utilizzano in casi particolari, quando ad esempio occorre acquisire velocemente un ingresso o gestire velocemente un’uscita eseguendone la gestione in task Fast che può essere eseguita ogni 1mS o anche più velocemente.
Il FB CPUModuleIO è un vecchissimo FB il cui uso è ormai deprecato da tempo.
Sergio Bertana
Amministratore del forumIl valore del tempo di esecuzione dei timer TON, TOF e TP è espresso nel formato TIME. Il formato TIME come indicato in questo articolo è un numero a 32 bits che rappresenta un tempo espresso in mS:
TIME Time expressed in milliseconds, range da -24d_20h_31m_23s_648ms a 24d_20h_31m_23s_647ms
Ora volendolo visualizzare sul pannello operatore basterà trasferire il valore di ET in uscita dal timer su di una variabile DINT allocata in DB100 per renderla accessibile da Modbus e poterla visualizzare sul terminale, in questo modo avrai il valore in mS se vuoi adattarlo potrai utilizzare la scalatura sul terminale. Ecco il programma ETOnHMI che esegue un TON con la visualizzazione sia del tempo trascorso TFromStart che del tempo che manca al termine TToEnd.
VAR OnDelay : TON; (* On time delay *) TFromStart AT %MX100.16 : DINT; (* Time from start *) TToEnd AT %MX100.20 : DINT; (* Time to end *) END_VAR OnDelay(IN:=NOT(OnDelay.Q), PT:=T#10s); //On time delay TFromStart:=TO_DINT(OnDelay.ET); //Time from start TToEnd:=TO_DINT(OnDelay.PT)-TO_DINT(OnDelay.ET); //Time to end
Nello screenshot la visualizzazione dei due tempi sul pannello operatore. Come si vede in LogicLab i tempi sono visualizzati nel formato TIME (7s10ms) mentre sul pannello il tempo e espresso in decimale 7040 (La diferenza di tempo è data dal tempo di campionamentro del valore da parte di LogicLab e del terminale).
Sergio Bertana
Amministratore del forumIniziamo con il precisare che purtroppo il simulatore di LogicLab non supporta gli streams di comunicazione, quindi non è possibile testare in simulazione le comunicazioni sia seriali che ethernet, e l’accesso al disco. Con il simulatore è possibile eseguire programmi logici testando il funzionamento di reti logiche e/o funzioni di calcolo matematico.
Per comunicare in Modbus sia RTU che TCP dovrai istanziare nel tuo programma il FB ModbusMaster, troverai molti esempi sia nella knowledge base che nel forum. Ma per testarlo devi necesseriamente utilizzare il modulo SlimLine.
Se ho capito il senso della tua domanda, vorresti poter provare il programma con la comunicazione Modbus collegandoti ad un dispositivo di prova e non ai componenti reali della cucina per poterti esercitare con la programmazione.
L’MPS050B020 dispone sia di una porta RS232 che di una porta RS485, quindi se per la programmazione ti colleghi via USB hai le due porte seriali libere e collegando alla porta seriale RS232 un convertitore RS232/RS485 puoi testare la comunicazione tra le due porte. Certo se avessi utilizzato un modulo CPU con interfaccia ethernet potresti testare la comunicazione direttamente in localhost senza fare connessioni tra porte.
Utilizzando le due porte seriali puoi istanziare il FB ModbusMaster su di una porta e interrogare i registri Modbus del sistema agli indirizzi a partire dal 40000 in avanti come indicato in questo articolo. Puoi anche istanziare il FB ModbusSlave sull’altra porta seriale e gestire gli indirizzi dei registri liberamente.
Quando poi testerai l’applicazione sul campo collegandoti ai dispositivi della tua cucina ti consiglio di utilizzare la console di spionaggio utilissima per individuare gli eventuali problemi di comunicazione.
Maggio 19, 2025 alle 2:32 pm in risposta a: Connessioni Rilevatore allagamento/Sensore livello SHV1 #82365Sergio Bertana
Amministratore del forumLa versione del Rilevatore allagamento/Sensore livello SHV1 che gestiamo ha le cconnessioni come indicato in figura.
Quindi l’alimentazione và connessa ai morsetti GND +Vcc, il sensore accetta sia ingresso in DC/AC da 15 a 24 volt.
Ai morsetti OUT RELAY è connesso il contatto NO del relè interno, lo stato dell’uscita può essere modificato spostando il jumper dalla posizione A alla posizione B.
- Posizione A: Il relè si eccita a contatto con il liquido, a contatto con il liquido OUT RELAY si chiude.
- Posizione B: Il relè si eccita immediatamente e si diseccita a contatto con il liquido, a contatto con il liquido OUT RELAY si apre.
Quindi visto che OUT RELAY è un contatto pulito valuta se è il caso di connetterlo ad un ulteriore relè in uscita.
Sergio Bertana
Amministratore del forumLa soluzione più economica che possiamo proporre è il modulo A-1812 Modulo I/O remoto Ethernet 2DI/4AI/2AO che dispone di 2 uscite analogiche. Il modulo supporta i comandi Modbus: 03/04/06/16 agendo sui registri 17 e 18 puoi impostare il valore di uscita con valori da 4 a 4000 ottieni in uscita da 0/4 a 20mA.
40017~40018 0~1 Current Output Value R/W R/W 0~4000:0/4~20mA
Con questo modulo non hai possibilità di “calibrare” il range di uscita sulla base del valore scritto nel regitro.
Se il calibrare il valore è una tua nessità, posso consigliarti uan soluzione basata su modulo CPU SlimLine MPS056B110 e muodulo di estensione uscita analogica PCB126C150 che ha 4 uscite 4-20mA. Naturalmente essendo un prodotto programmabile potrai agire a piacimento sul valore del registro per gestire l’uscita in corrente in base alle tue esigenze.
Il protocollo Modbus TCP/IP è nativo, con il FB SysSetAnOut puoi impostare il valore in uscita in base al valore definito da Modbus nel registro.
Sergio Bertana
Amministratore del forumSorry but i don’t understand your needs why you have to dynamically allocate the FBs. You need use them and then you destroy after use? and why you have to destroy them you need to save memory?
To obtain the same result as in the TWINCAT with LogicLab program you can write:
VAR SquareArea : REAL; (* Square area *) SquarePerimeter : REAL; (* Square perimeter *) RForm : Form; (* Reference to Form *) MySquare : Square; (* Square form *) END_VAR MySquare.Side:=10; //Square side RForm:=MySquare; //Reference to Form SquareArea:=RForm.Area(); //Square area SquarePerimeter:=RForm.Perimeter(); //Square perimeter
You simply static instantiate the objects and use them.
Sergio Bertana
Amministratore del forumIntato se vai alla pagina di definizione errori e cerchi l’errore 9951085, troverai l’indicazione “Terminato tempo utilizzo per FB protetta”. Quindi non hai definito correttamente la licenza per l’utilizzo dei PWM, per questo che terminato il tempo di funzionamento in demo hai il blocco di alcuni dei PWM in modo casuale.
Quindi la prima operazione è impostare correttamente la licenza, trattandosi di licenza DID verificare se il tipo di modulo e il numero seriale corrispondono al modulo CPU che stai utilizzando. Nel tuo programma non trovo la funzione SysPCodeVerify di impostazione licenza quindi immagino sia stata definita da pagina Web.
Guardando il file di log che hai inviato non vedo stranezze, dando una occhiata agli ultimi records vedo:
[16/05/2025 13:45:01.000] [L] SFW198[ 5003] MPS054C110-00488 power on [16/05/2025 13:45:01.000] [L] SFW198[ 5005] Starting Op. System SFW210B040 [16/05/2025 13:45:06.931] [L] SFR050[14025] Ethernet Link ok [16/05/2025 13:45:07.513] [L] SFW198[ 6000] Run ApplID:0x61FCA90C [19/05/2025 07:39:31.007] [L] SFW198[ 6010] Stop ApplID:0x61FCA90C [19/05/2025 07:39:33.715] [L] SFW198[ 6050] LogicLab executable download end [19/05/2025 07:39:36.168] [L] SFW198[ 6000] Run ApplID:0xF5BA33F9
L’ultima volta il sistema è stato acceso il 16/05 alle 13:45, poi al 19/05 alle 7:39 hai caricato il programma con LogicLab, la fase di caricamento esegue uno stop del programma e poi manda in esecuzione il programma indicandone il valore di HASH.
Maggio 19, 2025 alle 8:02 am in risposta a: Lettura dati seriale da dispositivo su pannello cMT #82334Sergio Bertana
Amministratore del forumLa domanda è molto generica, non dici di che tipo di protocollo dispone il tuo strumento di misura.
Se è uno dei protocolli gestiti nativamente dal pannello puoi fare riferimento Guida connessioni PLC per pannelli Weintek.
Se invece si tratta di un protocollo proprietario puoi utilizzare il Free protocol che ti permette da macro con le funzioni INPORT ed OUTPORT di ricevere ed inviare dati su qualsiasi interfaccia sia seriale RS232/485 che TCP/IP.
Se cerchi nel forum Free protocol puoi trovare informazioni utili, ti rimando a questo topic dove viene gestita una stampante. Oppure a questo topic dove è gestita una comunicazione TCP/IP.
Maggio 16, 2025 alle 3:56 pm in risposta a: Impostare da PLC su HMI l’indirizzo IP di comunicazione #82310Sergio Bertana
Amministratore del forumVisto che acquisendo nuovi indirizzi IP da un server DHCP sia il PLC che il pannello la comunicazione Modbus TCP non è più operativa, l’unica soluzione che posso proporre è di connettere l’HMI al PLC oltre che via ethernet anche con una connessione seriale. L’idea è di definire su HMI un nuovo Device/Server di tipo ELSIST MODBUS RTU che comunicherà in RS232 con il modulo PLC.
Tramite questa comunicazione Modbus RTU l’HMI potrà acquisire dal PLC l’indirizzo IP da assegnare alla connessione Modbus TCP che è la connessione principale quella in cui transita tutta la comunicazione tra HMI e PLC. Ipotizzando di avere due device nell’HMI avremo che il dispositivo Modbus TCP sarà il Local Device 4, i registri di definizione del suo indirizzo IP sono LW-9600, LW-9601, LW-9602, LW-9603, quindi per impostarli dovremo programmare un Data Transfer globale di un array di 4 variabili UINT dal PLC all’HMI (Screenshot).
In questo modo modificando i valori nell’array variamo l’indirizzo sull’HMI, per accettare la variazione occorre forzare la riconnessione del dispostivo 4, settando LB-10070. Per la sua attivazione ho realizzato una macro eseguita a tempo nell’HMI che alla variazione del valore nei registri di definizione indirizzo IP esegue il set del bit di force. La macro utilizza 2 LW nell’HMI (LW-0, LW-1) per salvare l’indirizzo IP attivo Ecco il listato.
// ============================================================================= // MACRO "ReconnectDevice" // ============================================================================= // La macro è eseguita a tempo, viene controllato valore 4 LW di definizione // indirizzo IP PLC a cui connettersi. Su variazione valore viene settato bit // LB-10070 forced to reconnect device 4 (ethernet) // ----------------------------------------------------------------------------- macro_command main() bool SBit=true short LWValue=0 unsigned int IPRead=0, IPMemo=0 // Si utilizzano 2 LW per salvare valore a 32 bits indirizzo IP. GetData(LWValue, "Local HMI", LW, 9600, 1) //Device 4's IP0 IPRead=LWValue GetData(LWValue, "Local HMI", LW, 9601, 1) //Device 4's IP1 IPRead=(IPRead*256)+LWValue GetData(LWValue, "Local HMI", LW, 9602, 1) //Device 4's IP2 IPRead=(IPRead*256)+LWValue GetData(LWValue, "Local HMI", LW, 9603, 1) //Device 4's IP3 IPRead=(IPRead*256)+LWValue // Leggo valore di IPMemo e confronto con valore IP letto. GetData(IPMemo, "Local HMI", LW, 0, 1) //IP memo if (IPRead <> IPMemo) then SetData(IPRead, "Local HMI", LW, 0, 1) //IP memo SetData(SBit, "Local HMI", LB, 10070, 1) end if end macro_command
Nel PLC SlimLine occorre realizzare un programma che trasferisce l’indirizzo IP nelle variabili acquisite dal data transfer dell’HMI. Conviene eseguire il programma in task Back, l’indirizzo IP potrebbe cambiare durante il funzionamento il server DHCP potrebbe inviare un nuovo indirizzo.
VAR i : UDINT; (* Auxiliary variable *) IPValue : ARRAY[0..3] OF BYTE; (* IP address value *) HMIIP AT %MW100.16 : ARRAY[0..3] OF UINT; (* HMI IP definition *) END_VAR // ***************************************************************************** // PROGRAM "SetHMIIPAddress" // ***************************************************************************** // Read some ETH0 informations. // ----------------------------------------------------------------------------- // ------------------------------------------------------------------------- // READ ETH0 INFORMATIONS // ------------------------------------------------------------------------- // Read the IP address and return it as a string. eTO_JUNK(SysOSIDValue(FALSE, OSID_ETH0_ACT_IP, ADR(IPValue))); FOR i:=0 TO 3 DO HMIIP[i]:=TO_UINT(IPValue[i]); END_FOR; // [End of file]
Sergio Bertana
Amministratore del forumVenendo al tuo programma vediamo le inesattezze, ce ne sono molte…
- Il TCPClient è sempre in connessione. Occorre connettersi solo quando si invia la eMail e sconnettersi al termine dell’invio. Se vedi nei ns esempi il comando di Connect è gestito dal FB di invio eMail TCPClient(Connect:=Mailer.Connect).
- Esegui un invio a raffica di tutti i comandi HELO, username, password. L’invio dei dati và fatto in risposta alle richieste del server.
- Terminato l’invio occore atendere l’Ok dal server e solo dopo inviare il comando di QUIT.
- Inviato il comando di QUIT occorre chiudere la connessione con il server.
- Ho visto che hai scritto SysFWrite e non Sysfwrite, siccome non hai errori di compilazione immagino che non hai settato il controllo maiuscole/minuscole nel progetto.
Riguardo all’errore:
i := Sysfwrite(Fp, ADR('EHLO smtp.office365.com' + CHR(13) + CHR(10)), Sysstrlen('EHLO smtp.office365.com' + CHR(13) + CHR(10)));
La funzione Sysfwrite, ha come 1° parametro l’indirizzo della stringa da inviare, come 2° parametro la lunghezza della stringa, come 3° parametro il numero di stringhe e come 4° parametro lo stream di comunicazione a cui inviare i dati. Quindi và scritta in questo modo:
eTO_JUNK(Sysfwrite(ADR('EHLO smtp.office365.com$r$n'), Sysstrlen(ADR('EHLO smtp.office365.com$r$n')), 1, Fp));
Ho sostituito i:= con la nuova definizione eTO_JUNK. Ho sostituito CHR(13) e CHR(10) con le rispettive codifiche $r e $n vedi articolo.
Attenzione alla capienza del buffer dello stream di comunicazione, nel TCP client hai definito il buffer di trasmissione a 256 caratteri ma la somma delle tue scritture Sysfwrite credo abbia dimensione maggiore quindi i caratteri che non ci stanno nel buffer vengono scartati.
Sergio Bertana
Amministratore del forumPer inviare l’eMail dal un sistema SlimLine devi utilizzare il FB EMailSend, puoi utilizzare l’esempio ST_EMailSend in fondo alla pagina. Colgo l’occasione della domanda per evidenziare alcuni punti.
- L’invio eMail senza crittografia TLS ormai non è quasi piu accettato dai servers SMTP, nel’esempio ho utilizzato Virgilio che sembra ancora accettare invio non crittografato.
- Per poter inviare eMail su qualunque server SMTP occorre utilizzare la crittografia come riportato nell’esempio ST_TLSEMailSend.
- In alternativa al FB SysTLSClient eseguire un programma mail relay su un PC, SlimLine invia al relay l’eMail non crittografata ed il relay l’inoltrerà al server pubblico crittografato.
- Per utilizzare come server di inoltro GMail occorre utilizzare la password generata dal servizio Password per le app. Rimando alla lettura di questa nota applicativa.
Sergio Bertana
Amministratore del forumI’ve rewritten your program in a form I supposed was correct but there’s two compiling errors.
VAR SquareArea : REAL; (* Square area *) SquarePerimeter : REAL; (* Square perimeter *) RectangleArea : REAL; (* Rectangle area *) RectanglePerimeter : REAL; (* Rectangle perimeter *) RForm : Form; (* Reference to Form *) MySquare : Square^; (* Reference to Square *) MyRectangle : Rectangle^; (* Reference to Rectangle *) END_VAR // Program initializations. IF (SysFirstLoop) THEN // MySquare:=SysMAlloc(SIZEOF(Square)); // MyRectangle:=SysMAlloc(SIZEOF(Rectangle)); MySquare^.Side:=10; //Square side MyRectangle^.Width:=20; //Rectangle width MyRectangle^.Height:=4; //Rectangle height END_IF; // Calculates area and perimeter. RForm:=MySquare^; //Reference to Form SquareArea:=RForm.Area(); //Square area SquarePerimeter:=RForm.Perimeter(); //Square perimeter RForm:=MyRectangle^; //Reference to Form RectangleArea:=RForm.Area(); //Rectangle area RectanglePerimeter:=RForm.Perimeter(); //Rectangle perimeter
I’ve to ask to Axel support how to manage this scenario.
I’ve a question, why you would dynamically instantiate the FBs? Is not easiest simply instantiate they in the data memory?
Maggio 15, 2025 alle 4:43 pm in risposta a: Invio eMail da dispositivo STE2 su server SMTP autenticato #82264Sergio Bertana
Amministratore del forumI prezzi sono visibili direttamente dal sito su registrazione, oltre ai prezzi è visibile anche la disponibilità del prodotto.
Il prodotto può inviare eMail su allarme senza bisogno di licenze, in questa nota applicativa si trovano le impostazioni per impostare come server SMTP di inoltro un qualsiasi account di GMail.
In aggiunta all’invio autonomo delle eMail il prodotto può essere connesso al portale HWg-Cloud senza bisogno di licenze mentre è prevista una licenza per il portale SensDesk (Vedi articolo).
-
AutorePost