Messwerte zyklisch in einen DB Speichern

MaurerT

Level-2
Beiträge
122
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo, ich habe ein Problem bei indirekter Adressierung (mit der ich auch irgendwie auf Kriegsfuss stehe. Die enstprechenden Themen hierzu habe ich im Forum gefunden und auch gelesen aber irgendwie sind Theorie und Praxis noch nicht ganz Deckungsgleich). Und zwar möchte ich über den OB35 einmal im Monat Zählerstände in einem DB ablegen als Ringspeicher mit 24 Monatswerten. Habe zu diesem Thema auch im Forum ein wenig gesucht und auch etwas gefunden was eigentlich gut passen würde allerdings bekomme ich nur einen Wert geschrieben und erhalte dann bei weiteren Versuchen Bereichlängenfehler beim schreiben in der CPU Diagnose. Habe den Code zur Zeit zum Testen in einem FB stehen und den M58.0 steuere ich über die Variablentabelle um den Schreibvorgang zu simulieren. Später im OB35 würde ich dann mit L MW 60 beginnen.

U M 58.0
FP M 58.1
SPBN M001
L MW 60 // hier sollte das Ziel DBD für DB11 stehen
SLD 5 // + 4Byte, SLD 3 für Byteadresse und SLD 2 für + 4Byte
L P#0.0
+D
LAR1
L MD 54 //hier liegt der Zählwert
AUF DB 11
T DBD [AR1,P#0.0]
L MW 60
+ 1
T MW 60
L 24
<I
SPB M001
L 0 //nach 24 Durchgängen wieder bei 0 Anfangen
T MW 60
M001: NOP 0

DB11 ist in der CPU vorhanden. Habe ich als Array 1..24 angelegt im Format DINT mit Anfangswert 0. Hat jemand einen Ansatz woher der Bereichslängenfehler kommt? Danke schon mal vorab.
 
Hi MaurerT,

also erster "Fehler" der mir auffällt wäre das du ein Word lädst und dann sagst SLD ... würde da mal versuchen MD60 zu laden anstatt MW60 weil sonst schiebst du ja uU in nen Bereich der garnicht da ist ...

Ansonsten hier mal ein Entwurf von mir dafür: (Ist ein wenig anders wie die meisten das hier machen aber find das eigentlich nur unnötig kompliziert ...)
Code:
U M     58.0
FP M     58.1
SPBN  M001
L MW    60         // hier sollte das Ziel DBD für DB11 stehen   
ITD                    // in DWORD wandeln
L P#4.0              // Zeigerbereich auf 4 Byte setzen
*D                     // Inhalt von MW60 in 4-Byte breiten Zeiger wandeln
T #Zeiger           // als Zeiger in DWORD-Variable zwischenspeichern
L MD54             
AUF DB11
T DBD[#Zeiger]

L MW60
L 1
+I
T MW60
L 24
<I
SPB M001
L 0
T MW60
M001: NOP 0

So mach ich das im Regelfall wenn ich Zeiger verwende ... Dürfte funktionieren! Hoffe ist auch soweit verständlich für dich!
Ansonsten sag bescheid!

Grüße,
Martin
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
OK, habe den Fehler selber gefunden. Problem war dass die CPU vernetzt ist und über PUT/GET Befehle der Partner CPU genau diesen Merkerbereich mit Messwerten überschrieben bekommt. In den Querverweisen/Referenzdaten werden diese aber nicht als belegt markiert. Bin ich aber auch erst durch Zufall drauf gekommen, da sich der Zustand des Merkers M58.0 bei längerer Beobachtung selbstständig geändert hat.
Der Teufel steckt im Detail. trotzdem Danke

@martin1988: Da ich ja nur Werte bis 24 Lade, sollte es egal sein aber rein formal gebe ich dir Recht. Das SLD benötige ich weil ich über das Adressregister lade und benötige diesen Befehel um den Wert in die Byteadresse zu verschieben. Mit dem zusätzlichen SLD 2 erzeuge ich die Sprungweite (bei dir L P#4.0). ansonsten dürfte deine Variante aber auch gehen. Danke
 
Hallo muss das Thema noch mal aufgreifen. Habe das Programm wie gesagt mit Merkern umgesetzt getestet und funktioniert auch. Dachte mir jetzt aber um Merker zu sparen könnte ich ja im FB eine statische Variable Datentyp DINT deklarieren und den verwendeten Merker durch die statische Variable ersetzen. Danach habe ich aber wieder das Problem mit dem Bereichslängen Fehler beim Schreiben/Lesen und zwar nennt er mir als Adresse die, die im statischen Bereich für die Variable vergeben wird. Kann man das nicht mit statischen Variablen machen?
 
Dachte mir jetzt aber um Merker zu sparen könnte ich ja im FB eine statische Variable Datentyp DINT deklarieren und den verwendeten Merker durch die statische Variable ersetzen. Danach habe ich aber wieder das Problem mit dem Bereichslängen Fehler beim Schreiben/Lesen und zwar nennt er mir als Adresse die, die im statischen Bereich für die Variable vergeben wird. Kann man das nicht mit statischen Variablen machen?
Doch, du musst nur den Offset vom AR2 addieren.
Ich denke mal du bist immer noch bei deinem Code geblieben, schreibe mal:
Code:
   +D 
[COLOR=#ff0000]  TAR2
   +AR1
[/COLOR]  LAR1
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo nochmal, mir ist der Groschens selber gefallen. Habe "vergessen" den Instanz-DB neu zu übertragen, somit konnte das Programm natürlich auch nicht auf das DBD zugreifen. Jetzt funktioniert aber alles wie gewünscht. Trotzdem danke für die Unterstützung.

@Paule: Unabhängig davon, verstehe ich deinen Einwand mit dem AR2 nicht. Ich habe doch an keiner Stelle mit dem AR2 gearbeitet ?
 
aus der Siemenshilfe
Beim FB-, FC-, Multiinstanz-CALL dürfen VKE oder AKKU1 und AKKU2 nicht als zusätzliche (implizite) Parameter verwendet werden.
Das DI-Register und das Adressregister AR2 werden systemseitig für den FB- und Multiinstanz-CALL verwendet und dürfen deshalb innerhalb von FB's nicht verändert werden.
Das Adressregister AR1 wird von einem Teil der ladbaren Standardbausteine verwendet.
Der Befehl "L P#Parametername" lädt innerhalb eines FB den Adressoffset des angegebenen Parameters, relativ zum Adressregister AR2. Um in multiinstanzfähigen FBs den absoluten Offset im Instanzdatenbaustein zu ermitteln, muss zu diesem Wert noch der bereichsinterne Zeiger (nur Adresse) des AR2-Registers addiert werden.
wenn du anstatt eines fb einen fc verwenden würdest hättest du dieses 'problem' nicht
 
Einen FB habe ich hier verwendet weil ich mehrere Instanzen vom SFB 0 (CU) benötige um eine Zählung durchzuführen. Schien mir ein sinnvoller Weg zu sein. Dann kam eben noch das Thema mit dem Ringspeicher hinzu und wie gesagt nachdem ich den Instanz-DB übertragen habe funktionierte auch alles ohne Probleme. Habe die Funktion durchgetestet und es wurden alle Werte sauber im DB abgelegt.
Hier noch mal der aktuelle Programmcode.

U M 88.0
FP M 88.1
SPBN M001
L #Zeiger_GH // Statische DINT Variable
SLD 5 //SLD 3 für Byteadresse, SLD 2 für 4 Byte Sprungweite --> SLD5
L P#0.0
+D
LAR1
L DB11.DBD 196 //aktueller Messwert
AUF DB 11
T DBD [AR1,P#0.0] //Offset Werte GH ab DBD0
L #Zeiger_GH
+ 1
T #Zeiger_GH
L 24
<I //24 Werte eintragen
SPB M001
L 0 // Wieder von vorne beginnen
T #Zeiger_GH
M001: NOP 0
--------------------------------------------------------------------------------------------------------
U M 88.0
FP M 88.2
SPBN M002
L #Zeiger_HW // Statische DINT Variable
SLD 5
L P#0.0
+D
LAR1
L DB11.DBD 192 //aktueller Messwert
AUF DB 11
T DBD [AR1,P#96.0] //Offset Werte HW ab DBD96
L #Zeiger_HW
+ 1
T #Zeiger_HW
L 24
<I
SPB M001
L 0
T #Zeiger_HW
M002: NOP 0

Die ersten 24 Werte werden ab dem DBD 0 abgelegt und die zweiten 24 Werte ab dem DBD 96. Kann jetzt hier noch ein Zustand eintreten der mir Probleme macht, da ich das mit dem AR2 noch nicht ganz geschnackelt habe?
 
Zuletzt bearbeitet:
Zurück
Oben