Bitnummer in DB (SCL)

Beiträge
226
Reaktionspunkte
27
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen.
Ich bin dabei, einen SCL-FC zu erstellen, mit einem Bit als Eingangsparameter.
Dieses Bit ist immer Teil eines Arrays. Nun sollte ich im FC den Arrayindex davon wissen.

Wenn ich also DBXY.ArrayXY[25] am FC verknüpfe, brauche ich IM(!!) FC die 25 als zBsp. Integer.
Wobei das ArrayXY vom Typ Bool ist.

Da das Array immer am Anfang eines DB's liegt, könnte ich das Bit als Pointer einlesen.
Denn die Bitnummer entspricht dabei immer dem Arrayindex da das Array von 0 - n geht.


Aus diesem Faden habe ich folgende Lösung:

http://www.sps-forum.de/simatic/24511-pointer-scl-kein-any.html

Code:
FUNCTION FC333 : void



VAR_INPUT
   Zeiger1 : POINTER;
    _Zeiger1 AT Zeiger1 : STRUCT
        DBNr: WORD;
        Adr: DWORD;
    END_STRUCT;
END_VAR



      ;
END_FUNCTION
Wie da auch steht, ist diese Deklaration als Input-Parameter in einem FC nicht möglich.

Ach übrigens, im AWL haben wir das so gemacht:
(ArrayBit ist ein InOut-Parameter vom Typ Pointer)
Code:
      L     P##ArrayBit
      LAR1 
      L     W [AR1,P#0.0]
      T     #DB_NR
 
      L     D [AR1,P#2.0]
      L     DW#16#FFFFFF
      UD   
      T     #INDEX

Und es muss ein FC sein. Hat jemand sowas ähnliches schon realisiert?
Ich hab auch daran gedacht einen reinen Pointer als Input-Parameter und einen als Tempvariable mit der Struktur
aber auch das frisst er mir nicht.

Im FB gehts. Der FC mag mich nicht :-(

Bin für alle Ideen dankbar.

Liebe Grüsse
 
Wenn Du dem FC den "DBXY.ArrayXY[25]" oder sonst einen "DBXY.ArrayXY[x]" übergibst, ist Dir doch zu diesem Zeitpunkt die Indexnummer 25 oder x bereits bekannt, sonst könntest Du den Arrayeintrag ja nicht übergeben.

Warum also übergibst Du die Indexnummer dann nicht einfach nochmal separat, wenn Du sie im FC benötigst?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi hucki
Da geb ich Dir natürlich zu 100% recht. Die Funktionalität wäre so absolut gegeben. Das ist nicht das Problem.
Es ist halt nicht die schönste Lösung. Ich möchte diesen einen Eingang mit dem Index noch sparen.
Ich habe ihn ja im Bit schon drin also ist es unnötig ihn nochmals manuell zu vergeben. Das muss einfach gehen.
Wie gesagt, manuell vergeben funktioniert, aber widerstrebt mir etwas. Auch weil der FC duzende Male pro Anlage verwendet wird.

Trotzdem Danke

Gruss
 
Es ist halt nicht die schönste Lösung. Ich möchte diesen einen Eingang mit dem Index noch sparen.
Ich habe ihn ja im Bit schon drin
Wenn Du nur das Bit übergibst, ist der Index nicht mit drin.



könnte ich das Bit als Pointer einlesen.
:confused:
Und das ist dann schöner und weniger umständlich als ein Bit und ein Int-Wert?
Ich glaub' da gehen unsere Ansichten auseinander. Vor allem dann, wenn das später mal jemand anderes (z.B. Instandhalter) verstehen muss.

Aber das ist Deine Entscheidung.
;)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Nochmals. Es ist ein FC geschrieben in SCL.
Dieser FC bearbeitet Mehrere Arrays. Diese Arrays sind alle gleich dimensioniert. In der Regel 1-512.
Gehen wir also davon aus, wir haben 3 Arrays, jeweils 1-512, 1 mal Bool, 1 mal Real, 1 x Integer.

Ein FC bearbeitet immer die drei Variabeln mit dem selben Index, also zBsp ArrayXYBool[34], ArrayXYReal[34] und ArrayXYInteger[34].
Dem FC muss ich dafür jeweils den Index angeben. Also gibts für jeden verwendeten Index einen FC-Aufruf.
Wie Hucki nun schon angemerkt hat, könnte ich dem FC einen INT als Input-Parameter geben und ihn einfach von aussen mit dem Index beschalten.
Funktioniert garantiert.

So, nun kann es sein, dass ich auf Inbetriebnahme oder Störungsbehebung den FC-Aufruf für den Index 34 suche. Ich weiss gerade nicht in welchem Baustein dieser Aufruf programmiert ist. Dann müsste ich eine Klartextsuche nach 34 machen.

Nun die Idee. Da das Array mit den Bits immer am Anfang vom DB steht, ist der Index immer Bitposition im DB + 1.
Bit 0.0 entspr. Bitposition 0 entspr. Index 1
Bit 0.1 entspr. Bitposition 1 entspr. Index 2
usw.

Wenn ich nun also als Input-Parameter einen Pointer verwende, und aussen am FC das Bit aus dem Array anlege, erhalte ich durch den Pointer
die Bitposition und somit den Index. Nur ist mir noch nicht ganz klar, wie ich in SCL mit dem Pointer dann umgehen kann. Wie wir das früher in AWL gemacht haben, habe ich ja als Beispiel angefügt. Wie es in einem FB geht, ist mir auch klar, aber der FC hat da so seine eigenen Bestimmungen und das ist mir nicht ganz klar und deshalb frage ich.

Das es mit dem Index einfacher ist, ist mir schon auch klar, aber was du sagst, stimmt nicht ganz. Gerade das Bit aus dem Array wird immermal wieder im Programm verwendet. Nehmen wir an im FBZZZ. Nun möchte ich im FBZZZ wissen wo der angesprochene FC-Aufruf für das Bit ArrayXYBool[34] ist, das kann ich dann mit einem Querverweis machen. Ist also Prinzipiell für den Instandhalter noch einfacher als nach Klartext 34 zu suchen.
 
Dein AWL Beispiel gibt dir aber auch nicht die indexnummer im Array aus oder? Das ist doch eher Zufall dass es grad passt.
Häng da mal ein zweites Array des DB an und überprüf den Index.

Edit: sorry letztes Post nicht gesehen. Wenn das Array immer am Anfang ist, funktioniert das natürlich. Aber brrr!
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ach übrigens, im AWL haben wir das so gemacht:
(ArrayBit ist ein InOut-Parameter vom Typ Pointer)

Hallo,
wenn du es in AWL mit einem INOUT machst - warum dann in SCL nicht auch ?
Ich kann das gerade nicht testen - könnte mir aber vorstellen, dass es dann geht (mit der AT-Sicht und der Auflösung davon).

Gruß
Larry
 
Ich glaube, ich habe das Anliegen verstanden. Hier mal ein Beispiel dazu. Die Typprüfung ist natürlich optional.

Code:
VAR_INPUT
  DEIN_BIT                          : ANY;                          // Bit als ANY übergeben
END_VAR

VAR_TEMP
  ANY_DEIN_BIT                      : ANY;
  X AT ANY_DEIN_BIT:
    STRUCT
      ID                            : BYTE;
      TYP                           : BYTE;
      ANZAHL_TYP                    : INT;
      DB_NR                         : WORD;
      ZEIGER                        : DWORD;
    END_STRUCT;
  BIT_INDEX                         : DINT;
  BYTE_INDEX                        : INT;
END_VAR


BEGIN

   ANY_DEIN_BIT := DEIN_BIT;
   IF SHR(IN:=X.ZEIGER, N:=24) <> 2#10000100 OR          // kein DB
      X.TYP <> 16#01                                     // Typ nicht BOOL
      THEN RETURN;
   END_IF;

   BIT_INDEX  := DWORD_TO_DINT(X.ZEIGER AND 16#0FFF);
   BYTE_INDEX := WORD_TO_INT(DWORD_TO_WORD(SHR(IN:=X.ZEIGER, N:=3)) AND 16#0FFF);

END_FUNCTION
 
wenn du es in AWL mit einem INOUT machst - warum dann in SCL nicht auch ?
Ich kann das gerade nicht testen - könnte mir aber vorstellen, dass es dann geht (mit der AT-Sicht und der Auflösung davon).
Der Pointer geht im In_OUT, aber die AT-Ansicht geht auf einen Pointer in SCL nicht. Pointer sind dort wohl nur zum Weiterreichen gedacht:
Siemens Simatic S7-SCL V5.3 für S7-300/400 schrieb:
SCL bietet jedoch nur eine Anweisung zur Verarbeitung des Datentyps POINTER
an: das Weiterreichen an unterlagerte Bausteine.
Da müßte er, wie von Harald und vom Onkel vorgeschlagen, auf Any ausweichen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen
Vielen Dank für die Antworten.

@LL
Hast recht. Aber gem. Hilfe kann eine Sicht für einen ANY bzw. Pointer im FC sowieso nur als VAR oder VAR_TEMP definiert werden.
Im FB gehts direkt als VAR_INPUT.

@ Onkel Dagobert
Astrein. Funktioniert einwandfrei. Da mein ARRAY von 1-XXX geht und der Bit-Index halt bei 0 beginnt musste ich noch jeweils 1 dazuzählen aber sonst echt genau was ich gesucht habe.
Vielen Dank dafür.

Habe mich da wohl zu sehr an den Pointer gehalten. Wobei ich glaube, dass es auch gehen müsste. Ich erhalte immer die Meldung, dass meine Sicht nicht zum Datentyp Pointer passt.
Scheinbar reichts nicht, wenn die Sicht einfach 6 Byte gross ist, sie muss wohl wirklich auch strukturell passen.


Edit:
@Hucki
Die SCL-Hilfe besagt aber dass auch im FC eine Sicht für Pointer möglich sein muss:

Sicht.png
 
Zuletzt bearbeitet:
Das gilt dann wohl eher für den ANY.
Den Pointer kannst Du im IN, IN_OUT und OUT deklarieren, aber keine Sicht darauf.
Und im TEMP geht vlt. die Sicht :)confused:) aber kein Pointer.
:(

Was Du sagst entspricht dem was ich gestern beim testen festgestellt habe. Dachte nur es müsse irgendwie gehen
da in der Hilfe der Pointer + Sicht angegeben ist. Aber da scheint es sich wohl wirklich eher um den ANY zu handeln.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
da in der Hilfe der Pointer + Sicht angegeben ist. Aber da scheint es sich wohl wirklich eher um den ANY zu handeln.
Solche "Ungenauigkeiten" sind allerdings nichts Ungewöhnliches in den Simatics Hilfen.
:(

Ähnliches wurde schon des Öfteren (zumindest in meiner subjektiven Wahrnehmung) hier im Forum gepostet.
 
Zurück
Oben