Dynamische DB Adressierung bei SCL

mr.binford

Level-1
Beiträge
36
Reaktionspunkte
2
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich versuche mich seit neustem mit SCL.

Meine Frage bezieht sich auf die Zeile :
DB_coDCO.DCO[RECORD].cmdSeqAon := db_recipe_control_001.SEQ_CONTROL.DCO[index].StepAon[Step_Nr];

Nun habe ich in meinem code nicht nur "db_recipe_control_001",
sondern auch db_recipe_control_002 und db_recipe_control_003 etc.

Bisher habe ich dies mit CASE gelöst, diese Lösung finde ich aber nicht so elegant.

Kennt jemand eine Lösung um diesen DB dynamisch zu anzusprechen?

////////////////////////////////////////
FUNCTION coSEQ_Control : void

VAR_TEMP
// Temporary Variables
INDEX : INT;
RECORD : INT;
END_VAR

VAR_INPUT
COUNT : INT; // pointer of element
STEP_NR : INT; // actual step number
RECIPE_NR : INT; // source recipe
END_VAR


FOR index := 1 TO count BY 1 DO
// load right record number
RECORD := db_recipe_control_001.SEQ_CONTROL.DCO[index].RecordNr;
DB_coDCO.DCO[RECORD].cmdSeqAon := db_recipe_control_001.SEQ_CONTROL.DCO[index].StepAon[Step_Nr];

END_FOR;


END_FUNCTION
////////////////////////////////////////////////////////////////
 
Dynamische DB Adressierung bei SC

Vieleicht hilft dir das.
Code:
Var_in
DBNR:int;// integer angebener Datenbaustein
End_Var


var
index:int;//Interger angegebenes Datenwort
end_Var


Beginn

Mw200:=Word_to_Block_DB(int_to_word(DBNR)).DW(index);//

End_Function
Viele Grüße Bernard
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das geht leider nicht mit symbolischer Adressierung, sondern nur absolut, siehe Bernard. Das endet leider in extrem krytischen Anweisungen und man verliert ganz fix den Überblick. Daher nehme ich auch oft die "unelegante" Version von dir, wenn es denn möglich ist.
 
Das endet leider in extrem krytischen Anweisungen

Wenn man den indizierten Datenbaustein über eine vorverarbeitende Schleife in einen internen structurierten Speicherbereich bringt,läßt sich danach voll Symbolisch arbeiten.

Viele Grüße Bernard
 
Danke für den Hinweis.

ich habe es nun so gelöst, dass ich die Struktur beim FC aufruf übergebe :
VAR_INPUT
COUNT : INT; // pointer of element
STEP_NR : INT; // actual step number
RECIPE_NR : INT; // source recipe
SEQ_CONTROL : UDT19; // structure of control recipe
END_VAR

//////////////////////



///////////////////////

FOR index := 1 TO count BY 1 DO
// load right record number
// RECORD := db_recipe_control_001.SEQ_CONTROL.DCO[index].RecordNr;
// DB_coDCO.DCO[RECORD].cmdSeqAon := db_recipe_control_001.SEQ_CONTROL.DCO[index].StepAon[Step_Nr];
RECORD := SEQ_CONTROL.DCO[index].RecordNr;
DB_coDCO.DCO[RECORD].cmdSeqAon := SEQ_CONTROL.DCO[index].StepAon[Step_Nr];


END_FOR;


2 Fragen hierzu:

1 . Hat es einen Nachteil (CPU Belastung) wenn ich die Struktur übergebe?
2. Wenn ich die von Dir beschriebene Lösung einsetze (muss ich da machen, wo ich nicht für jedes Rezept den FC einzeln aufrufen werde).
kann ich dan die DW Adresse einfach durch multuplizieren des offset mit dem index realisieren?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn man den indizierten Datenbaustein über eine vorverarbeitende Schleife in einen internen structurierten Speicherbereich bringt,läßt sich danach voll Symbolisch arbeiten.

Viele Grüße Bernard

Dassss verstehe ich nicht so ganz. Kannst Du mir das bitte etwas genauer erklären?

Danke!
 
Ich mach mal. ;)

Die UDT zu übergeben hat den Nachteil, daß man diese nicht weiter durchreichen kann. Wenn du also in deinem Baustein nochmal einen Bsuatein aufrufen willst, der mit dieser UDT arbeitet ginge das nicht.

Bernhard übergibt den Baustein und vielleicht noch einen Startpunkt und die Länge an den FB und kopiert dann die ganzen Daten in eine Strucktur um, die z.Bsp. im Stat-Bereich liegt. Mit der kann man dann voll symbolisch arbeiten. Aber falls man dort auch Daten verändert, müßte man es nachher wieder zurückkopieren. Außerdem kostet das Umkopieren natürlich Zeit. Hängt immer auch von der verwendeten SPS und vom Umfang des Ganzen ab.
 
Zuletzt bearbeitet:
Hallo,
wie wäre es denn, wenn du anstelle eines FC einen FB anlegst und die Daten zu einem Bestnadteil der Instanz machst. Dann kannst du in SCL auch sinnvoll darauf zugreifen und auch ggf. Datensätze nach irgendwo hin übergeben ...

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Im Prinzip währe es hier sinnvoll einen BufferDB oder instanz DB zu nehmen, wo ich vor und nach dem Schreiben die daten kopiere .

Ok Im Moment werde ich die date nnicht weiteeeerreichen, so kann ich die UDT übergeben, aber für den rest versuche ich mich mal mit der Adressberechnung.

Danke!
 
... das mit der Adress-Berechnung macht in SCL eigentlich gar keinen Sinn ...
Ich würde immer versuchen, das sinnvoll zu umgehen ...
 
....evtl. hast D uda recht.

Das was mir gut an SCL gefällt, ist die Symbolische Adressierung, und die schalte ich ja mit so einer Massnahme aus :)

Ich versuche das Ding mir der UDT Übergabe zu realisieren.

Noch eine Frage hierzu:

wenn ich einen Datentyp ändere und den DB neu Übersetze, gleicht sich dann der SCL code automatisch mit ab, oder verschiebt er sich, so wie ein in AWL geschriebener Code?

noch eine Frage :

Hat schon Jemand die Unterschiede AWL vs SCL in Punkto Pervormance aufgenommen oder gibt es hierzu Erfahrungen?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
wenn du den UDT oder den DB-Aufbau änderst, so kann SCL das nur nachvollziehen, wenn ihm diese Maßnehmen bekannt sind und du den SCL-Baustein neu generierst (compilierst). Das würdest du natürlich automatisch tun, wenn deine Daten Bestandteil der FB-Instanz sind (deshalb der Vorschlag) und der FB die Daten wahlweise ausgibt oder wieder aufnimmt. Das kann man z.B. durch eine entsprechende Binär-Beschaltung von Aussen realisieren.

Ob SCL-Bausteine langsamer oder schneller wie AWL-Bausteine sind läßt sich nicht pauschal sagen. Das ist sehr von deinem Baustein selbst abhängig - unter Umständen wird von SCL bei Verwendung von Strukturen ein ganz schönes pointer-Wirr-Warr in AWL erzeugt, was dann nicht unbedingt Laufzeit-optimiert ist. Im Gegenzuig erhälst du dafür gut durchschaubare Bausteine und Prozessorleistung ist im Zweifel nachrüstbar ... wähle selbst ...

Gruß
LL
 
Sorry aber nun habe ich ein anderes Problem.

wie kann ich bei diesen Aufruf :

CALL "coHMI_IVT_Recipe"
INDEX :="DB_IVT_Control_HMI".HMI_INDEX
val :=LW0
UPDATE_CMD :="DB_IVT_Control_HMI".HMI_UPDATE_DIALOG
SAVE_CMD :="DB_IVT_Control_HMI".HMI_SAVE_CMD
EDIT_CMD :="DB_IVT_Control_HMI".HMI_EDIT_CMD
IVT_CONTROL:="DB_IVT_Control_001".IVT_CONTROL // p#301.dbx0.0

den "DB_IVT_Control_001" in einer schleife hochzählen?

Der "coHMI_IVT_Recipe" ist mein SCL FC und diesen rufe ich in AWL auf.
 
Was genau ist das, eine Int, ein Pointer, ein Any oder was? (Denke ja ein Int oder DINT, also einfacher Standardtyp)
Je nach dem, wird es nur mit dem selbst zusammenbauen der Adresse gehen.
Bei einer z.Bsp. vorher in eine Temp umkopieren und danach wieder zurück. Bei einem Any schaust du mal zuerst die FAQ des Forums durch (Any und Pointer), stellst dann weitere Fragen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Es ist durchaus möglich und sinnnvoll mittels dynamischer DB-Adressierung weiterhin symbolisch innerhalb von SCL zu arbeiten.
Der Db Inhalt wird mittels indizierter Adressierung in eine Variable von Typ `Array of word` gelegt,zu dieser Arrayvariablen difiniert man ein`Sicht`,bei mir genauso groß wie das Array. In SCL greift man dann ncht auf die Arraygroessen zu, sondern auf die dort hinterlegten Sichtvariablen. Sodaß man in SCL vollsymbolisch arbeiten kann.
Leider kann ich im Augenblick kein Beispileprojekt hochladen da diese Funkion bei mir nicht funzt.Versuch es später noch einmal.
.
Code:
TYPE "Messgroessen"//UDT1 4 Word groß
STRUCT
    strom:REAL;//Strom
    Spannung:INT;//Ampere
    Zustand:BOOL;//1=ok
    END_STRUCT

END_TYPE


FUNCTION_BLOCK FBxxx
//***************************************************************************************************************
VAR_INPUT
DB_NR:INT:=1;  //Datenbausteinnummer 
Anf_Adresse:INT:=0;//Anfangsadresse der Inforamtion innerhalb des DB,Vorbelegung 0
END_VAR
//***************************************************************************************************************
VAR_output
Leistung:REAL;//Angabe in WAtt
Status:BOOL;//1=OK
END_VAR
//***************************************************************************************************************

VAR_TEMP
Index_Daten:INT;//Steuervariable für Datenübergabe von Extern
END_VAR
//***************************************************************************************************************
VAR
Datenspeicher:ARRAY[1..4] OF WORD;//Datenspeicher für die Versorgung von Extern länge wie UDT1
Messwert AT Datenspeicher:"Messgroessen";//Sichtweise auf Datenspeicher für die Bearbeitung intern,Format UDT1
END_VAR
begin
 //Datenübergabe von Extern an Datenspeicher
     Index_Daten:=1; //Vorbelegung Index mit 1  
      FOR Index_Daten:=1 TO 4 BY 1 DO//Schleife für Datenübergabe von Extern 4 Worte,länge wie UDT1
       datenspeicher[Index_Daten]:=WORD_TO_BLOCK_DB(INT_TO_WORD(DB_NR)).dw[2*Index_Daten-2+Anf_Adresse]; 
      END_FOR;
//Interne Programmierung mittels Sichten auf Datenspeicher       
Leistung:=Messwert.strom*(DINT_TO_REAL(INT_TO_DINT(Messwert.Spannung)));   //Übergabe nach OUT Beispiel 
Status:=Messwert.Zustand;
OK:=true;
END_FUNCTION_BLOCK
Viele Grüße Bernard
 
Beispieleprojekt hochladen

Anbei ein Versuchsprojekt in dem,innerhalb eines mit SCL erstellten FB,
Daten von aussen über direkte Adressierung übergeben werden.
Innerhalb des Bausteines wird über`Sichten` auf diese Daten vollsymbolisch zugegriffen.
Bei dem Beispiel geht es darum aus Strom u. Spannung die Leistung zu berechnen sowie den Zustand der Messung auszugeben.
Vat Tabelle zum lesen und schreiben der Daten liegt bei.

Viele Grüße Bernard
 

Anhänge

  • Dynamische_Daten_in_SCL.zip
    49 KB · Aufrufe: 19
Zurück
Oben