Normierung in SCL < Problem >

Pfalz

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

ich will mit einer SCL-Quelle eine Funktion zur Normierung eines Wertes erstellen.

Leider bekomme ich als Berechnung der Temperatur immer eine Null!

Wo liegt mein Fehler? Ich steh total aufm Schlauch.:confused:
Ich habe die Gleiche Formel in AWL, direkt in ein FC geschrieben und die Funktioniert.

Code:
FUNCTION FC50 : DINT

VAR_TEMP        // temporäre Variablen
    zwT_max: DINT;   // Zwischenwert Tmax in 1/1000000°C
    zwT_min: DINT;   // Zwischenwert Tmin in 1/1000000°C
    T_ist1: DINT;   // IST-Temperatur in 1/1000000°C      
END_VAR


VAR_INPUT
    PEW: INT;       // PEW vom Temperatursignal
    UGPEW: INT;    // PEW UG 5% = 0,45V
    OGPEW: INT;    // PEW OG 95% =8,55V 
    T_min:  INT;    // Tmin vom Temperaturbereich
    T_max:  INT;    // Tmax vom Temperaturbereich
END_VAR


VAR_OUTPUT
    T_ist:  INT;    // Ist Temperatur 
END_VAR    


// Anweisungsteil    
    zwT_max:= T_max*1000000;
    zwT_min:= T_min*1000000;
      
    T_ist1:= (PEW - UGPEW) * ((T_max - T_min) / (OGPEW - UGPEW)) + T_min;  // Normierung des PEW in IST Temperatur
    T_ist1:= T_ist1/100000;  // Temperatur in 1/10°C
    T_ist:= DINT_TO_INT(T_ist1);
    
    FC50 := T_ist;
    
    
END_FUNCTION
Vielen Dank für eure Unterstützung
 
Hallo Gerhard,
so gehts mir auch.

mit PEW meine ich den INT eines Eingangskanals 0...27648 Digits

Ich würde gerne einen Screen-shoot des Bausteins einfügen aber ich weis nicht wie das funktioniert.
 
Hast du alle Werte sinnvoll vorbelegt?
Wo hast du die 0 Grad? Am T_ist oder der Returnwert?

Also ich würde einfach mit debug kompilieren, dann kannst du dir die Werte und das Ergebnis Online anzeigen lassen.


bike
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zeig mal bitte deinen AWL-Baustein, der die gleiche Funktion macht und funktioniert.

Vielleicht liegt es daran, dass du die ganze Zeit mit Int bzw. Dint Werten rechnest.
 
Hi

also ich bin zwar auf dem gebiet nicht ganz versiert aber ich würte sagen der fehler liegt in der folgenden Zeile:

T_ist1:= (PEW - UGPEW) * ((T_max - T_min) / (OGPEW - UGPEW)) + T_min; // Normierung des PEW in IST Temperatur

wenn du nicht sicherstellen kannst das bei einer Teilung von Zahlen immer gerade (keine Kommazahlen) Zahlen bei rumkommen solltest du vollständig mit REAL Zahlen arbeiten und nicht mit INT bzw. DINT

Gruß
SK
 
Zuletzt bearbeitet:
das sieht mir aus, wie ne 0..10V messung?!

versuch mal das:

Code:
*
    T_ist1: = (((OGPEW - UGPEW) * PEW) / 27648) + UGPEW
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Erstmal vielen Dank für eure Antworten

@ vierlagig

Bei dieser Funktion ist es egal ob es 0...10V, 0...20mA oder 4...20mA oder irgend eine andere Größe handelt. Man kann eine x beliebige Größe in eine andere Größe normieren.

@ SKg

Der Knackpunkt ist aber, dass ich gerade nicht in REAL Zahlen rechnen soll.
Zykluszeit etc. Ja das ist totaler quatsch, aber so ist die Aufgaben Stellung nun mal. ;)

@ bike

Wie kann ich das machen, ich bekomme die Fehlermeldung:
Der Baustein ist nicht testbar!
Es wurde keine Debug Info erstellt.

Gibts da was in der Hilfe?

@ Dotzi

Code:
NW1 Temperatur in 1/1000000°C
      L     #T_min
      ITD   
      L     L#1000000
      *D    
      T     #T_min_DINT

      L     #T_max
      ITD   
      L     L#1000000
      *D    
      T     #T_max_DINT

NW2 Normierung der Temperatur
      L     #T_max_DINT
      L     #T_min_DINT
      -D    
      T     #zw1                        // T_max - Tmin

      L     #OGPEW
      ITD   
      L     #UGPEW
      ITD   
      -I    
      T     #zw2                        // IN_max - IN_min

      L     #zw1
      L     #zw2
      /D    
      T     #zw3                        // zw1 / zw2

      L     #PEW
      ITD   
      L     #UGPEW
      ITD   
      -D                                // IN_ist - IN_min

      L     #zw3
      *D    
      L     #T_min_DINT
      +D    
      T     #T_ist_DINT

NW3 Umrechnen der 1/1000000 in 1/10°C
      L     #T_ist_DINT
      L     L#100000
      /D    
      T     #T_ist
 
Wie kann ich das machen, ich bekomme die Fehlermeldung:
Der Baustein ist nicht testbar!
Es wurde keine Debug Info erstellt.

Gibts da was in der Hilfe?
Extras > Einstellungen > Compiler > nun den Haken "Debug Info erstellen" setzen, speichern und übertragen.
Jetzt kannst Du den Baustein online anschauen.

Wenn Du wieder Offline gehen willst, dann erneut auf die Brille und explizit noch mal auf Test > Test beenden (warum auch immer, ist halt so).
 
Normierung

Hi

also ich bin zwar auf dem gebiet nicht ganz versiert aber ich würte sagen der fehler liegt in der folgenden Zeile:

T_ist1:= (PEW - UGPEW) * ((T_max - T_min) / (OGPEW - UGPEW)) + T_min; // Normierung des PEW in IST Temperatur

wenn du nicht sicherstellen kannst das bei einer Teilung von Zahlen immer gerade (keine Kommazahlen) Zahlen bei rumkommen solltest du vollständig mit REAL Zahlen arbeiten und nicht mit INT bzw. DINT

Gruß
SK

Im Prinzip richtig aber es soll ja anscheinend nicht mit Fliesskomma gerechnet werden.

Wenn die Eingangssignale den vollen Wertebereich eines INT belegen, muss es bei einer Multiplikation zwangsweise zu einem Überlauf kommen. Was die SPS Implementation in diesem Falle daraus macht (manche setzen automatisch ein Fehler Flag), weiss ich nicht, aber es kommt Schrott raus, wenn man es nicht abfängt, den Schrott danach noch einmal dividieren erzeugt dann das nächste Problem.

Also: Eingangswerte von INT in DINT casten, mit DINT rechnen und dann das Ergebnis ganz am Ende wieder in INT verwandeln.

Dabei auch noch beachten, wenn es komplizierter wird: Zuerst Multiplizieren, danach dividieren, sonst geht die Genauigkeit weg. In Obigem Beispiel heisst das, die Klammern sind falsch !!!
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
du solltest vielleicht statt.
T_max und T_min

Code:
zwT_max:= T_max*1000000;
zwT_min:= T_min*1000000;
diese werte einsetzen.oder brauchst du die nicht?


Ich habe die Gleiche Formel in AWL, direkt in ein FC geschrieben und die Funktioniert.

da hast du aber immer die werte zuerst in DINT umgewandelt bevor du damit gerechnet hast.ist das bei SCL nicht notendig?
ich meine
Code:
T_ist1[COLOR=red](DINT)[/COLOR] := (PEW[COLOR=red](INT)[/COLOR] - UGPEW[COLOR=red](INT)[/COLOR]) * ((T_max[COLOR=red](INT)[/COLOR] - T_min[COLOR=#ff0000](INT)[/COLOR]) / (OGPEW[COLOR=#ff0000](INT)[/COLOR] - UGPEW[COLOR=#ff0000](INT)[/COLOR])) + T_min[COLOR=#ff0000](INT)[/COLOR];
 
Zuletzt bearbeitet:
Jetzt gehts

@ Paule
Das ist ne super Funktion!

@ RobiHerd & Gerhard K
ich habe alle Zwischenwert Variablen (zw) als DINT deklariert, nur nicht in die Formel geschrieben. Daher wurde die Zahl bei der Division kleiner 1. :oops:
Mit Gleitpunkt Zahlen hätte man dies sofort gesehen nur leider nicht mit ganzen Zahlen.

Code:
    zwT_max:= T_max*1000000;
    zwT_min:= T_min*1000000;
      
    T_ist1:= (PEW - UGPEW) * ((zwT_max - zwT_min) / (OGPEW - UGPEW)) + zwT_min;  // Normierung des PEW in IST Temperatur
    T_ist1:= T_ist1/100000;  // Temperatur in 1/10°C
    T_ist:= DINT_TO_INT(T_ist1);
In SCL kann man mit INT und DINT rechnen, es wird erst gemekert, wenn das Ergebniss > 32000 ist und als INT deklariert ist.

Vielen Dank euch allen.
Bin von diesem Forum ganz begeisteret!!!
 
Zurück
Oben