#analogIA #sae452 #mixer # Modulo Elettronico Analogico SIMATIC ET 200S 2AI I 4WIRE ST Preso dalle schede AI su il SAE452: ==6ES7 134-4GB11-0AB0== Manuale: [et200s\_2ai\_i\_4wire\_st\_manual\_en-US.pdf](https://cache.industry.siemens.com/dl/files/991/25545991/att_70599/v1/et200s_2ai_i_4wire_st_manual_en-US.pdf) ## Guida alla Configurazione e Programmazione per Misure 4-20 mA ## 1. Range di Misurazione per Corrente: 4-20 mA La seguente tabella contiene i valori analogici digitalizzati per il range di misurazione del modulo di ingresso analogico. Poiché la rappresentazione binaria dei valori analogici è sempre la stessa, questa tabella confronta i range di misurazione con le unità. ### Tabella 4-3: Formato SIMATIC S7: Range di misurazione 4-20 mA |Range di misurazione 4-20 mA|Unità| |Range| |---|---|---|---| ||Decimale|Esadecimale|| |> 22,8142|32767|7FFFH|Overflow| |22,8142 : 20,0005|32511 : 27649|7EFFH : 6C01H|Range di sovraccarico| |20,0000 16,0000 : 4,0000|27648 20736 : 0|6C00H 5100H : 0H|Range nominale| |3,9995 : 1,1852|-1 : -4864|FFFFH : ED00H|Range di sottoccarico| |< 1,1852|-32768|8000H|Underflow| | Assegnazione parametri | Valori misurati | | Descrizione | | -------------------------------------------------------------------------------------------- | --------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------ | | Decimale | Esadecimale | | | | • Diagnostica "Rottura cavo" abilitata | 32767 | 7FFFH | • Messaggio diagnostico "Circuito aperto" | | • Diagnostica "Rottura cavo" disabilitata
• Diagnostica "Overflow/underflow" abilitata | -32767 | 8000H | • Valore misurato dopo aver lasciato il range di sottoccarico
• Messaggio diagnostico "Valore limite inferiore superato verso il basso" | | • Diagnostica "Rottura cavo" disabilitata
• Diagnostica "Overflow/underflow" disabilitata | -32767 | 8000H | • Valore misurato dopo aver lasciato il range di sottoccarico | ## 2. Conversione da Brix a Corrente 4-20 mA Nel tuo caso specifico, desideri convertire valori Brix dove: - 60 Brix corrisponde a 20 mA (valore massimo) - 0 Brix corrisponde a 4 mA (valore minimo) ``` Brix = ((Corrente (mA) - 4) / 16) * 60 ``` ## 3. Parametri di Diagnostica ### Parametri per il modulo di ingresso analogico 2 AI I 4WIRE ST | Parametro | Valori | | --------------------------------------------------------------------- | ------------- | | Diagnostica di gruppo (errore assegnazione parametri, errore interno) | Abilitato | | Diagnostica: Overflow/underflow | Abilitato | | Diagnostica: Rottura cavo* | Abilitato | | Smoothing (Smorzamento) | Nessuno | | Tipo/range di misurazione | WIRE: 4-20 mA | ![[Pasted image 20250507112955.png]] ### Spiegazione dei Parametri di Diagnostica: 1. **Diagnostica di gruppo**: Quando abilitata, il modulo segnala errori generali come errori di parametrizzazione o errori interni del modulo. Attiva il LED SF (errore) e genera un messaggio diagnostico. 2. **Diagnostica Overflow/underflow**: Quando abilitata, il modulo genera messaggi diagnostici quando il valore di ingresso supera (overflow) o scende sotto (underflow) i limiti del range di misurazione. Questi sono: - Overflow: > 22,8142 mA - Underflow: < 1,1852 mA 3. **Diagnostica Rottura cavo**: Quando abilitata, il modulo rileva una interruzione del circuito se la corrente scende sotto 1,185 mA. Questa opzione è disponibile solo nel range di misurazione 4-20 mA. ## 4. Comportamento del Modulo in Caso di Errore ### Valori misurati in caso di rottura del cavo in relazione alla diagnostica abilitata: _Limiti del range di misurazione per il rilevamento di rottura del cavo e underflow: A 1,185 mA_ ## 5. Programmazione SCL per Gestire i Diversi Stati Ecco un esempio di come gestire i diversi stati in programmazione SCL per un PLC S7-300: ```pascal // FB100 - Gestione Misurazione Brix con diagnostica // Configurazione hardware richiesta: // - Group diagnostics: Abilitato // - Diagnostic overflow/underflow: Abilitato // - Wire break: Abilitato FUNCTION_BLOCK "FB_MisurazioneBrix" TITLE = 'Gestione sensore Brix con diagnostica' AUTHOR : Sysadmin FAMILY : Process VAR_INPUT i_IW_Analog : WORD; // Indirizzo dell'ingresso analogico (PEW) i_EnableDiagnostic : BOOL := TRUE; // Abilita la lettura dei messaggi diagnostici i_Reset : BOOL; // Reset allarmi END_VAR VAR_OUTPUT o_ValoreBrix : REAL; // Valore Brix convertito (0-60) o_CorrienteMa : REAL; // Valore corrente in mA (per diagnostica) o_StatoSensore : INT; // 0=OK, 1=Overflow, 2=Underflow, 3=Wire Break, 4=Errore ADAM (2mA) o_QualitaBuona : BOOL; // TRUE se la misura è affidabile o_DiagInfo : STRING; // Informazioni diagnostiche in formato testo END_VAR VAR // Definizione delle costanti OVERFLOW_VALUE : INT := 32767; // 7FFFH - Valore di overflow UNDERFLOW_VALUE : INT := -32768; // 8000H - Valore di underflow WIRE_BREAK_VALUE : INT := 32767; // 7FFFH - Con diagnostica wire break abilitata MAX_NORMAL : INT := 27648; // 6C00H - 20mA (valore massimo nel range nominale) MIN_NORMAL : INT := 0; // 0000H - 4mA (valore minimo nel range nominale) // Variabili interne ValoreAnalogicoInt : INT; // Valore analogico convertito in INT ErroreRilevato : BOOL; // Flag per errore rilevato TimerRitardo : TON; // Timer per filtrare falsi allarmi RitardoErrore : TIME := T#2S; // Ritardo di conferma errore (2 secondi) MemoriaStato : INT; // Memoria dell'ultimo stato valido // Variabili per la diagnostica di sistema DiagRequest : BOOL; // Richiesta di lettura diagnostica DiagBusy : BOOL; // Blocco diagnostica occupato DiagDone : BOOL; // Lettura diagnostica completata DiagError : BOOL; // Errore durante la lettura diagnostica DiagStatus : WORD; // Stato della diagnostica DiagBuffer : ARRAY[0..31] OF BYTE; // Buffer per i dati diagnostici // Variabili per rilevazione errore ADAM (circa 2mA) ADAM_ERROR_LOW : INT := -3600; // Limite inferiore per rilevare errore ADAM (~1.8mA) ADAM_ERROR_HIGH : INT := -3200; // Limite superiore per rilevare errore ADAM (~2.2mA) // Dati temporanei TempBrix : REAL; // Valore Brix temporaneo per calcoli FirstScan : BOOL := TRUE; // Flag per primo ciclo END_VAR VAR_TEMP TempValue : INT; // Valore temporaneo per calcoli TempReal : REAL; // Valore temporaneo per calcoli in virgola mobile StatusTemp : INT; // Stato temporaneo per logica degli stati END_VAR BEGIN // Inizializzazione delle variabili al primo ciclo IF FirstScan THEN FirstScan := FALSE; o_StatoSensore := 0; o_DiagInfo := 'Inizializzazione sistema'; MemoriaStato := 0; END_IF; // Converti il valore WORD in INT per elaborazione ValoreAnalogicoInt := WORD_TO_INT(i_IW_Analog); // Logica di stato iniziale - determina lo stato del sensore StatusTemp := 0; // Stato predefinito: OK ErroreRilevato := FALSE; // Verifica delle diverse condizioni di errore CASE ValoreAnalogicoInt OF OVERFLOW_VALUE: // 32767 (7FFFH) // Può indicare overflow o wire break se la diagnostica di rottura cavo è abilitata IF i_EnableDiagnostic THEN // Dobbiamo leggere le informazioni diagnostiche per distinguere tra overflow e wire break DiagRequest := TRUE; StatusTemp := 1; // Assumiamo inizialmente Overflow o_DiagInfo := 'Overflow rilevato o Wire Break?'; ELSE StatusTemp := 1; // Overflow (senza diagnostica non possiamo distinguere) o_DiagInfo := 'Overflow rilevato'; END_IF; ErroreRilevato := TRUE; UNDERFLOW_VALUE: // -32768 (8000H) StatusTemp := 2; // Underflow o_DiagInfo := 'Underflow rilevato - Valore troppo basso'; ErroreRilevato := TRUE; ELSE // Verifica se il valore è nell'intervallo che indica errore ADAM (circa 2mA) IF ValoreAnalogicoInt >= ADAM_ERROR_LOW AND ValoreAnalogicoInt <= ADAM_ERROR_HIGH THEN StatusTemp := 4; // Errore ADAM (2mA) o_DiagInfo := 'Errore rilevato dal sensore ADAM (2mA) - Problema misuratore Brix'; ErroreRilevato := TRUE; ELSIF ValoreAnalogicoInt < MIN_NORMAL AND ValoreAnalogicoInt > UNDERFLOW_VALUE THEN // Siamo in underrange ma non ancora in underflow completo o_DiagInfo := 'Valore in underrange (< 4mA)'; // Non consideriamo questo necessariamente un errore, solo una nota ELSIF ValoreAnalogicoInt > MAX_NORMAL AND ValoreAnalogicoInt < OVERFLOW_VALUE THEN // Siamo in overrange ma non ancora in overflow completo o_DiagInfo := 'Valore in overrange (> 20mA)'; // Non consideriamo questo necessariamente un errore, solo una nota ELSE // Valore nell'intervallo normale StatusTemp := 0; // OK o_DiagInfo := 'Misura OK'; END_IF; END_CASE; // Filtro temporale per gli errori (evita falsi allarmi) IF ErroreRilevato THEN // Avvia il timer se è stato rilevato un errore TimerRitardo(IN := TRUE, PT := RitardoErrore); // Imposta lo stato di errore solo se il timer è scaduto IF TimerRitardo.Q THEN o_StatoSensore := StatusTemp; END_IF; ELSE // Resetta il timer se non ci sono errori TimerRitardo(IN := FALSE); o_StatoSensore := StatusTemp; END_IF; // Reset degli allarmi se richiesto IF i_Reset THEN o_StatoSensore := 0; o_DiagInfo := 'Stato resettato dall operatore'; TimerRitardo(IN := FALSE); END_IF; // Calcolo del valore in mA indipendentemente dallo stato // Formula: mA = 4 + (ValoreAnalogicoInt / 27648) * 16 IF ValoreAnalogicoInt <= MAX_NORMAL AND ValoreAnalogicoInt >= UNDERFLOW_VALUE THEN // Conversione normale per valori validi o in underrange TempReal := INT_TO_REAL(ValoreAnalogicoInt); o_CorrienteMa := 4.0 + (TempReal / INT_TO_REAL(MAX_NORMAL)) * 16.0; // Un valore sotto lo zero corrisponde a meno di 4mA IF o_CorrienteMa < 0.0 THEN o_CorrienteMa := 0.0; // Limitato a 0mA minimo (per evitare valori negativi) END_IF; ELSIF ValoreAnalogicoInt = OVERFLOW_VALUE THEN o_CorrienteMa := 22.81; // Valore di overflow ELSIF ValoreAnalogicoInt = UNDERFLOW_VALUE THEN o_CorrienteMa := 0.0; // Valore di underflow END_IF; // Conversione da corrente a Brix // Formula: Brix = ((mA - 4) / 16) * 60 IF o_StatoSensore = 0 THEN // Calcolo normale solo se non ci sono errori IF o_CorrienteMa >= 4.0 THEN TempBrix := ((o_CorrienteMa - 4.0) / 16.0) * 60.0; // Limitazione del valore Brix tra 0 e 60 IF TempBrix < 0.0 THEN o_ValoreBrix := 0.0; ELSIF TempBrix > 60.0 THEN o_ValoreBrix := 60.0; ELSE o_ValoreBrix := TempBrix; END_IF; ELSE // Sotto 4mA, impostiamo Brix a 0 o_ValoreBrix := 0.0; END_IF; ELSE // In caso di errore, manteniamo l'ultimo valore valido o impostiamo un valore specifico CASE o_StatoSensore OF 1: // Overflow o_ValoreBrix := 60.0; // Impostiamo al valore massimo 2: // Underflow o_ValoreBrix := 0.0; // Impostiamo al valore minimo 3: // Wire Break o_ValoreBrix := -1.0; // Valore speciale per Wire Break 4: // Errore ADAM o_ValoreBrix := -2.0; // Valore speciale per Errore ADAM END_CASE; END_IF; // Imposta la qualità della misura o_QualitaBuona := (o_StatoSensore = 0); // Gestione lettura diagnostica di sistema (se abilitata) IF i_EnableDiagnostic AND DiagRequest THEN // Strutture dati necessarie per SFC51 VAR_TEMP DiagHeader : STRUCT // Struttura dell'header SZL LENTHDR : WORD; // Lunghezza dell'header SZL in byte N_DR : WORD; // Numero di record dati END_STRUCT; DiagResult : INT; // Risultato della chiamata SFC51 DiagLen : WORD; // Lunghezza dei dati ricevuti DiagCount : INT; // Contatore per l'analisi dei dati DiagFound : BOOL; // Flag per errore trovato DiagSlot : BYTE; // Slot del modulo diagnosticato DiagType : BYTE; // Tipo di errore diagnostico DiagAddr : WORD; // Indirizzo del modulo TempAddr : WORD; // Indirizzo temporaneo per calcoli DiagModuleStartAddr : WORD; // Indirizzo di inizio del modulo END_VAR // Leggi lo stato diagnostico del sistema utilizzando SFC51 // Lettura delle informazioni diagnostiche del modulo DiagResult := SFC51( REQ := TRUE, // Richiesta di lettura SZL_ID := W#16#00B1, // ID per informazioni diagnostiche (diagnostica slave DP) INDEX := W#16#0000, // Tutti gli slave RET_VAL := DiagStatus, // Codice di ritorno BUSY := DiagBusy, // Operazione in corso SZL_HEADER := DiagHeader, // Header SZL DR := DiagBuffer // Buffer per i dati diagnostici ); // Se l'operazione è completata, analizziamo i risultati IF NOT DiagBusy THEN DiagRequest := FALSE; // Reset della richiesta IF DiagStatus = W#16#0000 THEN DiagDone := TRUE; // Lettura completata con successo DiagFound := FALSE; // Reset flag errore trovato // Calcola l'indirizzo del modulo analogico // Nota: questo è un esempio, devi adattarlo al tuo hardware // Supponiamo che l'indirizzo dell'ingresso analogico sia PIW256 DiagModuleStartAddr := W#16#0100; // 256 in esadecimale // Analizza i dati diagnostici ricevuti per trovare errori specifici FOR DiagCount := 0 TO INT_TO_INT(DiagHeader.N_DR)-1 DO // Ogni record di diagnostica ha un formato specifico // Estrai lo slot e l'indirizzo del modulo per verificare che sia quello giusto DiagSlot := DiagBuffer[DiagCount*4]; // Slot in byte 0 del record TempAddr := WORD_TO_WORD(SHL(IN:=BYTE_TO_WORD(DiagBuffer[DiagCount*4+2]), N:=8)); TempAddr := TempAddr OR BYTE_TO_WORD(DiagBuffer[DiagCount*4+3]); DiagAddr := TempAddr; // Indirizzo del modulo // Verifica se questo è il nostro modulo analogico IF DiagAddr = DiagModuleStartAddr THEN // Leggi il tipo di errore (byte 1 del record) DiagType := DiagBuffer[DiagCount*4+1]; // Analizza il tipo di errore CASE DiagType OF B#16#06: // 6D = 00110: Wire break o_StatoSensore := 3; // Wire break o_DiagInfo := 'Wire Break rilevato tramite diagnostica'; DiagFound := TRUE; B#16#07: // 7D = 00111: Upper limit exceeded o_StatoSensore := 1; // Overflow o_DiagInfo := 'Overflow rilevato tramite diagnostica'; DiagFound := TRUE; B#16#08: // 8D = 01000: Lower limit undershot o_StatoSensore := 2; // Underflow o_DiagInfo := 'Underflow rilevato tramite diagnostica'; DiagFound := TRUE; B#16#09: // 9D = 01001: Error (modulo interno) o_StatoSensore := 5; // Errore interno modulo o_DiagInfo := 'Errore interno del modulo rilevato'; DiagFound := TRUE; B#16#10: // 16D = 10000: Errore parametrizzazione o_StatoSensore := 6; // Errore configurazione o_DiagInfo := 'Errore configurazione modulo'; DiagFound := TRUE; END_CASE; // Se abbiamo trovato un errore, usciamo dal ciclo IF DiagFound THEN EXIT; END_IF; END_IF; END_FOR; // Se non troviamo errori diagnostici ma il valore è 32767, è probabilmente un overflow IF NOT DiagFound AND ValoreAnalogicoInt = OVERFLOW_VALUE THEN o_StatoSensore := 1; // Overflow o_DiagInfo := 'Overflow rilevato (nessun messaggio diagnostico specifico)'; END_IF; ELSE // Errore nella lettura diagnostica DiagError := TRUE; o_DiagInfo := CONCAT(IN1:='Errore SFC51: ', IN2:=WORD_TO_STRING(DiagStatus)); END_IF; END_IF; END_IF; END_IF; END_FUNCTION_BLOCK // Chiamata al blocco funzionale di misurazione Brix // Sostituire "PIW256" con l'indirizzo effettivo dell'ingresso analogico CALL "FB_MisurazioneBrix", "DB_MisurazioneBrix" ( i_IW_Analog := PIW256, // Indirizzo ingresso analogico (da adattare) i_EnableDiagnostic := TRUE, i_Reset := "Reset_Allarmi" // Connetti a un ingresso digitale o a una variabile HMI ); // Qui puoi aggiungere ulteriore logica per gestire i valori e gli stati // Ad esempio, trasferire i valori a DB per visualizzazione HMI, attivare allarmi, ecc. ``` ## 6. Caso Specifico: ADAM/Maselli che Genera 0-20mA Per gestire questa situazione: 1. **Configurazione del modulo**: Configura il modulo analogico SIMATIC per il range 4-20mA 2. **Gestione dei valori sotto 4mA**: Quando il valore scende sotto 4mA (che in formato S7 sarebbe sotto 0 in decimale), il modulo lo interpreta come underrange. 3. **Rilevamento dell'errore a 2mA**: Il valore di 2mA corrisponde approssimativamente a -3456 in formato decimale S7 per il range 4-20mA. ### Senza utilizare la SFC51: *** ```pascal // Determinazione dello stato del sensore basata solo sul valore PEW IF ValoreAnalogicoInt = OVERFLOW_VALUE THEN // 32767 o_StatoSensore := 7; // Codice generico per "Overflow o Wire Break" o_DiagInfo := 'Rilevato Overflow o Wire Break'; ELSIF ValoreAnalogicoInt = UNDERFLOW_VALUE THEN // -32768 o_StatoSensore := 2; // Underflow o_DiagInfo := 'Underflow rilevato'; ELSIF ValoreAnalogicoInt >= ADAM_ERROR_LOW AND ValoreAnalogicoInt <= ADAM_ERROR_HIGH THEN o_StatoSensore := 4; // Errore ADAM (2mA) o_DiagInfo := 'Errore ADAM rilevato (2mA)'; ELSE o_StatoSensore := 0; // OK o_DiagInfo := 'Misura OK'; END_IF; ```