Analogausgängen

Zuviel Werbung?
-> Hier kostenlos registrieren
Du solltest den übertragenen Wert zunächst um 4 Bits nach rechts schieben mit SHR, um die Statusbits zu eliminieren. Jetzt musst Du aber mit 4095 arbeiten.
... oder die Bits einfach auf 0 setzen (... AND 16%FFF0), dann arbeitet man mit 0..32752 (nominal 32767), mit Stufen von je 16. Also den eigentlichen Analogwert vom ADU linksbündig in ein 16 Bit Word/Int schreiben.
Ähnlich macht das auch Siemens, um auf 0..27648..32767 zu kommen, egal wie die tatsächliche Auflösung des ADU ist.

"4095" ist nicht ganz korrekt. Durch das Rechtsschieben um 4 Bits von 0..32767 oder (vorzeichenrichtig!) -32767..+32767 würde sich ein Bereich von 0 .. 2047 bzw. -2047 .. + 2047 ergeben.

Man kann auch eine Struktur des Wertes mit Begleitwerten erstellen:
Code:
AStruct : STRUCT
    Wert  : INT;
    Diag0 : BOOL;
    Diag1 : BOOL;
    Diag2 : BOOL;
    Diag3 : BOOL;
    valid : BOOL;
    sim   : BOOL;
    ...
END_STRUCT;

AnalogWert : AStruct;

AnalogWert.Diag0 := AnalogRohwert.%X0;
AnalogWert.Diag1 := AnalogRohwert.%X1;
AnalogWert.Diag2 := AnalogRohwert.%X2;
AnalogWert.Diag3 := AnalogRohwert.%X3;
AnalogWert.Wert := AnalogRohwert AND 16%FFF0; //Diagnosebits alle auf 0 setzen


Ach so, welchen Vorteil habe ich, wenn ich mit 4095 arbeite anstatt mit 32.767?
0..2047: Dann ändert sich der Analogwert in 2048 Stufen von je 1 : 0 - 1 - 2 - 3 - ... 2047
0..32767: Dann ändert sich der Analogwert in 2048 Stufen (Sprüngen) von je 16 : 0 - 16 - 32 - 48 - ... 32752 (32767 mit Diagnosebits). Die Werte sind einfach 16 mal so groß wie die ADU-Werte, aber nicht genauer und nicht mehr Auflösung. Das ist wie wenn man irgendwo Bonuspunkte sammelt und es sind immer 1000, 2000, ... damit es mehr aussieht.

Und was bringt es, wenn ich die Statusbits eliminiere?
Du arbeitest dann mit dem reinen "richtigen" Wert 0..32752). Wenn du die Statusbits drin lässt, dann wird der Wert sehr minimal verfälscht, maximal um weniger als die Auflösung (1 Stufe, max 15) des ADU größer.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
PROGRAM Scale
VAR_INPUT
iWert_Codesys: WORD;

END_VAR
VAR_OUTPUT
Gewicht: REAL;

END_VAR
VAR
result: WORD;

END_VAR

result:= iWert_Codesys;
result := result AND 16#FFF0;

result := SHR (iWert_Codesys,4);

Gewicht := WORD_TO_REAL (result);
„Erstens danke ich euch für die umfangreichen Informationen.“ 😊


Also so habe ich es dann gemacht, warum habe ich bei 0 einen 10 woher kommt es
 

Anhänge

  • Screenshot 2024-11-27 145841.png
    Screenshot 2024-11-27 145841.png
    226,6 KB · Aufrufe: 14
Zuletzt bearbeitet:
Weil Du das mit den Analogwerten noch nicht richtig begriffen hast.
Deine Waage liefert Dir einen Strom, der proportional zum gemessenen Gewicht ist.
Übrigens kannst Du Dir die Zeile 4 schenken, denn durch das SHR gehen die Stellen eh verloren.
Was Du gemacht hast ist, die Statusbits zu eliminieren, aber dadurch erhältst noch keine physikalische Größe, in diesem Fall das Gewicht. Dafür musst Du den Wert noch skalieren.
In Zeile 8 musst Du noch die in REAL gewandelte Zahl mit dem Gewicht multiplizieren, bei dem die Waage 20mA ausgibt und dann das Ganze durch 2047.0 teilen. Soweit das Maximalgewicht eine Ganzzahl ist auch hier ein ".0" anhängen.
 
Also so habe ich es dann gemacht, warum habe ich bei 0 einen 10 woher kommt es
weil die Ganzzahl-Division bzw das SHR 168 / 16 = 10 ergibt
Und weil du noch keine Skalierung des ADU-Wertes zur physikalischen Größe hast.

Deine Zeilen 3 und 4 sind anscheinend nur Testcode und völlig überflüssig?

Hinweis: Wenn du bei Codesys den Code inklusive der Zwischenrechnungen beobachten willst, dann darfst du die Zwischenergebnisse nicht immer wieder der gleichen Variable zuweisen, weil Codesys zeigt als Beobachtungswert den Wert an, den die Variable am Ende des Zyklus hat - das muss nicht der Wert bei der beobachteten Zuweisung sein. So wie bei dir, wenn mehrmals verschiedene Werte zugewiesen werden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Weil Du das mit den Analogwerten noch nicht richtig begriffen hast.
leider
Deine Waage liefert Dir einen Strom, der proportional zum gemessenen Gewicht ist.
Übrigens kannst Du Dir die Zeile 4 schenken, denn durch das SHR gehen die Stellen eh verloren.
Was Du gemacht hast ist, die Statusbits zu eliminieren, aber dadurch erhältst noch keine physikalische Größe, in diesem Fall das Gewicht. Dafür musst Du den Wert noch skalieren.
In Zeile 8 musst Du noch die in REAL gewandelte Zahl mit dem Gewicht multiplizieren, bei dem die Waage 20mA ausgibt und dann das Ganze durch 2047.0 teilen. Soweit das Maximalgewicht eine Ganzzahl ist auch hier ein ".0" anhängen.
das habe jzt gemacht
Gewicht := WORD_TO_INT (result)*1500/2047;
Bei 1500 sollte die Waage mir die 4 mA anzeigen.
So hat er mir aber einen Wert von 7 gegeben.

Sollte ich eigentlich nicht die 4 mA abziehen? Liegt der Fehler vielleicht daran?
Gewicht := WORD_TO_INT (result)*100/2047;
Damit hat er mir dann 0 angezeigt, aber wenn ich etwas darauflege, bleibt es bei 0.

Ich denke, dass ich immer noch mit 16er-Schritten arbeite, oder?
 
Soweit 1500, dem zulässigen Maximalgewicht der Waage entspricht, müssen 20mA fließen und nicht 4mA, die 4mA fließen bei unbelasteter Waage.
Da es eine 4mA - 20mA Karte ist, brauchst Du gar nichts machen, dass erledigt die AI-Klemme schon für Dich. Anders sähe es aus, wenn Du ein Gerät, dass 4mA - 20mA liefert an eine Karte anschließt die 0mA - 20mA verarbeitet. Näheres hierzu findest Du in diesem FAQ-Beitrag.
Nachtrag: Und bitte beachte meine Hinweise bezüglich dem Anhängen von ".0". @PN/DP hat das gerade auch nochmals erwähnt und in der eben erwähnten FAQ steht auch ein Hinweis dazu. Das WORD_TO_REAL war schon nicht verkehrt, dann musst Du nur noch 1500.0 tippen statt 1500 und 2047.0 statt 2047.
 
Zuletzt bearbeitet:
die Ganzzahl-Division 1500/2047 ergibt immer 0
Wenn du genauer rechnen willst, dann müsstest du in REAL rechnen, also erst den Eingangswert in REAL wandeln und dann die Berechnung mit REAL-Werten machen, z.B. Gewicht := WORD_TO_REAL(result) * 1500.0 / 2047.0; (ich habe jetzt nicht geprüft, ob die Mathematik der Formel korrekt ist)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
PROGRAM Scale
VAR_INPUT
iWert_Codesys: WORD;

END_VAR
VAR_OUTPUT
Gewicht: REAL;

END_VAR
VAR
offset: INT := 10;

result: WORD;
analogValue: WORD;
maxlimit: WORD := 32752;
maxGewicht: REAL := 1500.0; // Maximalgewicht in kg
aduBereich: REAL := 2047.0; // ADU-Bereich
END_VAR
result := SHR (iWert_Codesys,4);

Gewicht := (WORD_TO_REAL( result - offset) / aduBereich)* maxGewicht;
So sieht es besser aus, aber leider habe ich immer noch 16er-Schritte.

Ich habe zwar jetzt den Wert 0 bei 0 kg, aber immer noch keinen genauen Wert.

Genauer gesagt macht er eine Schrittweite von 0,73 kg.

Ohne die 4 Bits zu verschieben, zeigt er Werte von 1,8 bis 2,2.
 
Zuletzt bearbeitet:
so sieht besser aus, aber leider immer noch 16ene schritte
ich habe zwar jzt die 0 bei 0kg aber immer noch keine genauer Wert
Was meinst Du mit 16er Schritte? Ganz genau wird es nie werden, kann es technisch auch nicht. Das Maximalgewicht mit dem die Waage belastet werden darf wird halt in 2047 Teile unterteilt, Änderungen die Kleiner sind werden nicht erfasst.
Wenn Deine Wage tatsächlich 1500g nehme ich als Einheit mal an wiegen kann, dann dann entspricht jede Änderung des Messwertes um 1 ungefähr 740mg. Dazu kommt dann auch noch die Toleranz der Karte, die vermutlich über den 740mg liegen wird.
Laut Handbuch hat die Klemme eine Abweichung von 0,1% auf den Messbereichsendwert. Da die Karte von 4mA - 20mA misst ist der Messbereich 16mA, 0,1% davon sind 16MicroA, das entspricht bei 1500g einem möglichen Fehler von 1,5g womit Du deutlich über den 740mg liegst.
Ich hoffe, ich habe hier keinen Blödsinn verzapft, falls ja haut mir bitte auf die Finger.
Nachtrag: Habe gerade im Internet nachgesehen und der Messbereichsendwert ist wohl nicht 126mA, sondern 20mA, dadurch ergibt sich ein größerer Wert. Bei einem Fehler von 0,1% entspricht das nun 20MicroA und damit 1,875g.
 
Zuletzt bearbeitet:
Was meinst Du mit 16er Schritte? Ganz genau wird es nie werden, kann es technisch auch nicht. Das Maximalgewicht mit dem die Waage belastet werden darf wird halt in 2047 Teile unterteilt, Änderungen die Kleiner sind werden nicht erfasst.
Wenn Deine Wage tatsächlich 1500g nehme ich als Einheit mal an wiegen kann, dann dann entspricht jede Änderung des Messwertes um 1 ungefähr 740mg. Dazu kommt dann auch noch die Toleranz der Karte, die vermutlich über den 740mg liegen wird.
Laut Handbuch hat die Klemme eine Abweichung von 0,1% auf den Messbereichsendwert. Da die Karte von 4mA - 20mA misst ist der Messbereich 16mA, 0,1% davon sind 16MicroA, das entspricht bei 1500g einem möglichen Fehler von 1,5g womit Du deutlich über den 740mg liegst.
Ich hoffe, ich habe hier keinen Blödsinn verzapft, falls ja haut mir bitte auf die Finger.
Ach so, das heißt, je weniger ich maximal belasten möchte, desto genauer wird es.

Obwohl ich gerade das Gerät auf 500 kg gestellt habe und mein Programm ebenfalls auf 500, macht er trotzdem Schritte von 0,73 kg.

So wird es jedoch nicht funktionieren.
Nachtrag: Es sind doch circa 0,32, aber wenn die Anzeige 1,4 zeigt, zeigt Codesys 0,732 an.

Irgendwie ist das völlig daneben.
 
Ja was hast du den als Gewicht auf der Waage?Leg mal 100 kg drauf.Bei einem Messbereich von 0..500kg
müsstest du dann 7,2mA messen
Leider habe ich in der Werkstatt keine 100 kg, die ich auf meinen Aufbau legen könnte.

Ich benutze stattdessen immer eine Wasserflasche. ich hab bisschen was davon getrunken jzt hat es ein Gewicht von 1.4 kg
Bei dieser habe ich 1,9 A gemessen, was gerade überhaupt keinen Sinn ergibt.
 
Zurück
Oben