Multiplizieren / Dividieren mit S5-100U(CPU100)

dollmas

Level-1
Beiträge
11
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ist es möglich in der s5-100u im Funktionsbaustein zu multiplizieren bzw. zu dividieren? Ich habe die CPU 100 in der die Funktionsbausteine FB242 und FB243 noch nicht vorhanden sind...

Eigentlich brauche ich ja den FB250 (den ich ja auch nicht habe) um die Werte meiner Analogbaugruppe zu normieren.
Jetzt wollte ich mir selbst einen solchen Baustein programmieren aber nun scheiterts am multiplizieren.

Die normierten Werte wollte ich im Dateinbaustein speichern und über mein OP5 ausgeben.

Gibt es noch eine andere Möglichkeit?

Danke Tom
 
Kann diese CPU denn überhaupt Analogwerte einlesen?
Wenn es nur an der Multiplikation liegt, die kann man aus Additions- und Schiebebefehlen aufbauen. Beispiel Faktor 10:
L Wert
SLW 2 // *4
L Wert
+F //4*Wert +Wert=5*Wert
SLW 1 // *2
Ergebnis: 2*(4*Wert +Wert)=10*Wert
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi,
ja das funktioniert, ich verwende eine analoge Eingabegruppe.

Ich müsste folgende Formel in den FB unterbringen:
Das X will ich aus einem Datenbaustein lesen und das Ergebnis Y wieder in einen Datenbaustein zurückschreiben.

Y = (((Ymax - Ymin)*(X-Xmin)) / (Xmax-Xmin))+Ymin

Mit meinen Werten lautet die Formel so..
Y = ((115*(X-30)) / 2018) +5

mfg Tom
 
Y = ((115*(X-30)) / 2018) +5
Ich ersetze X-30 durch A und konzentriere mich auf den Teil: 115*A / 2018.
Es würde sich wohl nicht lohnen, eine komplette 16 oder 32-Bit Division zu implementieren. Eine andere Methode ist, den Nener so zu verändern, daß er eine Zweierpotenz ist und die Division durch Rechtsschieben zu ersetzen. Dazu erweitere ich den Bruch mit (2048/2018).
Aus der 115 wird 116.7096135.
Y = (116.7096135*(X-30)) / 2048) +5
Da wir hier nur ganze Zahlen verarbeiten können, bedeutet das, daß wir Ersatzweise einen ganzzahligen Faktor nehmen müssen und einen Fehler in Kauf nehmen:
117 / 116.7... =1.00248.. -> Fehler +0.25%
116 / 116.7... =0.993.. -> Fehler -0.61%

Wenn diese Fehler in der Größenordnung inakzeptabel sind, kann man nun Zähler und Nenner (mehrfach) mit 2 malnehmen. Dadurch wird die Anzahl der Stellen im Faktor größer und der Fehler kleiner. Wenn wir mit 32 erweitern bekämen wir:

Y= 3734.707632*A /65536

Bei 3735 hätten wir nur noch einen Fehler von 0.0078 %. Ferner bräuchten wir das Ergebnis nicht einmal durch Rechtsschieben zu teilen, sondern nur die letzten beifden Bytes wegzulassen... Aber leider müßten wir dazu 32-Bit-Arithmetik haben oder implementieren.

Hier würde ich 117 wählen (es sei denn, ein positiver Fehler wäre unzulässig)
Die Binärdarstellung von 117 ist 111 0101.
Die größte "Weite" beim Schieben ist jetzt 6 Stellen.
Wenn ich annehme, daß deine Werte aus einem 11-Bit-A/D-Wandler stammen, sind Werte zwischen 0 und 2047 möglich. Wir haben also nur 5 Stellen Platz, wenn wir mit der 16-Bit-Arithmetik auskommen wollen. Wir lassen daher beim Faktor rechts eine Stelle weg:
111010 und gleich noch eine, denn wenn die rechte Stelle 0 ist, kann man den Bruch durch 2 kürzen: 11101.

Aus
Y = (116.7096135*(X-30)) / 2048) +5
wird:
Y = (29.11740338*(X-30)) / 512) +5
und mit dem ganzzahligen Faktor 29
Y = (29*(X-30)) / 512) +5

29 / 29.117... =0.9939.. -> Fehler -0.61%

Jetzt können wir programmieren:
Code:
L Wert
L 30
+F
T MW50 // Zwischenspeicher X+30
SLW 2
T MW52 // Zwischenspeicher  4*(X+30)
SLW 1
T MW54 // Zwischenspeicher 8*(X+30)
SLW 1
T MW56 // Zwischenspeicher 16*(X+30)

L MW54
+F		// akku enthält 24*(X+30)	
L MW52 
+F		// akku enthält 28*(X+30)	
L MW50 
+F		// akku enthält 29*(X+30)	
SRW 9	// akku enthält 29*(X+30)	/ 512
L 5
+F		// akku enthält 29*(X+30)	/ 512+5
T Ergebnis
[/code]
 
Hallo

Beitrag von mir gelöscht, da ich mich geirrt habe. Die Lade und Transfer Operationen sind in der 100U möglich, nur nicht als Formaloperanden.

Gruß
Question_mark
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi Zottel,
danke schon mal für die super schnelle und ausführliche Antwort!!!

Ladeoperationen und Schiebeoperationen funktionieren schon..

Werds gleich mal probieren! Wenn ich durchgestiegen bin :lol: :lol:

Melde mich...

Mfg Tom
 
Moing,

funktioniert optimal...
Man muss in deinem Vorschlag nur noch das

L Wert
L 30
+F
T MW50 // Zwischenspeicher X+30


durch

L Wert
L 30
-F
T MW50 // Zwischenspeicher X-30


ersetzen, wie in meiner Formel oben.

Dann stimmts und Genauigkeit reicht für meine Anwendung völlig aus.

Danke!
Super Forum hier :D
 
Hallo Forumgemeinde,

ich hole den Beitrag mal wieder raus weil ich heute vor einem gleichen Problem stehe. Ich seh aber vor lauter Bäumen irgendwie den Wald nicht mehr und hoffe es kann mir einer helfen bei dem Programmaufbau der S5/115U.

Wir haben hier einen Impulsgeber. Dieser liefert mir 3600 Impulse bei 1000ml Durchfluss. Ich habe einen Zähler aufgebaut der mir in gewissen Abständen diese Impulse zählt und von daher weiß ich dann immer genau wieviel ml durch die Leitung geflossen sind. So kurz um meine Formel müßte eigentlich heißen:

X= gezählte Impulse
Y= Ergebnis in ml (Ganzzahlig)

Y=((1000ml/3600Imp)*X)

Ich arbeite in der S5 mit DB´s. Die Ungenauigkeiten die durch die Umrechnungen entstehen nehmen wir in Kauf, da wir eh schon in kleinen Dimensionen uns bewegen.

Danke schon mal

Gruß

Jürgen
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo

bei der S5-115U sind dafür die Bausteine Fb242 MUL:16 und FB243 DIV:16 zuständig
wenn du die nicht im Programm hast aus der CPU holen damit du den Aufruf programmieren
Beschreibung steht im Handbuch

Gruss Chris
 
Ahhhh... die gute alte S5 Zeiten.

Das hier errinnere ich von ungf. 20 Jahre her:

Wenn man in S5 bis 115U multiplizieren oder dividieren will kann man entweder die bausteine FB242 und FB243 verwenden, oder mit SLW oder SRW arbeiten.
Die Bausteine FB242 und FB243 verschwenden sehr viel CPU Zykluszeit (millisekunden !).

In die grösseren 115U CPUs (ab 945 ?) und in 135U kann man direkt mit Fliesskomma arbeiten.
Mit SLW bzw. SRW:

Dein Formel Y=((1000ml/3600Imp)*X) ---> Y=0.278*X

0.278 ~ =

0.25 // SRW 2 .. dividiert durch 4 (2^2)
+ 0.015625 // SRW 6 .. 1 dividiert durch 64 (2^6)
+ 0.0078125 // SRW 7 .. 1 dividiert durch 128 (2^7)
+ 0.00390625 // SRW 8 .. 1 dividiert durch 256 (2^8 )
= 0.27734357 // Ziemlich nah zu 0.278

Code:

L "X"
SRW 2
L "X"
SRW 6
+F
L "X"
SRW 7
+F
L "X"
SRW 8
+F
T "Y" // Y = 0.27734357 mal X
 
Du könntest auch einen Vorzähler/Vorteiler programmieren, der nur bis 18 (oder 9) zählt und bei jedem Zählerüberlauf 5ml (oder 2.5ml) zum Hauptzähler addiert. Wenn diese Anzeigeauflösung ausreicht. Dann brauchst Du keine Division und keine Multiplikation.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Oder falls 1ml-Auflösung benötigt:
- Vorzähler 0..18
- beim 4, 7, 11, 14. und 18. Impuls jeweils 1 zum ml-Hauptzähler addieren, beim 18. Impuls den Vorzähler auf 0 rücksetzen

Harald
 
Zurück
Oben