SCL-Programmfehler Wer kann helfen?

S

sps_nath

Guest
Zuviel Werbung?
->Hier kostenlos registrieren
Das soll ein Programm zum Einlesen eines Analogwertes sein
Es funktioniert soweit auch aber der Stringscan am Ende will nicht so wie ich es gerne will.
Obwohl weiter hinten ein Minuszeichen steht wird meine Variable Ex_minus niemals true
Kann mir jemand einen Tip geben sonst verzweifle ich bald.
Compilerfehler gibt es keine.


Function_Block FB1

VAR_TEMP
Analogwert: WORD;
Ergebnis: STRING[ 20 ];
Help, Lauf, Laenge: INT;
Wert: REAL;
Ex_minus: BOOL;
END_VAR

BEGIN

Analogwert := PEW760 ;
Help :=WORD_TO_INT (Analogwert);

// Normierung des Wertes zwischen –104 und +104 °C Ergebnis ist ein //REALwert
Wert:=((-104.0 * ( 2048 – Help)) + ( Help * 104.0)) / 2048 ;

// Wert in einen String umwandeln
Ergebnis := R_STRNG( IN:= Wert);
// Stringlänge
Laenge := LEN( S:= Ergebnis);

// Der String sieht jetzt ungefähr so aus :
// -1.234567e-001
// Und ich möchte den String scannen um heraus zu finden ob ein Minus vorm Exponent steht
// Das erste Minus will ich ignorieren deswegen ab Position 2
FOR Lauf:= 2 TO Laenge DO

IF MID( IN:= Ergebnis, L:= 1, P:= Lauf) = ‘-‘ THEN
Ex_minus:= true;
Exit;

ELSE
Ex_minus:= false;
END_IF;
END_FOR;
// Auswertung der Variablen Ex_minus


End_Function_Block
 

Onkel Dagobert

Well-known member
Beiträge
4.823
Punkte Reaktionen
874
fehler- oder mangelhafte Statusanzeige

Hallo sps_nath,

es scheint sich um eine fehler- oder mangelhafte Statusanzeige zu handeln. Das "Ex_minus = FALSE" wird noch aus dem vorherigem Schleifendurchlauf angezeigt. Wenn du nach "END_FOR" noch einmal "Ex_minus" abfragst, erhältst du das richtige Resultat. (S7-SCL V5.1 SP5).

Gruß, Onkel
 
OP
S

sps_nath

Guest
Zuviel Werbung?
->Hier kostenlos registrieren
Vielen Dank erst mal für die Hilfe.
Aber wenn ich ehrlich bin leuchtet mir das nicht so richtig ein.
Schließlich wird doch die Schleife über das Exit verlassen wenn ein Minus im String ist.
Wieso sollte ich dann noch einmal ex_minus abfragen?
 

Ingo dV

Well-known member
Beiträge
61
Punkte Reaktionen
0
Moin

Du hast 2 byte Kopfdaten im String, deshalb musst du nicht bei 2 sondern bei 4 anfangen zu suchen
 

Onkel Dagobert

Well-known member
Beiträge
4.823
Punkte Reaktionen
874
nur zum Test noch einmal abfragen

Deine Schleife funktioniert richtig! Die Afrage deines "ex_minus" solltest du nur einmal testweise nach "END_FOR" einfügen, um dich von dem Ergebnis "ex_minus = true" zu überzeugen. Die Statusanzeige zwischen "ELSE" und "END_FOR" wird beim Verlassen der Schleife über "EXIT" in der aktuellen SCL-Version leider nicht aktualisiert! Das verwirrt schon manchmal ein bisschen.

Die von Ingo angesprochenen 2 Byte Kopfdaten sollten eigentlich von der Funktion "MID" berücksichtigt werden, bin mir da jedoch nicht so ganz sicher.

Betreibst du diesen enormen Aufwand eigentlich nur um zu überprüfen ob der Realwert zwischen -1.0 und +1.0 liegt? Oder machst du das nur so zum Probieren?

Gruß, Onkel
 

Ingo dV

Well-known member
Beiträge
61
Punkte Reaktionen
0
Zuviel Werbung?
->Hier kostenlos registrieren
Moin

1. Wenn du z.B. -1234567e-001 als String wandelst, bekommst du den String als ||-0.1234567e+000. Die Ersten beide Bytes sind die Kopdaten und werden vom MID Baustein NICHT (wie zuerst gedacht) berücksichtigt.

2. Die mit MID erzeugte Zeichenkette hat ebenfalls 2 Kopfdatenbytes. Das Ergebnis von z.B. L=1, P=2 würde in inserem Bspl. ||0 (3Bytes) sein.
 
OP
S

sps_nath

Guest
Vielen Dank nochmal !
Jetzt bin ich etwas schlauer. Also liegt der Fehler an der SCL-Version, die die Anzeige der Variable nach dem Else nicht aktualisiert. Da kann ich ja lang warten.

Übrigens mache ich das um die Temperatur abhängig von einem PT100 an einer 7Segment-Anzeige auszugeben. Ich denke wenn ich diesen Real-Wert in einen String wandel und mir die Stellen die ich brauche aus dem String "herausschneide" komme ich mit den Stringfunktionen am schnellsten ans Ziel.
Das Vorzeichen des Exponenten muss ich für den Fall berücksichtigen das der Wert zw. -0.9 und
+0.9 liegt. ansonsten ist der Exponent immer positiv.
 

Zottel

Well-known member
Beiträge
2.299
Punkte Reaktionen
277
Da eine 7-Segmentanzeige meist ohne Fliesskomma arbeitet, wäre es nicht einfacher, die Integers für die Stellen auf die Anzeige zu schreiben? Ohne den String?
 
OP
S

sps_nath

Guest
Zuviel Werbung?
->Hier kostenlos registrieren
Das Problem liegt an dem Analogwert der zwischen 0 und 2047 liegt.
Den muss ich auf einen Temperaturbereich normieren. Die dabei entstehende Zahl ist nun einmal
vom Type REAL.
Ich brauche 3 Stellen um eine Auflösung von 0.1 °C zu errechen.
 

Zottel

Well-known member
Beiträge
2.299
Punkte Reaktionen
277
sps_nath schrieb:
Das Problem liegt an dem Analogwert der zwischen 0 und 2047 liegt.
Den muss ich auf einen Temperaturbereich normieren. Die dabei entstehende Zahl ist nun einmal
vom Type REAL.
Nicht zwangsläufig.
L PEW...
L 104 //Dein max-wert
*D
L 2047
/D
macht das mit ganzen Zahlen.
Wenn Du die Zehntel brauchst, nimmst Du halt mit 1040 statt mit 104 mal. Multiplikation vor Division ergibt mehr gültige Bits.
Egal wie, hier wird abgrundet. Um das zu vermeiden, nimmst Du mit 2080 (2*1040) mal, addierst zum Ergebnis einst und teilst durch 4094 (2*2047).
 

volker

Supermoderator
Teammitglied
Beiträge
5.468
Punkte Reaktionen
935
ich finde auch, dass du mächtig aufwand betreibst um einen temp-wert zu normieren.
was zottel schreibt ist auf jeden fall besser. du kannst aber auch den normierungsbaustein aus der standart-lib benutzen (ich glaub das war fc 105/106). der ist zwar normal nur für die konvertierung s5->s7 gedacht aber dort kannst du einfach deine grenzen eingeben und bekommst am ende das was du haben willst.

PS: leute die sowas in scl programmieren sind für mich keine "vernünftigen" sps-programmierer. ihr solltet lieber einen anderen beruf wählen und bei euerem c++ etc. bleiben.
ein vernünftiges strukturiertes programm bekomme ich durch eigene überlegeungen und nicht durch einen compilerlauf. (nicht, dass man bei der programmierung in scl nicht denken muss, aber das ist halt nicht zu vergleichen mit der normalen programmierung einer sps)
 

Onkel Dagobert

Well-known member
Beiträge
4.823
Punkte Reaktionen
874
Zuviel Werbung?
->Hier kostenlos registrieren
real rechnen und dann runden

Hallo sps-nath,

Um Rundungsfehler zu vermeiden, würde ich das Normieren mit Realwerten durchführen, wegen der Kommastelle das Real-Ergebnis mit 10.0 multiplizieren und anschließend auf DINT runden (ROUND).

@volker
Ich finde es völlig in Ordnung dass du zu SCL deine eigene Meinung vertrittst. Deine Begründung ist allerdings, bei allem Respekt, ziemlich lächerlich. Und wie du hier SCL-Anwender abstempelst, halte ich für eine enorm starke Anmaßung! Es macht sich ja auch niemand über FUP-Programmierer lustig. Entschuldige, aber das musste ich jetzt mal los werden. Nein, der Onkel ist nicht böse :roll: .

Einen schönen Advent, Onkel
 
Oben