Realzahlwerte in Endlosschleife speichern in "Schubladen" 1-200

DennisBerger

Level-2
Beiträge
436
Reaktionspunkte
61
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
folgende Aufgabe wurde gestellt: Steuerung S7-200 CPU 224

Es sollen ermittelte Realzahlen (per Analoghwert je ein gemessenes Drehmoment pro montiertes Teil) gemessen werden und diese dann einzeln von 1-200 gespeichert werden und abrufbar sein.

Also
Teil 1 hat an AEW1 gemessene 2,43NM , diesen in Wert/Zeile 1 speichern für spätere Auswertung
Teil 2 hat an AEW1 gemessene 2,21NM diesen in Wert/Zeile 2 speichern für spätere Auswertung
..
Teil200 hat an AEW1 gemessene 2,33NM ... ... in Zeile 200 speichern..
zsw.

Ist Wert 200 geschrieben, soll wieder der von vorne der 1, Wert überschrieben werden. (also Endlosschleife)

Wie geht man da am besten / geschicktesten vor, dass man wenig Programmier Aufwand hat?

Ich glaube 200 Netzwerke machen und einen Zähler verwenden der bis 200 bei jedem neuen Teil hochzählt und dann immer je nach angefragten Zählwert 1-200 dem jeweiligen Speicherwert zuweist ist nicht so praktikabel oder?

Danke für Anregungen und Ideen

Dennis
 
Indirekte Adressierung ist Dein Stichwort.
Speicheradresse = 4 * Zähler + Anfangsadresse_Tabelle

(Zähler: 0...199, Anfangsadresse Tabelle: &VB....)

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Harald,
danke für die schnelle Antwort,
das ist aber nun doch etwas zu undruchsichtig / unverständlich für mich.
Kannst das genauer erklären bzw als AWL schreiben?

Oder irgendwie vereinfachen?+

Danke dir
 
Der Link von Volker bringt Dir für die 200er leider gar nichts. Der FIFO funktioniert, mal abgesehen vom Grundprinzip, dort ganz anders. Dafür hast Du dort allerdings einen fertigen Baustein,der Dir viel Arbeit abnimmt.
Vom Handy kann ich Dir leider nichts dazu posten, aber wenn Du Dich bis heute abend gedulden kannst, such ich Dir das raus.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Indirekte Adressierung ist Dein Stichwort.
Damit meine ich: in MicroWIN die Hilfe aufrufen > Index > Indirekte und direkte Adressierung

Wie ich Deine Aufgabe verstehe brauchst Du keinen FIFO. Einfach eine Tabelle/Liste für 200 Meßwerte und einen Ereigniszähler, der gleichzeitig der Index in diese Liste ist.

Angenommen Du willst in einer Liste ab VB1000 200 REAL-Meßwerte speichern:
VD1000 REAL Messwert_001 (bei Zählerstand 0)
VD1004 REAL Messwert_002 (bei Zählerstand 1)
VD1008 REAL Messwert_003 (bei Zählerstand 2)
...
VD1792 REAL Messwert_199 (bei Zählerstand 198)
VD1796 REAL Messwert_200 (bei Zählerstand 199)

angenommen, Du hast den Zähler in VW100
angenommen, Du hast den skalierten Meßwert in VD200

Immer wenn Dein Meß-Ereignis kommt, dann erhöhst Du den Zähler um 1, prüfst ob er 0...199 ist, setzt ihn ggf. auf 0, und dann speicherst Du Deinen Meßwert in die Liste an den Platz, dessen Index nun im Zähler steht:
Code:
//Meßwert in die Liste schreiben:
MOVW   VW100, AC1          //Zählerstand in Akku1
SLD    AC1, 2              //Zähler * 4 (wegen Pointer auf REAL-Liste)
MOVD   &VB1000, AC0        //Anfangsadresse der Liste in Akku0
+D     AC0, AC1            //dazuaddieren
MOVD   VD200, *AC1         //Meßwert in die berechnete Adresse in der Liste schreiben

Tip: den Zähler VW100 mit -1 initialisieren, dann schreibt das erste Meßereignis in den ersten Listenplatz VD1000.
Man kann bei Bedarf natürlich auch einen Zähler 1...200 benutzen, muß dann nur etwas mehr rechnen.

Harald
 
Wie ich Deine Aufgabe verstehe brauchst Du keinen FIFO. Einfach eine Tabelle/Liste für 200 Meßwerte und einen Ereigniszähler, der gleichzeitig der Index in diese Liste ist.
...
Code:
[FONT=courier new]//Meßwert in die Liste schreiben:
MOVW   VW100, AC1          //Zählerstand in Akku1
SLD    AC1, 2              //Zähler * 4 (wegen Pointer auf REAL-Liste)
MOVD   &VB1000, AC0        //Anfangsadresse der Liste in Akku0
+D     AC0, AC1            //dazuaddieren
MOVD   VD200, *AC1         //Meßwert in die berechnete Adresse in der Liste schreiben 
[/FONT]
Harald hat Recht.
Der eingebaute FIFO ist für Deine Wünsche auch nicht ohne Weiteres verwendbar, da er zum Einen zum Speichern von Int-Werten vorgesehen und zum Anderen auf 100 Werte begrenzt ist. Dessen war ich mir heut' Mittag nicht (mehr) bewußt, sorry. :oops:
Man kann zwar die Real-Werte auf 2 Wörter aufteilen, müßte dann aber schon 4 FIFOs kaskadieren und das ist doch erheblich aufwendiger als Haralds Code-Beispiel.
Und da es Dir ausreicht, den Speicher wieder von vorn zu überschreiben, müssen die Werte ja nicht durchgerückt werden. Dies würde der eingebaute FIFO automatisch machen, was dann meist einfacher für's Anzeigen auf dem HMI ist.



Tip: den Zähler VW100 mit -1 initialisieren, dann schreibt das erste Meßereignis in den ersten Listenplatz VD1000.
Man kann bei Bedarf natürlich auch einen Zähler 1...200 benutzen, muß dann nur etwas mehr rechnen.
Weder noch, sondern den Zähler nach dem Eintragen erhöhen. Dadurch braucht man keine extra Initialisierung oder aufwendigere Berechnung.
Damit ergibt sich dies' Gesamtnetzwerk:
Code:
//Freigabe Speichern nicht vergessen (sonst Speichern in jedem Zyklus):
[FONT=courier new]LD     #Speichern[/FONT][FONT=courier new]
[/FONT]
[FONT=courier new]//Meßwert in die Liste schreiben (von Harald):[/FONT]
[FONT=courier new]MOVW   VW100, AC1          //Zählerstand in Akku1[/FONT]
[FONT=courier new]SLD    AC1, 2              //Zähler * 4 (wegen Pointer auf REAL-Liste)[/FONT]
[FONT=courier new]MOVD   &VB1000, AC0        //Anfangsadresse der Liste in Akku0[/FONT]
[FONT=courier new]+D     AC0, AC1            //dazuaddieren[/FONT]
[FONT=courier new]MOVD   VD200, *AC1         //Meßwert in die berechnete Adresse in der Liste schreiben [/FONT]
[FONT=courier new]
//anschließend Zeiger erhöhen:
INCW   VW100                //Zeiger um 1 erhöhen
UW>=   VW100, 200           //Zeiger >=200?
MOVW   0, VW100             //dann auf 0 zurücksetzen
[/FONT]



Teil 1 hat an AEW1
AEW1 dürfte einen Fehler erzeugen. MicroWin läßt bei mir nur AEW0 oder AEW2 (4, 6 ...) zu.



PS:
Code:
...
[FONT=courier new]SLD    AC1, 2              //Zähler * 4 (wegen Pointer auf REAL-Liste)
[/FONT][FONT=courier new]...[/FONT]
Die Feinheiten der binären Festpunktarithmetik - um x Stellen nach links verschieben entspricht mal 2^x.
Ist ja im Dezimalen auch nicht anders (*10^x), trotzdem vergess ich das immer wieder, da ich es im Dezimalen nicht mehr bewußt wahrnehme.
Ich hätte wahrscheinlich aus Gewohnheit mal 4 gerechnet.
Danke für die Wissens-Auffrischung.
:D
 
Zuletzt bearbeitet:
Weder noch, sondern den Zähler nach dem Eintragen erhöhen. Dadurch braucht man keine extra Initialisierung oder aufwendigere Berechnung.
Damit ergibt sich dies' Gesamtnetzwerk:
Code:
//Freigabe Speichern nicht vergessen (sonst Speichern in jedem Zyklus):
[FONT=courier new]LD     #Speichern[/FONT][FONT=courier new]
[/FONT]
[FONT=courier new]//Meßwert in die Liste schreiben (von Harald):[/FONT]
[FONT=courier new]MOVW   VW100, AC1          //Zählerstand in Akku1[/FONT]
[FONT=courier new]SLD    AC1, 2              //Zähler * 4 (wegen Pointer auf REAL-Liste)[/FONT]
[FONT=courier new]MOVD   &VB1000, AC0        //Anfangsadresse der Liste in Akku0[/FONT]
[FONT=courier new]+D     AC0, AC1            //dazuaddieren[/FONT]
[FONT=courier new]MOVD   VD200, *AC1         //Meßwert in die berechnete Adresse in der Liste schreiben [/FONT]
[FONT=courier new]
//anschließend Zeiger erhöhen:
INCW   VW100                //Zeiger um 1 erhöhen
UW>=   VW100, 200           //Zeiger >=200?
MOVW   0, VW100             //dann auf 0 zurücksetzen
[/FONT]

Hallo
erstmal danke, das hab ich glaub ich so weit verstanden vom Prinzip her, da ich aber nie in AWL programmiere, hab ich noch ein paar Fragen zur Verständnis.
Korrigiert mich, wenn ich was falsches schreibe:

ACx:
-AC0 und AC1 sind flüchtige Arbeitsspeicher, die ich beliebig füllen kann. Geht das unendlich? also AC0 bis AC9999 oder wie ist das begrenzt.
-wie lange bleibt der Wert im ACx? Zyklusanfang der sps oder Spannungsunterbrechung?


-Was bedeutet der befehl SLd (LD steht für laden und S?)


- MOVD &VB1000, AC0 //Anfangsadresse der Liste in Akku0
Warum steht da &VB1000 und vorne MOVD? Müsste es nicht MOVB sein?
was bedeutet dieses & Zeichen? Dass nicht der tatsächlche Wert von VB1000 sondern die Adresse geladen wird in AC0? Also AC0 ist geladen mit VD1000


+D AC0, AC1
Ist das richtig, wenn ich sage, dass AC0 zu AC1 dazu addiert wird, also immer der erste AC in den der als 2. steht?


MOVD VD200, *AC1
Warum macht man hier ein *AC1 ? würde es nicht reichen wie weiter oben in der ersten Zeile MOVD VD200, AC1 ?

Danke schon mal für die Hilfe.
Hoffe das waren nicht zu viele Fragen, wollte den Code auch verstehen nicht nur abschreiben.

Dennis
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
da ich aber nie in AWL programmiere, hab ich noch ein paar Fragen zur Verständnis.
Gib' das obige (komplette) Netzwerk so ein, schalt' die Ansicht auf FUP oder KOP und staune. :)


Korrigiert mich, wenn ich was falsches schreibe:

ACx:
-AC0 und AC1 sind flüchtige Arbeitsspeicher, die ich beliebig füllen kann. Geht das unendlich? also AC0 bis AC9999 oder wie ist das begrenzt.
Jetzt aus dem Gedächtnis glaub ich, das sind nur 4 Accus. Genaueres im Handbuch.


-wie lange bleibt der Wert im ACx? Zyklusanfang der sps oder Spannungsunterbrechung?
Letzteres oder bis er von Dir überschrieben wird.


-Was bedeutet der befehl SLd (LD steht für laden und S?)
Nein, das bedeutet: Schiebe Bits nach Links im Doppelwort oder kurz - Schiebe Links DWORD.
Die Bits im Doppelwort um die angegebenen Stellen nach links verschieben und die freigewordenen Stellen mit Nullen auffüllen. Genaueres unter F1 und unter dem PS: in meinem vorigen Post.


- MOVD &VB1000, AC0 //Anfangsadresse der Liste in Akku0
Warum steht da &VB1000 und vorne MOVD? Müsste es nicht MOVB sein?
was bedeutet dieses & Zeichen? Dass nicht der tatsächlche Wert von VB1000 sondern die Adresse geladen wird in AC0? Also AC0 ist geladen mit VD1000
Genau, es wird die Adresse (1000) geladen und die ist ein Doppelwort.


+D AC0, AC1
Ist das richtig, wenn ich sage, dass AC0 zu AC1 dazu addiert wird, also immer der erste AC in den der als 2. steht?
Jup.


MOVD VD200, *AC1
Warum macht man hier ein *AC1 ? würde es nicht reichen wie weiter oben in der ersten Zeile MOVD VD200, AC1 ?
Der Inhalt von VD200 soll ja nicht in AC1 selbst, sondern in die dort angegebene Adresse geladen werden. Das wird durch den * unterschieden.
 
Zuletzt bearbeitet:
Zurück
Oben