Analogwertverarbeitung mit SCL

flotec79

Level-1
Beiträge
3
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

bin ein absoluter Anfänger in S7 SCL und mit Analogwerten hatte ich bei Siemensprogrammierung noch nie was zu tun. Ich benutze eine CPU313C. Hab am Analogeingang ein Poti angeschloßen in der HW Config alles konfiguriert. In der Variablentabelle ergeben sich damit Werte von ca. 3200 bis 32700. Wie kann ich jetzt diese Werte weiterverarbeiten.

Hab Analogwerte bis jetzt nur mit Codesys bearbeitet. Da funktionieren die Anweisungen ganz einfach.

z.B.

Analogwert > Variabler Wert then
Ausgang xyz := true;
end_if;

So einfach scheint mir das bei der SCL Programmierung nicht zu sein. Gibts für sowas ein Beispielprogramm oder irgendwas in der Art oder hat von Euch jemand eine sinnvolle Antwort.
Ich wäre für jeden Tip dankbar.

Besten Dank

Flo
 
:confused::confused::confused:

Hallo,
die Code-Syntax von Codesys-ST und Step7-SCL ist erstmal nicht gewaltig unterschiedlich. Du solltest also im Wesentlichen dein Programm in SCL ähnlich realisiert bekommen ...

Vielleicht stellst du uns dann doch mal deinen Code-Ansatz zur Verfügung ...

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
du könntest die analogwerte mit dem FC105 skalieren und damit einer physikalischen größe gleichsetzen.

das ist kein reine SCL-problem, sondern ein verständnisproblem zu analogwerten.

schau mal in die FAQ.
 
Code:
FUNCTION "SCAL_IIR" : VOID
TITLE   ='SCAL_IIR' 
NAME    : SCAL_IIR 
AUTHOR  : FSwierza 
FAMILY  : SCAL 
VERSION : '0.5' 
//KNOW_HOW_PROTECT 
// Typical-Attribute
{
  S7_m_c:='false';
  S7_blockview:='big'
}
VAR_INPUT      
IN         
   {
     S7_dynamic  := 'true'          
   }  :   INT := 0;             //ROH-EINGANGSWERT
IN_HIGH_I         
   {
     S7_dynamic  := 'true'          
   }  :   INT := 27648;         //Maximalwert Eingang (gleichzeitig MAX_LIMIT)
IN_LOW_I         
   {
     S7_dynamic  := 'true'          
   }  :   INT := -27648;        //Minimalwert Eingang (gleichzeitig MIN_LIMIT)
OUT_HIGH_I         
   {
     S7_dynamic  := 'true'          
   }  :   INT := 100;           //Abgebildeter Maximalwert am Ausgang (ggf. BEGRENZT)
OUT_LOW_I          
   {
     S7_dynamic  := 'true'          
   }  :   INT := -100;         //Abgebildeter Maximalwert am Ausgang (ggf. BEGRENZT)
S_STOER 
   {
     S7_dynamic  := 'true';
     S7_string_0 := 'S_OFF';
     S7_string_1 := 'S_ACTIV'            
   }  : BOOL := FALSE;          //Q_STOER Ausgang aktivieren/deaktivieren   
 
END_VAR
 
VAR_OUTPUT
OUT        
   {
     S7_dynamic  := 'true'          
   }  :   REAL   :=0.0;             //Scalierter Ausgang 
STATUS        
   {
     S7_dynamic  := 'true';
     S7_string_0 := 'NULL';
     S7_string_1 := 'IN_LOW';   
     S7_string_2 := 'IN_HIGH';  
     S7_string_3 := 'IP_ERROR';
     S7_string_4 := 'OP_ERROR';
     S7_string_5 := 'HW_ERROR'                      
   }  :   BYTE :=0;             //Status
 
Q_STOER 
   {
     S7_dynamic  := 'true';
     S7_string_0 := 'NORMAL';
     S7_string_1 := 'STOER'            
   }  : BOOL := FALSE;          //Statusbit Stoerung liegt an 
 
END_VAR
 
VAR_TEMP
    IN_HIGH            :   REAL ;
    IN_LOW             :   REAL ;    
    OUT_HIGH           :   REAL ;    
    OUT_LOW            :   REAL ;
    IN_REAL            :   REAL ;
END_VAR
 
 
BEGIN 
//Eingangstyp umsetzen    
IN_REAL  :=   INT_TO_REAL(IN);   
 
 
//Status zurücksetzen  
STATUS:= 0;  
 
 
//Grenzen umsetzen
IN_HIGH  :=   INT_TO_REAL(IN_HIGH_I);
IN_LOW   :=   INT_TO_REAL(IN_LOW_I);    
OUT_HIGH :=   INT_TO_REAL(OUT_HIGH_I);    
OUT_LOW  :=   INT_TO_REAL(OUT_LOW_I);
 
 
//Eingangssignal nach unten begrenzen
IF IN_REAL  <  IN_LOW    THEN  
    IN_REAL := IN_LOW  ; 
    STATUS  := 1;
END_IF;
 
//Eingangssignal nach oben begrenzen
IF IN_REAL  >  IN_HIGH   THEN  
    IN_REAL := IN_HIGH ; 
    STATUS  := 2;
END_IF;
 
 
//Parametrierung fehlerhaft
IF  IN_HIGH <= IN_LOW   THEN  
    IN_REAL :=0 ; 
    STATUS  := 3;
END_IF;
//Parametrierung fehlerhaft
IF  OUT_HIGH <= OUT_LOW   THEN  
    IN_REAL :=0 ; 
    STATUS  := 4;
END_IF;
 
 
//Hardwarefehler unabhängig von Fehler OBs erkennen
IF IN = 32767    THEN  
    STATUS:= 5;     
END_IF;
 
//Störung DIGITAL ausgeben
IF (NOT (STATUS = B#0) AND S_STOER)  THEN 
      Q_STOER := TRUE; 
   ELSE  
      Q_STOER := FALSE; 
END_IF; 
 
 
//Ausgangssignal berechnen
(* OUT:=  (OUT_MX - OUT_MN) * (IN - IN_MN) / (IN_MX - IN-MN) + OUT_MN; *)    
OUT := ((OUT_HIGH-OUT_LOW) * (IN_REAL-IN_LOW) / (IN_HIGH - IN_LOW) + OUT_LOW);
 
END_FUNCTION


Was in der {Klammer} steht brauche ich nur für CFC und kann daher auch weggelassen werden.

27648 = 100% = 10Volt = 20mA
32767 = 118% ....

0 = 0% = 0 Volt = (0)/4 mA

-27648 = - 100% usw.

wie auch immer man begrenzt will.



SCAL_IIR heißt übrigens

I(nterger) Eingangswert
I(nterger) Grenzwerte
R(eal) Ausgangwert

d.h. der FC ist damit für EW/PEW gedacht.



Gruß


Frank
 
Zuletzt bearbeitet:
Hallo flotec,
habe hier mal ein einfaches Beispiel. Der OB1 (sorgt für den schnellstmöglichen Zyklus bei der S7-300/400) ruft die FC1 zyklisch auf. In der FC1 wird ein Messwert vom PEW754 eingelesen und ins MD50 normiert. Der digitalisierte Analogwert 0 bis 27648 (Ende Nennbereich bei den meisten Analogbaugruppen) wird in 0 bis 100 normiert. Ist der normierte Wert größer als 60 wird die Anzeige 1 eingeschaltet.

Code:
FUNCTION FC1:VOID
//Messwert ins Real-Format normieren
IstwertReal:=3.616898e-3 * IstwertPEW;
IF IstwertReal > 60 THEN
    Anzeige1:=TRUE;
ELSE
    Anzeige1:=FALSE;
END_IF;
END_FUNCTION


Code:
ORGANIZATION_BLOCK OB1
VAR_TEMP
    info : ARRAY[0..19] OF BYTE;
END_VAR
FC1();
END_ORGANIZATION_BLOCK

globale Symboltabelle
Code:
Anzeige1     A4.0    BOOL   Anzeige 1
IstwertPEW   PEW754  INT    Digitalisierter Messert 0 bis 27648
IstwertReal  MD50    REAL   normierter Messwert im Real-Format


Gruß
Earny
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So, erst mal vielen Dank an Euch alle für die flotten Antworten. Habs jetzt hin bekommen ohne etwas zu normieren. Hab nicht gecheckt das PEW 752 als INT in der Symboltabelle zu deklarieren. Kann diesen Wert jetzt in einem FB verwenden und weiter verarbeiten.

Jetzt kommt auch schon mein nächstes Problem. Jetzt möchte ich diesen Wert 3200 bis 32767 in eine Zeit umwandeln. Bei Codesys sieht das ganze so aus:

(*Zeiteinstellung über externes Poti*)
IF NachlaufHub_IW > 6700 THEN
Temp_DWORD:=0;
ELSE
Temp_DWORD:=(6700-NachlaufHub_IW)*2/5;
END_IF;
T_NachlaufHubAb.PT:=DWORD_TO_TIME (Temp_DWORD);

nur kann ich das bei SCL nicht verwenden. Hab im Handbuch, in der SCL Hilfe und im Forum FAQ geschaut. Finde leider nix brauchbares.
Bin für jede Hilfe dankbar.

Grüße

Flo
 
Hallo,
die Anweisung "DWORD_TO_TIME" kennt SCL nicht - ist aber auch nicht so schlimm. Das kannst du auch genausogut mit der AT-Sicht erledigen :
Code:
VAR_TEMP
    Temp_DWORD : DWORD ;
    Time_DWORD AT Temp_DWORD : Time ;
END_Var 
 
und im Code dann :
 
Temp_DWORD:=(6700-NachlaufHub_IW)*2/5;
T_NachlaufHubAb.PT:= Time_DWORD  ;
Die Anweisung AT (siehe hierzu auch die SCL-Hilfe) stellt eine andere Sichtweise der gleichen Variablen her.

Ich denke, das "T_NachlaufHubAb" ein IEC-Timer vom Typ SFB4 (vermutlich) ist und im VAR-Bereich deines FB's deklariert wird, ist dir bekannt (?) ...

Gruß
LL
 
Hallo Miteinander,

Vielen, vielen Dank Euch allen. Habs mit Eurer Hilfe zum laufen gebracht.
Übung macht den Meister. :)

Grüße

Flo
 
Zurück
Oben