Mykola Posted July 2 Report Posted July 2 Buongiorno a tutti. Scusate se faccio qualche errore grammaticale, non sono madrelingua italiano. Sono nuovo nel settore della programmazione PLC e sto lavorando al mio primo progetto che riguarda l’automazione di 7 pompe tramite il protocollo Modbus RTU. Ho scritto in modo semplice la lettura e scrittura dei registri di ogni softstarter delle pompe, creando una catena di richieste: cioè, utilizzando l’uscita del blocco funzione ModRtuMast relativo all’ultimo dispositivo con la condizione NOT Busy OR Done per attivare l’ingresso Execute della prima richiesta di lettura dei registri a 16 bit; successivamente, con la stessa condizione, attivavo il blocco ModRtuMast per la scrittura di 32 coil dello stesso softstarter. Poi ripetevo la lettura e scrittura per il softstarter successivo, e così via. Quando facevo delle prove avevo soltanto un softstarter e tutto sembrava funzionare correttamente, ma quando ho provato nell’impianto reale con 7 softstarter ho iniziato a ricevere degli errori di comunicazione. Il PLC e i softstarter sono della marca ABB: il PLC modello PM5052-T-ETH e i softstarter della serie PSTX. L’errore che compare è ‘P1 E00’ — Errore di comunicazione Fieldbus. Il bus non è lungo: tutti i dispositivi si trovano nella stessa stanza e sono collegati in serie. Alla fine del bus ho inserito anche una resistenza da 120 Ohm. La schermatura del cavo è presente. Devo tornare sull’impianto tra qualche giorno per riprovare e, nel frattempo, ho pensato di chiedere aiuto qui per capire dove potrei aver sbagliato. Ora sto cercando di riscrivere la logica di comunicazione inserendo una pausa tra una richiesta e l’altra, sperando che questo risolva il problema.
Ctec Posted July 2 Report Posted July 2 Attenzione al tempo di attesa tra un comando e un altro, quindi anche tra uno slave e l'altro. Normalmente, dipende dalla velocità di trasmissione, bisogna attendere un carattere e mezzo prima di mandare il comando successivo. Questo per garantire che la linea sia elettricamente libera e stabile dopo l'ultima risposta. Non conosco l'ABB, ma spesso questo parametro è impostabile, in ms, direttamente nei parametri della porta di comunicazione modbus.
NoNickName Posted July 2 Report Posted July 2 Naturalmente i softstarter devono avere indirizzi diversi l'uno dall'altro. Scusa per l'ovvietà, ma meglio accertarsene.
Mykola Posted Saturday at 06:56 PM Author Report Posted Saturday at 06:56 PM Il 02/07/2025 alle 17:40 , Ctec ha scritto: Attenzione al tempo di attesa tra un comando e un altro, quindi anche tra uno slave e l'altro. Normalmente, dipende dalla velocità di trasmissione, bisogna attendere un carattere e mezzo prima di mandare il comando successivo. Questo per garantire che la linea sia elettricamente libera e stabile dopo l'ultima risposta. Non conosco l'ABB, ma spesso questo parametro è impostabile, in ms, direttamente nei parametri della porta di comunicazione modbus. Grazie mille per la risposta. Non ho molta esperienza e non sapevo bene come impostare correttamente una comunicazione tramite Modbus RTU. Facendo alcune prove con un SoftStarter ABB della serie PSTX, anche cambiando varie impostazioni, ottenevo sempre lo stesso errore: ‘P1 E00’ – Errore di comunicazione Fieldbus. Alla fine, l’errore spariva solo impostando il parametro "Fieldbus Failure Operation" su OFF, ma in quel caso la comunicazione non funzionava correttamente. Infatti, il blocco di funzione ModRTUMast richiede un fronte di salita sull'ingresso Execute per iniziare la comunicazione, e dopo che l’uscita Done o Error si attiva, è necessario resettare Execute a FALSE per preparare la richiesta successiva. Durante i test in impianto, avevo dimenticato dell’importanza del parametro "Fieldbus Failure Operation", ma ho scoperto che i SoftStarter ABB PSTX hanno un timeout di comunicazione predefinito di 600 ms. L’errore ‘P1 E00’ compare quando il dispositivo non riceve nessuna richiesta Modbus (né lettura né scrittura) entro questo intervallo. Disattivando "Fieldbus Failure Operation", l’errore non compariva, e tutti e 7 i SoftStarter sulla linea Modbus comunicavano normalmente. Successivamente, ho capito che era necessario modificare l’approccio alla comunicazione e ho sviluppato una piccola macchina a stati. Questa sequenza funziona così: Effettuo una richiesta di lettura di 12 registri (16 bit) per il primo SoftStarter. Dopo aver ricevuto Done o Error, attendo 2 ms. Invio una richiesta di scrittura di 32 coil per lo stesso dispositivo. Dopo Done o Error, attendo di nuovo, incremento l’indice, e passo al secondo SoftStarter. Ripeto la stessa logica per tutti e 7 i dispositivi, poi riporto l’indice a 1 e ricomincio il ciclo. Con un tempo di attesa tra le richieste fino a 4–5 ms, tutto funziona anche con il parametro "Fieldbus Failure Operation" attivato. Tuttavia, se imposto un’attesa superiore a 10 ms, ricompare l’errore ‘P1 E00’. Vorrei sapere: Come si struttura normalmente una comunicazione Modbus RTU in ambiente PLC? E, secondo Lei, la soluzione che ho adottato è corretta o ci sono miglioramenti che potrei fare? Le ringrazio molto per l’aiuto!
Marco Fornaciari Posted Saturday at 10:59 PM Report Posted Saturday at 10:59 PM Premetto che anch'io non conosco le apparecchiature che stai utilizzando. Il cadenzamento che hai fatto è quello corretto (di fatto il solo che funziona in ogni comunicazione seriale), eventualmente cambianao i tempi di ritardo e clock. Se ho inteso bene l'errore è nel softstarter, mi pare strano che richieda una comunicazione continua entro 600 mS, con solo due apparecchi in rete ci può anche stare, ma oltre no. Pertanto quel parametro deve essere modificabile, a meno che non si riferisca ad altro, es. una stinga ben precisa che deve ricevere, oppure che devi impostare una maggiore volocitè di comunicazione. Ma scusa. Dando un guardata in rete prendo atto che quel PLC e quei softstarter gestiscono la Profinet: quindi la domanda è, perché nel 2025 complicarsi la vita non usandola?
Mykola Posted Sunday at 09:54 AM Author Report Posted Sunday at 09:54 AM 10 ore fa, Marco Fornaciari ha scritto: Premetto che anch'io non conosco le apparecchiature che stai utilizzando. Il cadenzamento che hai fatto è quello corretto (di fatto il solo che funziona in ogni comunicazione seriale), eventualmente cambianao i tempi di ritardo e clock. Se ho inteso bene l'errore è nel softstarter, mi pare strano che richieda una comunicazione continua entro 600 mS, con solo due apparecchi in rete ci può anche stare, ma oltre no. Pertanto quel parametro deve essere modificabile, a meno che non si riferisca ad altro, es. una stinga ben precisa che deve ricevere, oppure che devi impostare una maggiore volocitè di comunicazione. Ma scusa. Dando un guardata in rete prendo atto che quel PLC e quei softstarter gestiscono la Profinet: quindi la domanda è, perché nel 2025 complicarsi la vita non usandola? Grazie mille per la risposta. Il progetto inizialmente era stato concepito per un funzionamento diverso: non era prevista la presenza di un PLC. Le pompe dovevano essere avviate in modalità manuale tramite un semplice galleggiante, che chiudeva un contatto. Successivamente, poiché il SoftStarter dispone dell’interfaccia RS485, si è deciso di utilizzare la comunicazione tramite protocollo Modbus RTU. È proprio in questa fase che ho iniziato a riscontrare dei problemi. Dopo una lunga ricerca, ho capito che per una semplice lettura dei registri si poteva evitare il problema della comunicazione senza attivare la funzione Fieldbus Control. Tuttavia, senza questa funzione attivata, non è possibile scrivere nei registri Coil (per inviare comandi). Per evitare modifiche complesse al cablaggio, si è deciso di utilizzare un'uscita digitale (DO) del PLC per chiudere il contatto che originariamente veniva attivato dal galleggiante. Tuttavia, è rimasta la necessità di scrivere nei registri, ad esempio per poter gestire il reset degli eventi direttamente dall’HMI, senza dover intervenire manualmente sull’interfaccia del SoftStarter. A tal proposito, ho trovato un parametro utile nella lista delle protezioni: “Fieldbus Failure Operation”, che ha permesso di gestire meglio queste condizioni. Inoltre, per comunicare con l’HMI (sempre ABB) sono costretto a utilizzare il protocollo Modbus TCP. Questo richiede che ogni variabile abbia un indirizzo preciso nella memoria del PLC. Per me non è semplice, perché devo calcolare attentamente questi indirizzi per evitare sovrascritture di altre variabili, e tutto ciò diventa complesso da gestire. Mi trovo da solo in azienda, senza un vero supporto tecnico, e non sono un programmatore esperto. I corsi base forniscono una panoramica molto distante dalla realtà pratica, e mi rendo conto ogni giorno di quanto ci sia ancora da imparare. Per questo motivo, mi rivolgo a voi programmatori con più esperienza per ricevere qualche consiglio pratico. Grazie ancora per il supporto!
Marco Fornaciari Posted Sunday at 03:10 PM Report Posted Sunday at 03:10 PM Il protocollo Modbus è di fatto semplice e pure gratis (che poi cambia poco dal CAN che la base ti tutti gli altri, ma non gratis), ma per gestirlo bene e con facilità bisogna progettare prima tutta la gestione delle variabili. In questi casi di aggiunta dopo normalmente non perdo tempo e rimappo tutte le variabili riscrivendo il SW, sfruttando il cambio in automatico magari in due passaggi, so da dove e parto e dove arrivo, e risolvo in tempi certi e brevi: spesso bisogna osare e rifare un SW, in fin dei conti è tutto lavoro a tavolino e l'originale è sempre lì pronto all'uso. Sono decenni che progetto tutte le variabili prima, anche dello schema, con excel. I corsi ti insegnano le cose principali e descrivono le funzioni più usate, ma non possono insegnare tutti contesti: ci vuole fantasia e poi osare.
Mykola Posted 21 hours ago Author Report Posted 21 hours ago Volevo chiedervi un’altra cosa: nello screenshot ci sono i parametri di default dell’interfaccia RS485. Se ho capito bene, quando si imposta nessuna parità, è necessario impostare 2 bit di stop per ottenere il famoso "carattere e mezzo" tra le richieste Modbus RTU. Se è così, allora le impostazioni di default (se ad esempio sono parità: None e 1 stop bit) possono causare errori di comunicazione Modbus RTU, giusto?
Ctec Posted 17 hours ago Report Posted 17 hours ago No, per esempio io imposto sempre 8N1, 8bit, nessuna parità, 1 stop. La pausa deve proprio essere un carattere e mezzo. Considera però che un carattere (byte) in trasmissione equivale a 10bit (con 8N1, oppure 11 con 8N2), per cui devi attendere 15bit (o 16), che vanno poi rapportati al baud rate. Se per esempio lavori a 19200, un bit dura 1/19200"=>52us circa, per cui l'attesa deve essere almeno 15*52=781us=0,781ms. Le impostazioni devono essere identiche per tutti i partecipanti (baud e composizione), altrimenti avrai errori di comunicazione e/o dati sballati
Mykola Posted 14 hours ago Author Report Posted 14 hours ago 2 ore fa, Ctec ha scritto: No, per esempio io imposto sempre 8N1, 8bit, nessuna parità, 1 stop. La pausa deve proprio essere un carattere e mezzo. Considera però che un carattere (byte) in trasmissione equivale a 10bit (con 8N1, oppure 11 con 8N2), per cui devi attendere 15bit (o 16), che vanno poi rapportati al baud rate. Se per esempio lavori a 19200, un bit dura 1/19200"=>52us circa, per cui l'attesa deve essere almeno 15*52=781us=0,781ms. Le impostazioni devono essere identiche per tutti i partecipanti (baud e composizione), altrimenti avrai errori di comunicazione e/o dati sballati PROGRAM ModBusRTU_ST VAR i : INT:= 1; fb_ModBusRead : ModRtuMast; fb_ModBusWrite : ModRtuMast; Stato : INT :=0; Fase : BOOL; //False - lettura, TRUE - scrittura TimerAttesa : TON; TempoAttesa: TIME :=T#2MS; DoneR, BusyR, ErrorR : BOOL; DoneW, BusyW, ErrorW : BOOL; R_trigR: R_TRIG; R_trigW: R_TRIG; ExecuteRead, ExecuteWrite : BOOL; ContaRead: INT; ContaWrite: INT; ContaDoneRead: INT; ContaError: INT; END_VAR R_trigR(CLK:=((Stato=0) AND NOT Fase) , Q=> ); R_trigW(CLK:= ((Stato=0) AND Fase), Q=> ); ExecuteRead := R_trigR.Q; ExecuteWrite := R_trigW.Q; TimerAttesa(IN:= , PT:=TempoAttesa, Q=> , ET=> ); CASE Stato OF //Avvio comando lettura o scrittura 0: IF NOT Fase THEN // BLOCCO LETTURA fb_ModBusRead( Execute:= ExecuteRead , Done=> DoneR, Busy=> BusyR, Error=> ErrorR, Endian:= , Serv:= Pump[i].ModBusRTU.PumpAddress, Fct:= Pump[i].ModBusRTU.FunRead, //4 Timeout:= Pump[i].ModBusRTU.Timeout, //T#100ms Addr:= 511, Nb:= 12, Data:= ADR(PumpModbusData[i].AnalogInputs), ErrorID=> , Com:= Pump[i].ModBusRTU.ComPort ); Pump[i].Status.DoneRead := DoneR; Pump[i].Status.ErrorRead := ErrorR; IF DoneR OR ErrorR THEN ExecuteRead := FALSE; Stato := 10; END_IF ELSE // BLOCCO SCRITTURA fb_ModBusWrite( Execute:= ExecuteWrite , Done=> DoneW, Busy=> BusyW, Error=> ErrorW, Endian:= , Serv:= Pump[i].ModBusRTU.PumpAddress, Fct:=Pump[i].ModBusRTU.FunWrite , //15 Timeout:= Pump[i].ModBusRTU.Timeout, //T#100ms Addr:= 256, Nb:= 32, Data:= ADR(PumpModbusData[i].CoilOutputs), ErrorID=> , Com:= Pump[i].ModBusRTU.ComPort ); Pump[i].Status.DoneWrite:= DoneW; Pump[i].Status.ErrorWrite:= ErrorW; IF DoneW OR ErrorW THEN ExecuteWrite := FALSE; Stato := 20; END_IF END_IF //pausa dopo la Lettura 10: TimerAttesa.IN := TRUE; IF TimerAttesa.Q THEN TimerAttesa.IN := FALSE; Fase := TRUE; Stato := 0; END_IF //pausa dopo scrittura 20: TimerAttesa.IN := TRUE; IF TimerAttesa.Q THEN TimerAttesa.IN := FALSE; Fase :=FALSE; i:= i +1; Stato := 0; IF i>7 THEN i :=1; Stato:= 0; END_IF END_IF END_CASE IF Pump[2].Status.DoneRead THEN ContaDoneRead := ContaDoneRead +1 ; END_IF IF Pump[2].Status.ErrorRead THEN ContaError := ContaError +1 ; END_IF In teoria, considerando una richiesta di lettura di 12 registri a 16 bit (che occupa 8 byte), e una risposta del dispositivo composta da: - 1 byte per l'indirizzo; - 1 byte per il codice funzione; - 1 byte per il numero di byte da leggere; - 12 registri × 2 byte = 24 byte; -2 byte per il CRC otteniamo una risposta di 28 byte. Sommando i 28 byte della risposta agli 8 byte della richiesta, il totale è di 36 byte, ovvero 288 bit. 288 bit / 19200 bit/s = 0,015 s = 15 ms allora 1.5 parametro corrisponde 22.5 ms? Vorrei profondire questo argumetro, scusate mi tanto per la mia ignoranza
Ctec Posted 14 hours ago Report Posted 14 hours ago 7 minuti fa, Mykola ha scritto: allora 1.5 parametro corrisponde 22.5 ms? No, un byte e mezzo, più start/stop/parità. La pausa va messa alla fine della ricezione del messaggio di risposta e prima di inviare il prossimo. Quindi: messaggio-attesa risposta-risposta-pausa 1.5ch e via andare. Considera che lo slave, ricevuto il messaggio, automaticamente mette lui almeno un'attesa di 1.5ch prima di inviare la risposta. Che PLC usi per tutto ciò? Per esempio, qui è come si imposta la porta seriale di un LS: Qui vedi (CH2) ho impostato il modbus a 57600, 8N1, attesa di risposta dello slave 100ms (che è un bel po' di tempo...) delay time prima di trasmissione a 0 (in pratica tra la fine di un messaggio e il successivo io passo una scansione, pari a circa 2ms massimo) e nessun ritardo tra i caratteri (è per apparecchiature molto vecchie). Non è campato in aria, è una macchina perfettamente funzionante con 3 inverter e 1 servo controllati in seriale.
Mykola Posted 13 hours ago Author Report Posted 13 hours ago 39 minuti fa, Ctec ha scritto: No, un byte e mezzo, più start/stop/parità. La pausa va messa alla fine della ricezione del messaggio di risposta e prima di inviare il prossimo. Quindi: messaggio-attesa risposta-risposta-pausa 1.5ch e via andare. Considera che lo slave, ricevuto il messaggio, automaticamente mette lui almeno un'attesa di 1.5ch prima di inviare la risposta. Che PLC usi per tutto ciò? Per esempio, qui è come si imposta la porta seriale di un LS: Qui vedi (CH2) ho impostato il modbus a 57600, 8N1, attesa di risposta dello slave 100ms (che è un bel po' di tempo...) delay time prima di trasmissione a 0 (in pratica tra la fine di un messaggio e il successivo io passo una scansione, pari a circa 2ms massimo) e nessun ritardo tra i caratteri (è per apparecchiature molto vecchie). Non è campato in aria, è una macchina perfettamente funzionante con 3 inverter e 1 servo controllati in seriale. Grazie mille. Io uso un PLC ABB PM5052-T-ETH. Ho impostato PT:=T#2MS in Timer per fare la pausa tra la lettura e scrittura. La comunicazione sembra funzionare, ma volevo sapere se questo è il modo corretto di procedere.
Ctec Posted 13 hours ago Report Posted 13 hours ago Come detto, metti eventuale pausa dopo la risposta prima del nuovo messaggio. Altrimenti rallenti inutilmente il tutto
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now