Pointer für einen Datenlogger

hantschel1981

New member
Beiträge
3
Punkte Reaktionen
0
Zuviel Werbung?
->Hier kostenlos registrieren
Hallo SPS-Forums User
zuerst mal allen ein Gutes neues Jahr.

Ich habe ein Problem mit Variablen Pointern:

Die Anleitung, wie ein Pointer aufgebaut ist, habe ich gelesen und auch glaube ich verstanden.
Jedoch scheitert es an der Umsetzung.

Meine Hardware:
CPU 319 3PN/DP (318er)
Zu meinem Problem:

Ich mochte mir einen Datenlogger basteln.
Daten alle 5 Minuten aufzeichnen und diese in eine Array mit 288 Realwerten schreiben.
Ich habe einen Integer erzeugt, der alle 5 Minuten um den Wert 1 weiterspringt.
Nun soll ein Realwert geladen werden und abhängig vom INT-Wert (Zähler für Pointer) in den Passenden ARRAYEINTAG geschrieben werden.

Kann mir dafür jemand ein Beispiel schreiben?
Die Daten werden wie gesagt in einem DB abgelegt der wie Folgt aussieht:

STAT:
DB562.DBW0 Kurven-Anforderung [WORD]
DB562.DBW2 Kurven-Übertrag [WORD]
DB562.DBD4 LOGGER [0, 1] Loggerwert 1 [REAL]
DB562.DBD8 LOGGER [0, 2] Loggerwert 2 [REAL]
DB562.DBD12 LOGGER [0, 3] Loggerwert 3 [REAL]
DB562.DBD16 LOGGER [0, 4] Loggerwert 4 [REAL]
usw (288 Werte)

Vielen Dank im Voraus
Gruß Stefan
 

SCM

Well-known member
Beiträge
335
Punkte Reaktionen
33
Hallo!

Hier mal ein kleiner Denkanstoß:

Code:
FUNCTION "LOGGER": VOID
VAR_INPUT
    SAVE:           BOOL;
    SAVE_COUNT:     INT;
    SAVE_VALUE:     REAL;
END_VAR
VAR_IN_OUT
    LOGG_ARRAY:     ARRAY[1..288] OF REAL; 
END_VAR
BEGIN
IF SAVE THEN
    LOGG_ARRAY[SAVE_COUNT]:= SAVE_VALUE;   
END_IF;
END_FUNCTION

Gruß
 

Ralle

Supermoderator
Teammitglied
Beiträge
15.101
Punkte Reaktionen
3.818
Zuviel Werbung?
->Hier kostenlos registrieren
Mal auf die Schnelle: Dein erster Wert beginnt bei DBD4

Angenommen, du fängst mit den Zähler für den Pointer mit 1 an, dann paßt das glücklicherweise so schon.
(Beginnt deine Wertetabelle später im DB, dann rechnest du noch den Offset dorthin vor dem SLD 3 dazu.)

Dann rechnest du :

Code:
L #Pointerzaehler
L 4                       //ein DWord hat 4 Byte, also immer 4 Byte von Wert zu Wert
*I
SLD 3                   //Pointerformat erstellen
T #MyPointer

zusammengefaßt ergibt das

Code:
L #Pointerzaehler
SLD 5
T #MyPointer

Damit kannst du dann den Wert wie folgt schreiben

Code:
L #Pointerzaehler
SLD 5
T #MyPointer
LAR 1
 
AUF DB 562
L #MyRealWert 
T DBD[AR1, P#0.0]
 

borromeus

Well-known member
Beiträge
2.270
Punkte Reaktionen
329
Kann mir irgendwer verraten was ich beim FB-Aufruf hinschreiben muss, wenn der IN_OUT Parameter ein Array ist?
(also so wie da oben von SCM beschrieben).
 
OP
H

hantschel1981

New member
Beiträge
3
Punkte Reaktionen
0
Danke Ralle, ef funzt.

Musste nur ne kleine änderung durchführen:


L #Pointerzaehler
SLD 5
T #MyPointer
LAR 1
L #MyRealWert
AUF DB 562
T DBD[AR1, P#0.0]
 

SCM

Well-known member
Beiträge
335
Punkte Reaktionen
33
Zuviel Werbung?
->Hier kostenlos registrieren
Also beim FC Aufruf an den Eingang "LOGG_ARRAY" kommt ein Array.
Wenn das Array im DB "TEST" steht und "SAVE" heißen würde kommt dort "TEST".SAVE ran!

Gruß
 

borromeus

Well-known member
Beiträge
2.270
Punkte Reaktionen
329
Najo, ich habe einen FB, ist das ein Unterschied?
Ich habe einen DB angelegt mit einer Arraylänge von 1..288, diesen MESSWERTE getauft und im DBX0.0 steht nun der Bezeichner Feld.

Schreibe ich "MESSWERTE".Feld kommt die Fehlermeldung:
Aktualdatentyp ARRAY paßt nicht zu formalem Typ ARRAY des Formalparameters LOGG_ARRAY
 

SCM

Well-known member
Beiträge
335
Punkte Reaktionen
33
Müsste egal sein ob FC oder FB!
Ist es auch ein REAL array?
Also bei mir funktioniert das!
Gruß
 

SCM

Well-known member
Beiträge
335
Punkte Reaktionen
33
Also das ist dann komisch!
Leg dir mal einen UDT an und ändere es im Baustein so das dort staht dem Array ein UDT steht!

Code:
TYPE UDT_SAVE
STRUCT
    VALUE:      ARRAY[1..288] OF REAL; 
END_STRUCT
END_TYPE
FUNCTION_BLOCK SYS_LOGGER
TITLE = 'LOGGER'
VAR_INPUT
    SAVE:           BOOL;
    SAVE_COUNT:     INT;
    SAVE_VALUE:     REAL;
END_VAR
VAR_IN_OUT
    LOGG_ARRAY:     UDT_SAVE;
END_VAR
BEGIN
IF SAVE THEN
    LOGG_ARRAY.VALUE[SAVE_COUNT]:= SAVE_VALUE;   
END_IF;
END_FUNCTION_BLOCK


So sollte es auf jedenfall auch bei dir funktionieren
Später im DB Messwerte bei Feld statt dem Array den udt eingeben!

GRUß
 
Zuletzt bearbeitet:
OP
H

hantschel1981

New member
Beiträge
3
Punkte Reaktionen
0
So, nun läuft mein logger aber ich habe noch eine Frage:

Wir setze ich am einfachsten einen Teil des Arrays auf Nullwerte

Wie gesagt, das Array ist: PV [0..2, 1..288] Of Real
Nun will ich mit einem Befehl das Array 0 also 288 werte auf 0.0 setzen.

Danke und Gruß Stefan
 

Ralle

Supermoderator
Teammitglied
Beiträge
15.101
Punkte Reaktionen
3.818
Zuviel Werbung?
->Hier kostenlos registrieren
So, nun läuft mein logger aber ich habe noch eine Frage:

Wir setze ich am einfachsten einen Teil des Arrays auf Nullwerte

Wie gesagt, das Array ist: PV [0..2, 1..288] Of Real
Nun will ich mit einem Befehl das Array 0 also 288 werte auf 0.0 setzen.

Danke und Gruß Stefan

Entweder du programmierst dafür eine Schleife (siehe Befehl LOOP in der Step7 Hilfe) oder du nutzt den SFC21 (FILL).

PS. Das mit dem DB-Aufruf sollte eigentlich gehen, zumindest, wenn es eine Temp-Var ist, bei einer Stat-Var in einem FB bin ich mir gerade nicht sicher was genau passiert...
 
Zuletzt bearbeitet:

borromeus

Well-known member
Beiträge
2.270
Punkte Reaktionen
329
Also das ist dann komisch!
Leg dir mal einen UDT an und ändere es im Baustein so das dort staht dem Array ein UDT steht!


So sollte es auf jedenfall auch bei dir funktionieren
Später im DB Messwerte bei Feld statt dem Array den udt eingeben!

GRUß

OK, funktioniert alles....
Fehler war, eine nicht aktualisierte Symboltabelle.
Danke
 
Oben