Vai al contenuto

Stefano

Risposte nei forum create

Stai visualizzando 15 post - dal 1 a 15 (di 67 totali)
  • Autore
    Post
  • in risposta a: Parsing stringa da porta seriale #77651
    Stefano
    Partecipante

    Sto ampliando il progetto oggetto di questo post, scritto sulla falsa riga dell’esempio nella documentazione di SysSerialPort.

    Adesso raccolgo dalla seriale dati da macchine diverse. Il parsing delle stringhe è alquanto diverso: alcune usano la virgola per i decimali, altre il punto, altre hanno la stringa con i valori posti in ordine differente, altre hanno la seriale con parametri diversi. Fin’ora avevo due casi e portavo avanti due software diversi. Ora i casi sono di più e vorrei unificare in un software solo, mettere un valore indicante il tipo di macchina in SysUSetA e nel software agire diversamente in base al valore.

    Guardando sempre l’esempio ST_SerialDataReceive se io creassi dei blocchi funzionali per i le varie casistiche, e li richiamassi nel codice a seconda del tipo di macchina, le variabili locali dichiarate in ST_SerialDataReceive sarebbero accessibili dai blocchi funzionali oppure dovrei dichiararle tutte come variabili globali (o passarle come parametro) perchè siano accessibili?

    In alternativa potrei usare anche le macro per tenere diviso il codice.

    in risposta a: Blocco funzione per acquisizione cella di carico #74119
    Stefano
    Partecipante

    Per alimentare il ponte di misura di una cella di carico è percorribile la strada di prelevare i 5V dalla usb di uno slimline (se presente) o dal bus di espansione?

    in risposta a: Errori comunicazione Modbus RTU #71406
    Stefano
    Partecipante

    Noto anche una cosa, sempre che io stia interpretando bene i dati:

    10:48:04.730514|ModbusMaster:Tx|04 03 00 00 00 05 85 9C
    10:48:05.553558|ModbusMaster:Rx|04 03 0A 82 3F 00 00 00 00 08 78 08 91 DF 75
    10:48:06.054401|ModbusMaster:Tx|03 03 00 00 00 05 84 2B
    10:48:07.183762|ModbusMaster:Rx|03 03 0A 82 3F 00 00 00 00 E8 B8 00 00 25 A2

    Tra il primo invio e la ricezione passano 800ms,
    tra il secondo invio e la ricezione passano 1100ms.

    I devices sono estremamente lenti a rispondere e la cosa mi sembra strana.

    Sicuro che la ModbusMaster venga eseguita abbastanza spesso?

    in risposta a: Errori comunicazione Modbus RTU #71398
    Stefano
    Partecipante

    Se la comunicazione è in RS485 hai provato ad aumentare il valore “Delay” nel blocco ModbusMaster_V2?

    Alcuni dispositivi ci mettono un po’ di tempo a liberare il bus RS485 dopo aver finito di trasmettere. Per esperienza finchè si interroga un dispositivo solo non ci sono grossi problemi, quando se ne interrogano di più è meglio assicurare una congrua pausa (10ms? dipende dai dispositivi) tra la richiesta ad un nodo e ad un altro.

    in risposta a: Visualizzare variabili indicizzate su pagina modello #70303
    Stefano
    Partecipante

    Mi viene in mente anche un metodo C che forse ti viene più comodo:

    • Pagina con tutti i controlli appoggiati a locazioni sul pannello. Poi una tendina, o un valore numerico, che indica quale set di variabili PLC leggere.
    • Una macro in esecuzione ogni X secondi quando la pagina è attiva che:
      Con un case che punta al valore di selezione esegue un GetData per tutte le variabili PLC che ti servono e appoggia i dati in variabili locali alla macro.
      Dopo il case fai varie SetData dalle variabili locali della macro alle locazioni su cui sono appoggiati i controlli.

    Se i controlli hanno tutti lo stesso tipo di dato puoi ottimizzare un pochino: si appoggiano i controlli a tutte locazioni sequenziali (esempio tre controlli rispettivamente su LW-0, LW-1, LW-2). Nella macro si crea un array i 3 elementi. Tre GetData, all’interno delle varie case, scrivono ognuna su un indice dell’array. Alla fine si fa un unico SetData con l’array come dato da scrivere, che punta a LW-0 e con conteggio dati uguale a 3.

    in risposta a: Visualizzare variabili indicizzate su pagina modello #70263
    Stefano
    Partecipante

    Non ho mai usati i dispositivi Siemens ma ho il dubbio che la logica da usare nel tuo caso sia:

    GetData(read_data, device_name, device_type, address_offset, 1)

    Quindi ricavare l’indirizzo assoluto delle TAG (driver tipo “Absolute Addressing”), creare una matrice device_type/address, usare varie “GetData” con il device_type fisso e scegliere quale usare con un case. Poi mettere l’indirizzo in una variabile posta su address_offset. Se non  è permessa la variabile (non ho mai usato questo metodo) allora usare la stessa logica del case impiegando però i registri indice.

    Il metodo più “Weintekioniano” per fare una cosa simile a quello che ti serve credo sia uno dei due che ti scrivo seguito:

    Metodo A:

    In una pagine mettere tutti i controlli appoggiati a variabili locali. Per ogni controllo/tag mettere un data transfer di pagina. Quindi se “Lampada A” è riferita a 10 possibili tag ci saranno 10 data transfer verso l’indirizzo a cui è appoggiato il controllo. Nei vari data transfer utilizzi Sicurezza -> Attiva/Disattiva da registro e con una macro vai ad Attivare/Disattivare a runtime i data transfer che ti interessano.

    Metodo B senza macro:

    Crei una pagina che ha tutti i controlli appoggiati a variabili locali.

    Crei una pagina trasparente per ogni set di tag che ti interessa visualizzare. Nelle impostazioni della pagina metti come “pagina sottostante” la pagina con i controlli (non importa se messa nel campo sopra, centro o sotto). Nella pagina trasparente metti una data transfer di pagina per ogni oggetto relativo al tag che vuoi visualizzare.

    Cambiando poi pagina i controlli visualizzati sono sempre gli stessi, ma cambiano gli oggetti data transfer che copiano i valori da PLC a variabile locale dell’oggetto.

    in risposta a: Come utilizzare il FB Average #70008
    Stefano
    Partecipante

    Questo è il mio codice di acquisizione di una temperatura:

    PROGRAM MyProgram
    VAR
        ALR_SENS_HEATER : BOOL; (* Sensor alarm *)
        AN_TEMP_HEATER : REAL; (* Temperature (°C) *)
        ANA_IN_2 : SysGetAnInp; (* Analog inout acquisition *)
        AV_IN_2 : Average; (* Temperature average *)
    END_VAR
    
        ANA_IN_2(Address:=3, Channel:=1, Mode:=AD_PT100_DIFFER);
    
        IF ANA_IN_2.Fault THEN
            ALR_SENS_HEATER:=TRUE; //Sensor alarm
        ELSIF ANA_IN_2.Done THEN
            AV_IN_2(Value:=ANA_IN_2.Value,Coefficient:=125.0);
            AN_TEMP_HEATER:=AV_IN_2.Average; //Temperature (°C)
        END_IF;
    
    // [End of file]

    Oggi c’è stato un problema elettrico sulla PT100. Probabilmente il blocco di acquisizione analogica ha restituito qualche valore spropositatamente alto. L’errore ha comunque attivato l’uscita Fault, la cosa è gestita quindi l’operatore veniva informato del problema. La manutenzione ha sistemato il problema elettrico senza riavviare l’impianto. La segnalazione d’errore era rientrata, quindi l’operatore non vedeva guasti, ma dopo più di un ora la temperatura indicata era di 180°C, con trend in calo, contro la temperatura reale della sonda attorno ai 22 °C. Questo mi fa pensare che il blocco Average fosse semplicemente “sporco”.

    La mia idea sarebbe di appoggiare “Coefficient” ad una variabile che viene settata a zero quando il blocco SysGetAnInp è in “Fault” e riportata al valore corretto alla fine del codice eseguito quando il blocco segnala “Done”. Così mi assicuro che alla prima lettura venga “ripulito” il blocco Average.

    In una situazione simile, quindi ripristino della sonda da guasto, potrebbe essere necessario anche una sorta di reset del blocco SysGetAnInp ? O magari un reset fisico dell’hardware PCB126C110?

    in risposta a: Errore “eGetBYTE => Funzione sconosciuta” in compilazione #68383
    Stefano
    Partecipante

    Risolto anche il problema dei puntatori, ora mi rimane questo, ho definito la variable

    CNVDatetime : LDATETIMESTRUCT;

    Usata come da esempio “LogicLab (Ptp116, ST_DateTimeOperators)”:

    CNVDatetime:=TO_LDATE_AND_TIME(SysDateGetNs());

    La compilazione riporta:

    ST_SerialDataReceive(192) – warning G0065:  CNVDatetime => Il tipo destinazione può essere troppo piccolo per contenere il risultato

    ST_SerialDataReceive(192) – errore G0043:  Module: armcodegen.cpp, line: 6299 => ERRORE INTERNO DEL GENERATORE DI CODICE

    in risposta a: Errore “eGetBYTE => Funzione sconosciuta” in compilazione #68378
    Stefano
    Partecipante

    Ho eseguito il comando “Progetto -> Aggiorna sistema corrente” ed in automatico si è aggiunta la libreria eLLabCommonlib.

    Ora non ho più quell’errore, ma non funzionano più le assegnazioni con puntatore (es: @Ptr:=Ch;) Il programma di test è una versione leggermente modificata di “LogicLab (Ptp116, ST_SerialDataReceive) Semplice protocollo seriale”, modificata il tanto che basta a fare il parsing della stringa con una logica diversa.

    Le operazioni di accesso con i puntatori sono esattamente le stesse non toccate.

    in risposta a: Disponibilità protocollo OPC-UA #68101
    Stefano
    Partecipante

    Qualche novità in merito?

    in risposta a: Creare report diagnostici di segnalazione errore #67319
    Stefano
    Partecipante

    Mi accade la stessa cosa con 2 Mt8073iE, leggono dati su RS485 (modbus RTU) e li pubblicano in MQTT con broker interno.

    Dopo circa 2 mesi di funzionamento smettono di comunicare con il PLC.
    Per ovviare li faccio riavviare una volta a settimana.

    Ho altri pannelli uguali e non ho riscontrato il problema, solo su quelli in cui uso il protocollo MQTT.

    in risposta a: Funzione SysVarsnprintf per costruire stringa #65768
    Stefano
    Partecipante

    Si potrebbe avere un esempio di SysVarsscanf con il formato ‘%{%d%}’ indicato nel manuale?

    Ho fatto un programma di test con la stringa ‘ 123 456 ‘ ed il formato come sopra ma SysVarsscanf restituisce sempre FALSE.

    in risposta a: Parsing stringa da porta seriale #65484
    Stefano
    Partecipante

    Per fare il debug dell’applicazione mi farebbe comodo avere una pagina web che mostri il log delle stringe arrivate tramite seriale. Esattamente la cosa che fa la pagina web di sistema che mostra i log. C’è un modo standard per replicarla appoggiata ad un diverso file di testo?

    in risposta a: Comunicazione modbus con multimetro Lovato DMG110 #65483
    Stefano
    Partecipante

    Dopo innumerevoli prove sono giunto alla soluzione.
    Il problema fondamentale è che i registri non sono Unsigned Long (32 bit) ma bensì Unsigned long-long (64 bit). Inoltre bisogna stare attenti a leggere sempre un numero di registri multiplo di 2 a partire da indirizzi pari altrimenti lo strumento va in errore.

    Per leggere i due registri incriminati mi sono appoggiato ad una macro che legge i registri, li converte in un float a 32 bit e copia il valore in un registro del pannello.

    Non sarebbe il massimo perchè arriverà un momento in cui il valore mostrato sarà approssimato, ma per ora a me basta così. Di seguito la Macro:

    macro_command main()
    
    unsigned int uiData[2] = {0,0}
    float energy = 0
    
    GetData(uiData[0], "DMG110", 5x, 1b21, 2)// read 4 words active energy
    
    energy = uiData[0]
    energy = (energy + uiData[1] * 65536) / 100
    
    SetData(energy, "Local HMI", LW, 30, 1)
    
    GetData(uiData[0], "DMG110", 5x, 1b29, 2)// read 4 words reactive energy
    
    energy = uiData[0]
    energy = (energy + uiData[1] * 65536) / 100
    
    SetData(energy, "Local HMI", LW, 32, 1)
    
    end macro_command
    in risposta a: Comunicazione modbus con multimetro Lovato DMG110 #64396
    Stefano
    Partecipante

    Con EasyDiagnoser ho trovato l’errore. Un errore “2” su una richiesta era dato da un indirizzo non esistente sul dispositivo.

    L’altro era un errore numero 12 dato da 2 richieste successive:
    [5x] 2031616/2
    [5x] 2097152/2

    Corrispondenti a queste indicazioni del produttore del dispositivo:

    1B20H 4 Energia Attiva Importata totale Total imp. Active Energy kWh / 100 Unsigned long-long
    1B28H 4 Energia Reattiva Importata totale Total imp. Reactive Energy kvarh / 100 Unsigned long-long

    il 4 che si vede dopo l’indirizzo è il numero di word da leggere, sono valori a 64 bit. Evidentemente il dispositivo genera un errore se non si leggono consecutivamente tutte le 4 word. Credo che l’unico modo sia con una macro.

    PS tutti questi valori erano pubblicati via MQTT. Se un oggetto ha un indirizzo errato semplicemente non viene visualizzato l’oggetto. Se l’indirizzo non valido è tra i dati MQTT appare il messaggio “PLC no response”.

Stai visualizzando 15 post - dal 1 a 15 (di 67 totali)