Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 19

Thema: Wie kann ich in einem Array of FB erfahren, welche Array-Nummer aktiv ist?

  1. #1
    Registriert seit
    19.05.2008
    Beiträge
    648
    Danke
    117
    Erhielt 136 Danke für 105 Beiträge

    Frage


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo Allerseits,

    zur Vereinfachung will ich Bausteine, welche sehr oft aufgerufen werden, gleich als ARRAY definieren. Das hab ich bereits getestet und geht auch ganz gut.

    Beispiel:
    VAR
    _ Antrieb : ARRAY[1..200] OF Motor_RL;
    END_VAR


    (* Aufrufe der Antriebseinheiten *)
    Antrieb[1](
    _ AntriebNr:= '001',
    _ sName:= 'Steigband Süd ',
    _ FRG:= I_NOT_AUS_iO,
    _ VWrechts:= I_M1_Rechts_123S1,
    _ VWlinks:= I_M1_Links_123S2,
    _ tRW:= t#1s500ms,
    _ Q_rechts=> Q_M1_Rechts,
    _ Q_links=> Q_M1_Links,
    _ sStatus=> sTemp_001); (* => AntriebNr & sName & Info-Intern *)


    Gibt es hier eine Möglichkeit, im FB auszuwerten, welche Array-Nummer gerade aufgerufen ist?

    Hintergrund ist, die Eingangs-Variable „AntriebNr“ wegzulassen und die Nummer von „Antrieb[i]“ direkt zu verwenden. Somit wird eine Falscheingabe verhindert und es müssen nicht so viele Parameter übergeben werden.

    Bin für jeden Tipp dankbar. Im Moment dreh ich mich nur im Kreis…

    Gruß
    Chräshe
    Angehängte Grafiken Angehängte Grafiken
    Zitieren Zitieren Wie kann ich in einem Array of FB erfahren, welche Array-Nummer aktiv ist?  

  2. #2
    Registriert seit
    19.11.2006
    Beiträge
    1.346
    Danke
    6
    Erhielt 254 Danke für 231 Beiträge

    Standard

    Deklarier im FB doch nen Eingang, dem du später dann die Nummer des Array-Elements übergibst.

  3. #3
    Registriert seit
    25.07.2007
    Beiträge
    79
    Danke
    2
    Erhielt 12 Danke für 12 Beiträge

    Standard

    Zitat Zitat von Chräshe Beitrag anzeigen
    Gibt es hier eine Möglichkeit, im FB auszuwerten, welche Array-Nummer gerade aufgerufen ist?
    Darf ich fragen wozu die Instanz den ArrayIndex wissen muss? Im Moment habe ich keine Vorstellung wozu das benötigt werden könnte.

    Damit ich nicht nur dumm herumfrage noch ein Beispiel wie vom trinitaucher vorgeschlagen:
    Code:
    (* -------------------------------------- *)
    (* Init Drive 1 *)
    Idx := 1
    Antrieb[Idx].sName    := 'Steigband Süd ';
    Antrieb[Idx].FRG      := I_NOT_AUS_iO;
    Antrieb[Idx].VWrechts := I_M1_Rechts_123S1;
    Antrieb[Idx].VWlinks  := I_M1_Links_123S2;
    Antrieb[Idx].tRW      := t#1s500ms;
    
    Q_M1_Rechts := Antrieb[Idx].Q_rechts;
    Q_M1_Links  := Antrieb[Idx].Q_links;
    sTemp_001   := Antrieb[Idx].sStatus;
    
    (* -------------------------------------- *)
    (* Init Drive 2 *)
    Idx := 2
    Antrieb[Idx].sName    := 'Steigband Nord ';
    Antrieb[Idx].FRG      := I_NOT_AUS_iO;
    Antrieb[Idx].VWrechts := I_M2_Rechts_122S1;
    Antrieb[Idx].VWlinks  := I_M2_Links_122S2;
    Antrieb[Idx].tRW      := t#1s500ms;
    
    Q_M2_Rechts := Antrieb[Idx].Q_rechts;
    Q_M2_Links  := Antrieb[Idx].Q_links;
    sTemp_002   := Antrieb[Idx].sStatus;
    
    (* -------------------------------------- *)
    (* Call instances *)
    For Idx := 1 to DRIVE_MAX
    do
      Antrieb[Idx] ( AntriebNr := Idx );
    end_if
    Geändert von ybbs (19.02.2010 um 19:11 Uhr)

  4. #4
    Registriert seit
    19.11.2006
    Beiträge
    1.346
    Danke
    6
    Erhielt 254 Danke für 231 Beiträge

    Standard

    Zitat Zitat von ybbs Beitrag anzeigen
    Darf ich fragen wozu die Instanz den ArrayIndex wissen muss? Im Moment habe ich keine Vorstellung wozu das benötigt werden könnte.
    Wenn er z.B. mehrere Antriebe mit gleicher Ansteuerung hat, aber je nach Position des Antriebs in der Maschine unterschiedliche Antriebsparameter verwendet werden sollen.
    Wenn der Parameter nicht im aufrufenden Programm, sondern im Antriebs-FB gehaltern werden soll, ist das sehr praktisch. Es vereinfacht den Code.

    Ich hab sowas schon häufiger programmiert.

  5. #5
    Avatar von Chräshe
    Chräshe ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    19.05.2008
    Beiträge
    648
    Danke
    117
    Erhielt 136 Danke für 105 Beiträge

    Idee

    Zitat Zitat von trinitaucher Beitrag anzeigen
    Deklarier im FB doch nen Eingang, dem du später dann die Nummer des Array-Elements übergibst.
    Hallo trinitaucher,
    meinst du etwa so...

    (* Aufrufe der Antriebseinheiten *)
    Antrieb[1](
    _ AntriebNr:= '001', (* hier zufällig als String, damit intern keine Wandlung notwendig wird *)
    _ sName:= 'Steigband Süd ',
    _...
    Ja, das könnte funktionieren.

    Meine Frage ist: Wie kann ich innerhalb vom FB Antrieb[x] erfahren, welches Array- Element gerade aktiv ist, ohne dass ich zusätzlich eine Nummer übergebe?
    Die Nummer soll immer mit [x] identisch sein. Bei Tippfehler käme es in diesem Fall zu falschen Statusmeldungen.
    Zitat Zitat von ybbs Beitrag anzeigen
    Darf ich fragen wozu die Instanz den ArrayIndex wissen muss? Im Moment habe ich keine Vorstellung wozu das benötigt werden könnte. [/CODE]
    @ybbs
    Um einem String eine eindeutige Meldenummer mitzugeben, für eine Statusanzeige in der Visu oder eventuell eine Protokollierung...

    OK, so sollte auch schon gut sein.

    (* Aufrufe der Antriebseinheiten *)
    Idx := 1
    Antrieb
    [Idx](
    _ AntriebNr:= Idx,
    _ sName:= 'Steigband Süd ',
    _

    Wenn jemand was eleganteres weiß, bin ich immer noch interessiert.

    Gruß
    Chräshe

  6. #6
    Registriert seit
    06.11.2005
    Ort
    daheim natürlich
    Beiträge
    119
    Danke
    11
    Erhielt 2 Danke für 2 Beiträge

    Standard

    Zitat Zitat von Chräshe Beitrag anzeigen


    Meine Frage ist: Wie kann ich innerhalb vom FB Antrieb[x] erfahren, welches Array- Element gerade aktiv ist, ohne dass ich zusätzlich eine Nummer übergebe?

    Gruß
    Chräshe
    geht nicht. habe das vor ein paar monaten auch schon mal probiert ( in meinem Fall habe ich das mit Fehler FB's versucht). bin dann auch auf die von trinitaucher erklärte Lösung gegangen. (ich kann damit leben, denn von nem Programmierer kann man schon erwarten das er 2mal die selbe Zahl an einem FB angibt)
    mfg,
    Flo

  7. #7
    Registriert seit
    29.03.2004
    Beiträge
    5.739
    Danke
    143
    Erhielt 1.686 Danke für 1.225 Beiträge

    Standard

    Ich habe in dem Zuge mal was mit der Berechnung der Speicheradressen probiert, um daraus den Index zu berechnen. Aber bei meiner Codesys Version (und Steuerung) kommt nichts sinnvolles heraus. Laut Dokumantation soll Pointerarithmetik im C-Stil möglich sein.

    Ich habe einen fbTEST:
    Code:
    FUNCTION_BLOCK fbTEST
    VAR_INPUT
    	pArrStart : POINTER TO BYTE;	(* Startadresse des Array *)
    	pArrAkt : POINTER TO BYTE;		(* Meine Adresse im Array *)
    	size : INT;
    END_VAR
    VAR_OUTPUT
    	dif : DWORD;
    	pos : DINT;
    END_VAR
    VAR
    	aAkt : DINT;
    	aStart : DINT;
    	dw : DWORD;
    END_VAR
    
    aAkt 	:= DWORD_TO_DINT(ADR(pArrAkt));
    aStart 	:= DWORD_TO_DINT(ADR(pArrStart));
    dw 		:= ADR(pArrAkt) - ADR(pArrStart);
    
    dif 	:= aAkt - aStart;
    pos 	:= dif / size;
    Diesen rufe ich als Array auf;
    Code:
    fbt : ARRAY[0..5] OF fbTEST;
    
    (************************************)
    aStart := ADR(fbt);
    
    fbt[0](
    	pArrStart:= ADR(fbt),
    	pArrAkt:= ADR(fbt[0]),
    	size:= SIZEOF(fbt[0]) ,
    	dif => d,
    	pos => p
    );
    
    fbt[1](
    	pArrStart:= ADR(fbt),
    	pArrAkt:= ADR(fbt[1]),
    	size:= SIZEOF(fbt[0]) ,
    	dif => d,
    	pos => p
    );
    
    fbt[2](
    	pArrStart:= ADR(fbt),
    	pArrAkt:= ADR(fbt[2]),
    	size:= SIZEOF(fbt[0]) ,
    	dif => d,
    	pos => p
    );
    Theoretisch sollte an "pos" die Position in Array herauskommen, tut es aber nicht.
    Für das was ich in der Onlinesicht sehe habe ich mal einen Screenshot gemacht. Es ist schon komisch dass bei der Adress-Onlinesicht an "aStart" jedes mal ein anderer Wert berechnet (oder zumindest angezeigt) wird.
    Angehängte Grafiken Angehängte Grafiken

  8. #8
    Registriert seit
    29.03.2004
    Beiträge
    5.739
    Danke
    143
    Erhielt 1.686 Danke für 1.225 Beiträge

    Standard

    Hach, direkt nach dem Absenden sieht man den Fehler. Im Baustein darf der Adressoperator natürlich nicht stehen:
    Code:
    aAkt   := DWORD_TO_DINT(pArrAkt);
    aStart := DWORD_TO_DINT(pArrStart);
    dw     := pArrAkt - pArrStart;
    
    dif 	:= aAkt - aStart;
    pos 	:= dif / size;
    Dann kommt an "pos" auch die passende Position heraus.

    Nur ganz ohne zusätzlichen Parameter scheint es so auch nicht zu gehen, da z.B. ein sizeof() vom eigenen Baustein wegen Rekursion nicht möglich ist.

  9. #9
    Registriert seit
    11.07.2004
    Beiträge
    1.597
    Danke
    10
    Erhielt 213 Danke für 183 Beiträge

    Standard

    das geht unter Umständen schon, erfordert aber drei Dinge:
    -die erste Variable im FB muß gleich bleiben (es darf also nachträglich keine weitere davor gesetzt werden)
    -eine Arrayposition muß bekannt sein (also beispielsweise die [0])
    -das Array von FBs muß entweder Global definiert sein oder aber muß bekannt sein, in welchem Programm es angelegt ist. Im Beispiel unten wurde letzteres gemacht.

    Im FB sieht es dann so aus:

    Code:
    FUNCTION_BLOCK fbTest
    VAR_INPUT
        MeinEingangsparameter1:    INT;
    END_VAR
    VAR_OUTPUT
        Index:    DINT;
    END_VAR
    VAR
        Test1:    DINT;
        Test2:    DINT;
        Test3:    INT;
    END_VAR
    Code:
    Index:=(ADR(MeinEingangsparameter1)-ADR(PLC_PRG.fbt))/SIZEOF(PLC_PRG.fbt[0]);
    Test1:=Test1+1;
    Test2:=Test2-1;
    Test3:=DINT_TO_INT(Test1+Test2);
    Test1, Test2 und Test3 dienen nur zur Verdeutlichung wo das eigentliche Programm stehen kann
    Geändert von Oberchefe (20.02.2010 um 11:14 Uhr)

  10. #10
    Registriert seit
    29.03.2004
    Beiträge
    5.739
    Danke
    143
    Erhielt 1.686 Danke für 1.225 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Zitat Zitat von Oberchefe Beitrag anzeigen
    das geht unter Umständen schon, erfordert aber drei Dinge:
    -die erste Variable im FB muß gleich bleiben (es darf also nachträglich keine weitere davor gesetzt werden)
    -eine Arrayposition muß bekannt sein (also beispielsweise die [0])
    -das Array von FBs muß entweder Global definiert sein oder aber muß bekannt sein, in welchem Programm es angelegt ist. Im Beispiel unten wurde letzteres gemacht.
    Die erste Variable, in dem Fall ADR(MeinEingangsparameter1), ist dann gleichbedeutend mit dem in der Objektorientierung üblichen this-Zeiger (oder self-Zeiger, je nach Sprache).
    Bei ST kann ich den Startindex im Array aber auch bei != 0 beginnen lassen, dann hat die Zahl die ich berechne keine direkte Bedeutung mehr.

Ähnliche Themen

  1. Antworten: 6
    Letzter Beitrag: 30.09.2011, 13:35
  2. Startwert von einem Array in DB
    Von Flo im Forum Simatic
    Antworten: 8
    Letzter Beitrag: 05.03.2010, 14:09
  3. Warum kann S7 nur 6-dimensionales Feld (Array)?
    Von bischkul im Forum Simatic
    Antworten: 15
    Letzter Beitrag: 26.10.2009, 21:14
  4. UDT Array Input an einem FC
    Von TagebauCoder im Forum Simatic
    Antworten: 17
    Letzter Beitrag: 04.10.2009, 02:29
  5. Probleme mit einem Array
    Von Hitschkock im Forum CODESYS und IEC61131
    Antworten: 7
    Letzter Beitrag: 30.03.2009, 11:42

Stichworte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •