CASE_OF

Zuviel Werbung?
-> Hier kostenlos registrieren
Und was soll das bringen? Welchen Vorteil?
Hab ich doch schon woanders erzählt.. ich persönlich finde es leserlicher dadurch..
Ich hab doch nur meine persönliche Meinung mitgeteilt.. jeder hat so seine Eigenheiten wie er bestimmte Dinge eben programmiert, das ist auch gut so.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Es hat keinen Vorteil - aber auch keinen Nachteil ... und wenn er es für sich doch schöner / übersichtlicher findet ... ;)
Also mir stellen sich bei folgendem Satz und dem Code die Nackenhaare auf:

1713424610267.png
Ich meine, was bringt man einem Neuling da bei? Mach einfach überall Klammern drüber dann ist es besser...
Aber gut, jeder wie er meint.
 
Zuletzt bearbeitet:
So, jetzt zur Frage:
Ja, Dein Eingang liefert (in dem Beispiel) 0 bei 0V und 32767 bei 10V. Wenn Du also 4095 vom Eingang geliefert bekommst, dann rechnest Du:
4095 / 32767 = 12.5% --> Prozentualer "Ausschlag" des Eingangs vom Meßbereich
Das Ergebnis multiplizierst Du mit dem elektrischen Meßbereich (hier 10V): 1.25V wird am Eingang gemessen.
warum multipliziere ich mit meinem Messbereich, das SPS hat schon mir den 0-10V umgewandelt :unsure:

also wenn zum Beispiel
mein Digit Wert hat 5bar das entspricht 5V an meinem Analogsignal dann mein Sps liest mir 16383
ich dividiere den Wert durch den Hersteller gegebene Nummer dann kommt mir den 5V wieder und wenn ich das in 100% haben möchte dann multipliziere ich es mit 10 dann sollte es funktionieren, aber bei mir kommt zwischen 0-10 raus, bis ich mit 100 multipliziere dann kommt richtig raus.
bestimmt hat er mit meinem DATEN TYP was zu tun oder ?
23.png
Schau dir am besten noch einmal in Ruhe das FAQ von @oliver.tonn zum Thema Skalierung an. Da ist alles wunderbar beschrieben
"Ich habe es tatsächlich mehrmals gelesen, aber bei der Umsetzung stoße ich immer wieder auf Probleme.":(
Ich gebe dir für etwas anderes noch mal einen Tipp:

In folgendem Code, was passiert wenn PercentLevel die Wertigkeit 25 oder 1 hat? Überdenke das noch einmal genau.

Anhang anzeigen 77360
Danke für den Tipp <3
 
warum multipliziere ich mit meinem Messbereich, das SPS hat schon mir den 0-10V umgewandelt :unsure:
Weil es eventuell das ist, was man haben möchte. Nicht jeder möchte am Ende % als Ergebnis haben, sondern eventuell den Druck und dann muss man halt mit dem maximalen Druck den der Sensor messen kann multiplizieren.
Bei einem Sensor der 0-5 Bar misst und eine Spannung von 0-10V ausgibt, die die SPS wiederum in 0 - 32767 umsetzt wäre die Formel:
Wert der an SPS übergeben wurde * 5 Bar / 32767
Bei einem Wert von 4095 kämen dann rund 0,625 Bar raus.
Bei 16384 wären es rund 2,5 Bar.
 
also wenn zum Beispiel
mein Digit Wert hat 5bar das entspricht 5V an meinem Analogsignal dann mein Sps liest mir 16383
ich dividiere den Wert durch den Hersteller gegebene Nummer dann kommt mir den 5V wieder und wenn ich das in 100% haben möchte dann multipliziere ich es mit 10 dann sollte es funktionieren, aber bei mir kommt zwischen 0-10 raus, bis ich mit 100 multipliziere dann kommt richtig raus.
bestimmt hat er mit meinem DATEN TYP was zu tun oder ?
Du hast noch ein Problem mit den Begriffen.
Deine 5 Bar ist die (gemessene) physikalische Größe. Aus der macht Dein Sensor 0-5 V (0V = 0%, 5V = 100%).
Die Digits ist der Wert den die analoge Eingangskarte an die SPS meldet (0V = 0, 10V = 32767).
Da Du nur die % benötigst brauchst Du nur die Digits, in Deinem Fall entspricht 0 = 0% und 16383 (oder 16384) = 100% und damit, für den Dreisatz, 32767 = 200%.
Darüber musst Du jetzt einen Dreisatz bilden um die % zu berechnen und bitte immer mit den richtigen Typen.
Die Digits erst in eine REAL-Zahl wandeln und bei den Konstanten immer mit ".0" arbeiten, also nicht "/32767", sondern "/32767.0", damit die Konstante als Fließkommazahl interpretiert wird.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also mir stellen sich bei folgendem Satz und dem Code die Nackenhaare auf:

Anhang anzeigen 77365
Ich meine, was bringt man einem Neuling da bei? Mach einfach überall Klammern drüber dann ist es besser...
Aber gut, jeder wie er meint.

Ich meine mich zu erinnern, dass in den Nexeed Programmiervorgaben von Bosch eine solche Klammersetzung vorgegeben ist. Dann kommen aber noch ein paar Enter und Leerzeichen/Tabs mit dazu, müsste imho so aussehen:

Code:
doValveSilo1 := (     diSilo1Up    ) AND
                ( NOT doValveSilo2 ) AND
                ( NOT doValveSilo3 );
 
Du hast noch ein Problem mit den Begriffen.
Deine 5 Bar ist die (gemessene) physikalische Größe. Aus der macht Dein Sensor 0-5 V (0V = 0%, 5V = 100%).
Die Digits ist der Wert den die analoge Eingangskarte an die SPS meldet (0V = 0, 10V = 32767).
dann wenn mein aiLevel 16000liefert/32000mein SPS maxWert = 0.5 da ich %brauche multipliziere mit 100 und so habe ich mein 50%Screenshot 2024-04-18 122422.png
Da Du nur die % benötigst brauchst Du nur die Digits, in Deinem Fall entspricht 0 = 0% und 16383 (oder 16384) = 100% und damit, für den Dreisatz, 32767 = 200%.
Digits wie du vorhin erklärt hast 0-32767 und und ich mach es in REAL in dem ich /32767.0 mache
der Zähler in meiner Division ist aiLevel und der ist in INT
deswegen mache ich int_to_REAL
Percentlevel (das Ergebnis ) ist in UINT
aber ihm gefällt trotzdem nicht :(
Und was hast du dagegen unternommen?
ich habe <= 25
<= 1
gemacht ^-^
 
Zuviel Werbung?
-> Hier kostenlos registrieren
dann wenn mein aiLevel 16000liefert/32000mein SPS maxWert = 0.5 da ich %brauche multipliziere mit 100 und so habe ich mein 50%Anhang anzeigen 77381

Digits wie du vorhin erklärt hast 0-32767 und und ich mach es in REAL in dem ich /32767.0 mache
der Zähler in meiner Division ist aiLevel und der ist in INT
deswegen mache ich int_to_REAL
Percentlevel (das Ergebnis ) ist in UINT
aber ihm gefällt trotzdem nicht :(

ich habe <= 25
<= 1
gemacht ^-^
Vielleicht solltest Du ab und zu mal die Hilfe zu den Befehlen aufrufen, dann wäre Dir aufgefallen, dass es "INT_TO_REAL(Variable)" lauten muss und nicht "INT_TO_REAL Variable". Wenn Dein Ergebnis ein UINT ist würde am Ende der Rechnung wieder eine implizite Konvertierung stattfinden. Ich dachte Du wolltest ein Ergebnis mit Nachkommastellen haben. Falls nicht brauchst Du nicht in REAL zu wandeln, dann würde der Code so aussehen:
Code:
PercentLevel := DINT_TO_UINT(INT_TO_DINT(aiLevel) * 200 / 32767):
Codesys und seine Derivate nehmen für Zwischenergebnisse zwar immer die größte Variante eines Variablentyps, daher könnte man das "INT_TO_DINT" auch weglassen, aber so ist es sauberer.
Das ".0" brauchst Du jetzt nicht mehr, da Du ja mit Ganzzahlen rechnen möchtest.
Du musst mit 200 multiplizieren, weil laut Deiner Angabe der Sensor 0-5V liefert und nicht 0-10V.
Wäre PercentLevel auch ein DINT, könnte die Konvertierung "DINT_TO_UINT" wegfallen.
Um die Verwirrung noch zu vergrößern. Auch die Konstanten werden von der Entwicklungsumgebung interpretiert und im Speicher als entsprechender Typ abgelegt, z.B. als UINT. Damit die Konstanten jetzt auch alle als DINT interpretiert werden müsste der so aussehen:
Code:
PercentLevel := DINT_TO_UINT(INT_TO_DINT(aiLevel) * DINT#200 / DINT#32767):
Aber ich glaube das wird dann doch etwas übertrieben.
 
Zuletzt bearbeitet:
Noch ein Nachtrag: Da Du mit Ganzzahlen rechnest ist in deinem Fall die Reihenfolge der Rechnung sehr wichtig.
Würdest Du erst aiLevel / 32767 rechnen käme, aufgrund der "fehlenden" Nachkommastellen immer 0 raus und damit wäre das Endergebnis nach der Multiplikation mit 200 auch immer 0.
 
Vielleicht solltest Du ab und zu mal die Hilfe zu den Befehlen aufrufen, dann wäre Dir aufgefallen, dass es "INT_TO_REAL(Variable)" lauten muss und nicht "INT_TO_REAL Variable". Wenn Dein Ergebnis ein UINT
ist würde am Ende der Rechnung wieder eine implizite Konvertierung stattfinden. Ich dachte Du wolltest ein Ergebnis mit Nachkommastellen haben. Falls nicht brauchst Du nicht in REAL zu wandeln, dann würde der Code so aussehen:
Code:
PercentLevel := DINT_TO_UINT(INT_TO_DINT(aiLevel) * 200 / 32767):
was ist mit [/CODE] gemeint ?
Codesys und seine Derivate nehmen für Zwischenergebnisse zwar immer die größte Variante eines Variablentyps, daher könnte man das "INT_TO_DINT" auch weglassen, aber so ist es sauberer.
Das ".0" brauchst Du jetzt nicht mehr, da Du ja mit Ganzzahlen rechnen möchtest.
diese konvertieren funktioniert mit mir nicht. :(
um mit nachkommazahl zu rechnen muss mein Zielergebnis in REAL sein. bei mir PercentLevel
und falls die Variable (Sensor+Berechnung) in Ganzzahlen passieren da muss ich meine Konstante mit .0 machen, und mein aiLevel von INT_TO_REAL machen damit nachkommazahl nicht weggeht. und mir bei Percentlevel mit Komma gezeigt wird
habe ich richtig verstanden ?
Du musst mit 200 multiplizieren, weil laut Deiner Angabe der Sensor 0-5V liefert und nicht 0-10V.
bei mir steht mein Sensor liefert mir 0-32767, heißt ich muss nachprüfen ob er 0-5v liefert oder 0-10V
Hier ist die korrigierte Version:

"Solange man visualisiert und noch nicht den SPS mit den Sensoren verbunden hat, muss man das Programm für jeden verschiedenen Sensor anpassen und die Werte berücksichtigen, die er liefert."😵‍💫
Wäre PercentLevel auch ein DINT, könnte die Konvertierung "DINT_TO_UINT" wegfallen.
Um die Verwirrung noch zu vergrößern. Auch die Konstanten werden von der Entwicklungsumgebung interpretiert und im Speicher als entsprechender Typ abgelegt, z.B. als UINT. Damit die Konstanten jetzt auch alle als DINT interpretiert werden müsste der so aussehen:
Code:
PercentLevel := DINT_TO_UINT(INT_TO_DINT(aiLevel) * DINT#200 / DINT#32767):
Aber ich glaube das wird dann doch etwas übertrieben.
brauchen alle solang um diese Thema zu verstehen oder geht es nur bei mir so ?


jzt spinnt bei mir total, IF_ELSE hat alle BITS TRUE gesetzt 😤
 

Anhänge

  • gg.png
    gg.png
    75,1 KB · Aufrufe: 7
Zuviel Werbung?
-> Hier kostenlos registrieren
In der 2. Zeile muss PercentLevel < 90 sein, sonst wäre Bedingung 1 schon erfüllt.
In der 3. Zeile muss PercentLevel <= 25 sein, sonst wäre Bedingung 1 oder Bedingung 2 schon erfüllt,
Bedingung 4 wird immer erfüllt, wenn die ersten 3 Bedingungen nicht erfüllt werden (entweder der Wert war >1 oder er ist <= 1, was 3. gibt es da nicht!), deshalb kann es nie ein ELSE geben.

Wenn man das alles zusammenkürzt, verbleibt lediglich:
Code:
IF PercentLevel >= 90 THEN doHigh := TRUE;
   ELSIF PercentLevel > 25 THEN doOk  := TRUE;
   ELSIF PercentLevel >  1 THEN doLow := TRUE;
   ELSE doAlarm := TRUE;
END_IF;
Nun entscheide selbst, was lesbarer von beidem ist.
Ergebnis: unnötigen/doppelten Code/Abfragen möglichst vermeiden!



Und jetzt zur eigentlichen Frage:

Wie werden all die Flags denn ggf. wieder auf FALSE zurückgesetzt? Das erfolgt mit obigen Code nämlich nicht!
IMHO sauberer Code wäre:
Code:
doHigh   := PercentLevel >= 90;
doOk     := PercentLevel <  90 AND PercentLevel > 25;
doLow    := PercentLevel <= 25 AND PercentLevel >  1;
doAlarm  := PercentLevel <=  1;
doDefekt := ?;
Und schon ist auch eine dieser elendigen und vor allem unnötigen IF-ELSE-Orgien beseitigt.
;)
 
jzt spinnt bei mir total, IF_ELSE hat alle BITS TRUE gesetzt 😤
Nö, der spinnt nicht.
Hast ja nirgends (bzw. zumindest bei dem was man hier sieht) einen Befehl zum Rücksetzen drin:
Und jetzt zur eigentlichen Frage:

Wie werden all die Flags denn ggf. wieder auf FALSE zurückgesetzt? Das erfolgt mit obigen Code nämlich nicht!
...
Lösung:
Siehe Post hier drüber!
 
Zuletzt bearbeitet:
Nö, macht er nicht.
Hast ja nirgends einen Befehl zum Rücksetzen drin:
stimmt, kann ich dann unter
ELSE
doHigh:= FALSE;
doOk:= FALSE;
doLow:= FALSE;
doAlarm:=FALSE;
End_IF
?

Lösung:
Siehe Post hier drüber!
habe ich gesehen, Danke, aber was macht dein Programm wenn den Wert außerhalb, nichts oder
er wird doHight TRUE setzen
oder doLow auf TRUE
gä ?
 
Zurück
Oben