DB-Nummer in FB übergeben in SCL

Der Bithirte

Level-1
Beiträge
4
Reaktionspunkte
2
Zuviel Werbung?
-> Hier kostenlos registrieren
Abend zusammen
Hab da gerade ein kleines Problem und zwar folgendes:

Hab 12 Analogeingänge über die ich Messreihen aufnehmen möchte. Hab mir 12 DBs erstellt die alle aus einem "Datensatz ARRAY [1..1800] of Wert" bestehen (Wert ist als INT deklariert)

Jetzt möchte ich mir einen FB schreiben, der so variabel ist, dass ich nur noch meinen entsprechendes PEW (Analogeingang) und meine DB-Nummer übergebe, auf welchen ich alle 10 sec meine Messwerte schreiben möchte.

...der FB in SCL steht soweit und läuft, nur das mit der variablen Adressierung des DBs geht nicht!

so hab ich mir das vorgestellt:

VAR_INPUT
DB_NR :
???; //DB Nummer in welchen der AI geschrieben werden soll
.
.
.
END_VAR

VAR
Satz_Nr : INT; //Zählvariable für Arrayindex
.
.

.
END_VAR
.

Begin
.
.
.
If xxx Then //Alle 10 sec wird hier durchgelaufen

DB_Nr.Datensatz[Satz_Nr].Wert := Analogwert; //Messwert in DB schreiben
Satz_Nr := Satz_Nr +1;

End_If

Wie bekomme ich den Analogwert (berechnet und nomiert ist er schon) in den DB geschrieben, wie sieht der Syntax für den DB-Aufruf auf???

Grüße

 
Block_db

Hi, du kannst es als BLOCK_DB Deklarieren, aber finde ich nicht so Flexibel. Kannst deine DB NUmmer einfach als INT Deklarieren und dann dirket im FB umwnadeln. so kannst du direkt deine variable DB nummer berechnen und als integervariable dem eingangsparameter übergeben. Sollte so ungefähr funktoinieren:

Code:
[COLOR=#2e8b57]VAR_INPUT
DB_NR : INT[/COLOR][COLOR=seagreen]; //DB Nummer in welchen der AI geschrieben werden soll
.
.
.
END_VAR[/COLOR]
[COLOR=#2e8b57][/COLOR] 
[COLOR=#2e8b57]WORD_TO_BLOCKDB(INT_TO_WORD(DB_NR)).Datensatz[Satz_Nr] := Analogwert;[/COLOR]
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke an Bensen83 für den Vorschlag, aber so ganz gehts noch nicht!

Hier der aktuelle Stand der SCL-Quelle. Hab mal mein problem als Kommentar in die Quelle geschrieben. Vielleicht kann mir dann jemand noch den letzten Tip geben!

Code:
// UDT Analogwert ##########################################################
//
TYPE T_AI_WERT
AUTHOR  : TOS
VERSION : 1.00
  STRUCT
    Wert       : INT;
  END_STRUCT
END_TYPE
//##########################################################################
// DB_ANALOGWERTE ##########################################################
//
DATA_BLOCK DB_SPANNUNG_AKKU_1
AUTHOR  : TOS
VERSION : 1.00
  STRUCT
 
    Datensatz :  ARRAY[1..1800] OF T_AI_WERT;
 
  END_STRUCT
BEGIN  
 
END_DATA_BLOCK
//##########################################################################
 
 
 
 
FUNCTION_BLOCK FB_AI_WRITE
TITLE = 'Datensatz Suchen'
//
//Know_How_Protect
VERSION : '1.00'
AUTHOR  : TOS
CONST
    ENDE := 1800; //Achtung bei Änderung am DB muss dieser Wert angepasst werden! 
END_CONST
VAR_INPUT
    Start : BOOL;
    PEW_AI : INT;
    H_LIM : REAL;
    L_LIM : REAL;
    DB_NR : INT;
    ZEIT : TIME;
END_VAR
VAR_OUTPUT
  FEHLER : WORD;
  Fertig : BOOL;
END_VAR
VAR_TEMP
   AI_WERT_REAL : REAL;
   AI_WERT_DINT : DINT;
   AI_WERT_INT : INT;
END_VAR
VAR
  SATZ_NR : INT;
  T_PULS : TON;
  TEMP : INT;
END_VAR    
BEGIN
 
  IF Start THEN
 
       T_PULS (IN := Start AND NOT T_PULS.Q, PT := ZEIT); //Alle X sec. Flanke für Durchlauf Aufzeichnung generieren
 
       //Analogwert normieren
       FEHLER := SCALE(IN :=  PEW_AI
                ,HI_LIM :=  H_LIM
                ,LO_LIM :=  L_LIM
                ,BIPOLAR :=  false
                ,OUT :=  AI_WERT_REAL
                ); 
       //Analogwert wandeln in INT        
       AI_WERT_DINT := TRUNC (AI_WERT_REAL); 
       AI_WERT_INT := DINT_TO_INT (AI_WERT_DINT);  
 
       //Analogwert in DB schreiben
       IF T_PULS.Q AND NOT (Satz_Nr = 1800) THEN
         // WORD_TO_BLOCK_DB(INT_TO_WORD(DB_NR)).DW[Satz_Nr].Wert := AI_WERT_INT; ==> geht nicht da er .Wert nicht akzeptiert
         // WORD_TO_BLOCK_DB(INT_TO_WORD(DB_NR)).DW[Satz_Nr].DW[Satz_Nr] := AI_WERT_INT; ==> geht nicht da er AI_WERT_INT nicht akzeptiert als INT geht aber als WORD
         //==> sieht so aus, das er den ARRAY-Zugriff .Wert nicht akzeptiert!
          DB_SPANNUNG_AKKU_1.Datensatz[Satz_Nr].Wert := AI_WERT_INT;
          Satz_Nr := Satz_Nr + 1;
       END_IF;
 
       IF Satz_Nr = 1800 THEN
          Fertig := true; 
       END_IF;
 
  ELSE 
      Fertig := false; 
  END_IF;
END_FUNCTION_BLOCK
 
//######################################################################
 
Zuletzt bearbeitet:
Hallo,
über diese Form des Zugriffes kannst du nur den Rohdatenbereich übergeben - also BYTE, WORD und DWORD, nicht aber INT, DINT und/oder REAL.
Du müßtest dir also dein INT erst in ein WORD wandeln (z.B.).
Für dich konkret :
Code:
WORD_TO_BLOCK_DB(INT_TO_WORD(DB_NR)).DW[Satz_Nr].Wert := [COLOR=red][B]int_to_WORD[/B][/COLOR](AI_WERT_INT);
Gruß
Larry
 
Mahlzeit Larry Laffer
Vielen Dank für deine Antwort, genau das ist mein Problem, ich möchte die Daten als INT speichern und dafür hätte ich gerne eine variable Lösung.
Nur so wie sich das anhört geht das bei dieser Art der Adressierung nicht!

Und zu deinem Vorschlag:

Code:
WORD_TO_BLOCK_DB(INT_TO_WORD(DB_NR)).DW[Satz_Nr[COLOR=red]].Wert[/COLOR] := int_to_WORD(AI_WERT_INT);

Gibt es die Compiler-Fehlermeldung "Fehlerhafte Variable, der Punkt ist nicht zulässig"

Nehm ich jetzt ".Wert" raus, nimmt er mir das! Nur da hab ich ein kleines Problem damit, denn in diesem Fall mag das ja ok sein, hab ja ein Array-Element (UDT) mit nur einer INT deklariert dh funktioniert auch "DW[Satz_Nr]" ohne .Wert. Nur wenn ich jetzt einen großen UDT hab und ich möchte da Symbolisch drauf zugreifen bzw. drauf schreiben geht das halt plötzlich nicht mehr so leicht.....

Vielleicht kann mir da jemand mal paar Ansätze liefern, wie ich mir FBs aufbauen kann mit variabler Beschaltung von DBs

Beispiel:
12 Analogeeingänge
12 DBs
1 FB zum normieren und speichern der AI-Werte ==> FB ruf ich 12 mal auf und geb ihm nur das PEW (AI) und die DB_Nummer des DBs an, in dem ich meine Werte speichern möchte
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... jetzt bist du bei dem Elementar-Problem angekommen ...
Das mit dem ".Wert" hatte ich nicht gesehen - sorry - das geht natürlich nicht ...
SCL kann auf Alles symbolisch zugreifen, dass es kennt. Alles, was du dir absolut zusammenbaust (und das machst du da ja gerade) kannst du auch nur so ansprechen.

Wenn der UDT ein IN-Parameter (oder IN_OUT) deines FB's ist, dann kannst du natürlich wieder die darin liegenden Unterwerte direkt symbolisch ansprechen. Vielleicht ist das dein Weg.

Gruß
Larry
 
Ok

Hey Sory hatte bei mir auch noch was vergessen. Wenn du Symbolisch drauf zugreifen willst müstte es doch so gehen:

Code:
[COLOR=#2e8b57]WORD_TO_BLOCKDB(INT_TO_WORD(DB_NR)).Datensatz[Satz_Nr].Wert := Analogwert;[/COLOR]
 
Zurück
Oben