Step 7 IBIS LED Anzeige ansteuern

Zuviel Werbung?
-> Hier kostenlos registrieren
Das ist ganz normales AWL was du auch mit deiner Version verwenden kannst.
Du kannst den Code über eine AWL-Quelle wieder zu einem Baustein übersetzen.
Im Simatic-Manager fügst du in deinem Projekt im Ordner "Quellen" eine neue AWL-Quelle ein. Die Quelle öffnest du, und fügst dort den Code aus meinem Anhang ein.

Dann gehst du in die Symboltabelle, und fügst das Symbol "IBIS_string_erzeugen" (ohne Anführungszeichen) ein, mit der Adresse FC xy. Für xy gibst du eine freie FC-Nummer an.
Dann kannst du die AWL-Quelle übersetzen (Menü Datei -> Übersetzen), und erhältst dann im Bausteinordner einen FC. Diesen kannst du dann in deinem Programm aufrufen.
 
Bekomme beim übersetzen der Quelle zwei Fehler:
F Ze 000197 Sp 013: Syntaxfehler bei #str.
F Ze 000197 Sp 018: Syntaxfehler bei 22.
Es wird folgende Zeile markiert:
T #str[22];// Prüfsumme
 
Ja, die 0 hinter dem T im Kopf ist die Taktzeit und gehört nicht zum Messwert.

Das habe ich angepasst und dabei beim XOW eine Zeile davor das ; vergessen.

Nun habe ich übersetzt und den Baustein übertragen.

Jetzt möchte das Programm im OB1 das ich folgendes eingebe:

Wert:= z.B. 85.12

Len: = ? wieso, ich dachte das betimmt der FC
str:= ???
 
Der Parameter str ist der String.
Wenn ich das richtig gelesen habe, hast du diesen im DB11 angelegt. Am Besten ist wenn du symbolisch programmierst. Dazu musst du dem DB11 in der Symboltabelle einen symbolischen Namen verpassen, z.B. "DB_Ibis_Daten".
Wenn dein String in diesem DB dann das Symbol "ibis_string" hat, dann schreibst du an den Aufruf:
str := "DB_Ibis_Daten".ibis_string

An den Ausgang len kannst du eine Variable anlegen, die du an den Eingang LEN des Sendebausteins weitergeben kannst. Z.B. ein Merkerwort oder eine temporäre Variable.

Versuche lieber den Bausteincode zu verstehen und ihn an deine Gegebenheiten anzupassen, anstatt ihn 1:1 einsetzen zu wollen. Es kommen sicher noch mehr Dinge die du gerne anders hättest.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo mal wieder,
mir ist beim testen der Weitenmessung aufgefallen, das einige Werte von der LED Anzeige nicht oder falsch angezeigt werden.
Ich habe den FC von Thomas verwendet.
Folgendermaßen habe ich getestet:
den DB in dem der Realwert gespeichert wird und den der FC als "Wert" verwendet, habe ich mit der Brille beobachtet und gleichzeitig mit dem Wert auf der LED Anzeige verglichen.
das habe ich Impuls für Impuls (bis 3,00 Meter) zwei mal durchgespielt.
folgendes kam dabei heraus:
Wert im DB=>Wert auf Anzeige (nur die Werte wo etwas nicht passte, alle anderen Werte sind OK)
0.53=>0.52
0.59=>0.58
1.05=>1.04
1.06=>1.05
1.17=>1.16
1.18=>1.17
2.09=>2.08
2.10=>2.09
2.11=>2.10
2.12=>2.11
2.34=>2.33
2.35=>2.34
2.36=>2.35
2.37=>2.36
ich habe bei den Fehlwerten mehrere Übertragungsimpulse gewartet, doch die Werte blieben falsch.
hat jemand eine Idee woran das liegen kann?
Gruß Christian
 
Das ist ja in der Tat so, habe ich echt nicht mit gerechnet :(
Ich kann aber momentan noch nicht detailliert erklären warum das passiert. Ich hätte gedacht, dass es bei deinem Wertebereich und Anzahl der Stellen da noch keine Probleme geben sollte. Das muss ich mir erst genauer zu Gemüte führen.

Bei meinem Code kannst du das korrigieren indem du am Anfang um 3 Stellen verschiebst und dann wieder eine zurück.
Code:
// Dezimalstelle verschieben 100.0 == 10000
      L     #Wert
      L     1.000000e+003               // Kommastelle verschieben
      *R    
      TRUNC                             // Nachkomma abschneiden
      L     L#10
      /D    
      T     #inWertDInt
Ohne jetzt beweisen zu können dass es für alle Werte von 0.00 bis 999.99 korrekt ist.

Eigentlich gibt es eine Funktion in der Standardlib welche eine Real-Zahl in einen String wandelt. Diese nutzt ein anderes prinzipiell genaueres Verfahren. Damit musst du den Ergebnisstring aber erst wieder formatieren (wenn du eine feste Anzahl Vorkommastellen mit führenden Nullen haben willst) und Strings zusammenkopieren. Ohne SCL ist das aber sehr unschön handzuhaben, darum habe ich diese manuelle Version in das Beispiel kopiert.
 
Das ist ja in der Tat so, habe ich echt nicht mit gerechnet :(

Ich kann aber momentan noch nicht detailliert erklären warum das passiert. Ich hätte gedacht, dass es bei deinem Wertebereich und Anzahl der Stellen da noch keine Probleme geben sollte. Das muss ich mir erst genauer zu Gemüte führen.
Hätt ich mir eigentlich auch nicht erwartet.

Wie du siehst wird 0.53*100.0 -> TRUNC -> zu 52.
TRUNC_052.jpg

REAL 0.53 entspricht zwar DOUBLE 0.5299999713897705.
REAL 53 ist aber auch DOUBLE 53.
Scheint so als würde beim *100.0 die Ungenauigkeit mit übernommen und 52.9999 draus.

Komisch...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Was ich jetzt gefunden habe, liegt das an der Maschinengenauigkeit
http://de.wikipedia.org/wiki/Maschinengenauigkeit

Die Ungenauigkeit ist ein Mantissenbit.
Bei 53.0 ist der Exponent 2^5
Das wäre dann 2^5 * 2^23 = 0.000004

Das Ergebnis nach Multiplikation ist genau um dieses epsilon zu klein d.h. 53 - 0.000004 und beim TRUNC bleiben dann 52 übrig.

Bei 999.99 hat man den höchsten zu erwartenden Exponent mit 2^9. Dementsprechend könnte 0.00006 addiert werden und es sollte passen.
Die Frage ist nur, ob es auch mal vorkommen kann, dass der Wert um dieses Epsilon zu groß ist? Wobei das nicht stören sollte, da nach der Multiplikation mit 100.0 die unteren Stellen "frei" werden.

Ich habe da nicht mit solchen Problemen gerechnet, denn 5+2, also 7 tragende Stellen sollten ja eigentlich noch in Real zu berechnen sein.
 
Es sollte reichen, das TRUNC durch RND zu ersetzen:
Code:
// Komma um 2 Dezimalstellen verschieben 100.00 == 10000
      L     #Wert
      L     1.000000e+002               // Kommastelle verschieben
      *R
      RND
      T     #inWertDInt

Wo kommt die REAL-Zahl eigentlich her? Wie wird sie berechnet? Wäre es vielleicht genauer, die Weitenmessung (?) in Ganzzahl zu rechnen?

Harald
 
Bei meiner Weitenmessung zähle ich die Impulse (ein Impuls = 1cm) und wandle anschließend von Int > Dint > Real und teile durch 100 um auf Meter zu kommen.
Ich kann also auch den Int Wert (in cm) in meinen DB übertragen.

Christian
 
Zurück
Oben