Positions / Koordinatenabfrage-abfrage in SCL oder auch AWL

Bonsai-San

Level-1
Beiträge
34
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen

Ich habe folgendes Problem:

ich soll die Koordinate aus einer Datenbank abhängig von der Istposition auslesen.
Dazu muß ich aber gleich sagen, ich habe von SCL noch nicht so viel Ahnung, arbeite mich da gerade erst ein.

In der Tabelle die Entfernung im Verhältnis zur Position:
Code:
  |        |       |       |       |       |       |       |  
 100      156     219     248     312     366     420     486
  x1      x2      x3      x4      x5       x6      x7      x8

Aufbau der DB
DB1
Code:
ADRESSE   NAME    TYP       Anfangs...    Komment..
0.0       X1      DINT      L#100         Platz 1
4.0       X2      DINT      L#150         Platz 2
8.0       X2      DINT      L#200         Platz 3 ....

Istposition wäre z.B 221
Ergebnis sollte dann logischerweise X3 sein, da 221 näher an 200 als 250 liegt.

bin gespannt auf eure Ideen bzw Anregungen.

schon mal Danke

Sascha

Änderung: der Abstand zwischen den einzelnen Positionen soll variabel sein
 
Zuletzt bearbeitet:
Hallo,

Die Auswahl, welcher Wert gebraucht wird machst Du über ein Fenster. Du vergleichst den Wert mit einer Unter/Obergrenze. Wenn er hineinfällt, dann lädst du aus deinem Datenbaustein welchem du noch 2 Zeilen(Wert für Positionsfenster0 und 50) vorannstellst mitttels Pointer, welcher nach folgender Formel im Datenbaustein positioniert wird den Wert.
Adresse=Positionsfenster/50*4

Thomas

Ps: Den Vergleich kannst du dementsprechend kurz in einer Schleife ausführen indem du der UG/OG in jedem Durchlauf 50 addierst.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich würde den DB als Struct Array aufbauen, dann kannst du das Array einfach über eine Schleife durchlaufen und musst nicht mit Adressen arbeiten. Dann einfach 25 auf den aktuellen Array-Wert addieren und gucken ob du mit deiner Position grösser oder kleiner bist, daraus ergibt sich dann ob dein Name aus dem aktuellen oder nächsten Array-Element kommt. Sollten in SCL so 5-8 Zeilen sein. ;)
 
vorgestellt hab ich mir das so auch :ROFLMAO:

nur das umsetzen ist komisch..

mmh, könnt ihr mir ein Buch empfehlen wo ich so etwas nachlesen kann ??
wie gesagt, hab gestern das erste mal etwas mit SCL zu tun gehabt

MfG
Sascha
 
mmh, irgendwo muß hier ein Denkfehler sein, wer kann ihn finden :confused:

Code:
FUNCTION FC100 : void
VAR_INPUT
    IP: INT;  
    Pos_DB : BLOCK_DB;
    erste_adr: INT;
    letzte_adr: INT;
END_VAR
VAR_TEMP
    Pos_dif: DINT ;
    x_1: INT ;
    x: INT ;
    IP_DB: INT ;
    Pos_X: DINT ;
    Pos_Y: DINT ;
END_VAR
 
VAR_OUTPUT
        Koordinate: DINT ;
 
END_VAR
 
VAR
 
END_VAR   
 
BEGIN   
 
//Schleife hochzählen 
FOR x :=erste_adr TO letzte_adr BY 4 DO
    IF IP < Pos_DB.Dd[x] [COLOR=red]THEN[/COLOR] IP_DB := 1 ;    
    ELSE IP_DB := 0 ;
 
    END_IF;
END_FOR;
IF IP_DB = 1 THEN 
    x_1 := x-4;
    Pos_dif := ((Pos_DB.DD[x] - Pos_DB.Dw[x_1]) / 2);
    Pos_X := Pos_DB.DD[x]-Pos_dif;
END_IF;
IF IP < Pos_X THEN 
   Koordinate := x/4;
ELSIF IP > Pos_X THEN
 Koordinate := x_1/4;
END_IF;
 
END_FUNCTION

Bei der Roten markierung zeigt er mir folgenden Fehler an:
Code:
Der Ausdruck muss vom Datentyp BOOl sein
 
Probier mal Semikolon am ende der zeile mit dem roten THEN wegmachen
Ne, das Semikolon ist schon richtig,
aber (wird wohl auch nichts helfen) das ganze in einer Zeile habe ich so noch nie gesehen und gemacht.
Ein Versuch ist es ja mal Wert, nach dem "THEN" einen Zeilenumbruch.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Datentypen passen nicht zusammen. Ich kann mir auch nicht vorstellen dass es nur die eine Fehlermeldung gibt.
Die Variable IP ist ein INT, und Pos_DB.DD[x] ist ein Doppelwort. Verschiedene Datentypen kann man in SCL nur mit einer entsprechenden Konvertierungsfunktion vergleichen.

Probier mal:
Code:
IF IP < DWORD_TO_INT(Pos_DB.DD[x]) THEN
 
Guten Abend,
eine Lösung in AWL.


Im Anhang ist ein S7 Programm, welches in einer Schleife die Koordinaten einliest, mit der Ist-Position vergleicht und die nächst nähere Postion ausgibt.

Die Koordinaten stehen im DB1.
Im OB1 wird der Baustein aufgerufen in dem die Schleife abläuft.

Es können nachträglich die Koordinaten verändert werden da die Schleife flexibel ist.


Anzahl Koordinaten -1 = Schleifen anzahl

erste Koordinate = 0
letze Koordinate = Maximum

DB1.DBD0 = X1
DB1.DBD4 = X2
...

MD 4 = Ist-Koordinate
MD 10 = nächst nähere Koordinate




Mfg

Alex
 

Anhänge

  • Koordina.rar
    291 KB · Aufrufe: 8
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Datentypen passen nicht zusammen. Ich kann mir auch nicht vorstellen dass es nur die eine Fehlermeldung gibt.
Die Variable IP ist ein INT, und Pos_DB.DD[x] ist ein Doppelwort. Verschiedene Datentypen kann man in SCL nur mit einer entsprechenden Konvertierungsfunktion vergleichen.

Probier mal:
Code:
IF IP < DWORD_TO_INT(Pos_DB.DD[x]) THEN

Dacht da auch schon dran, meinte aber woher soll ich aus der Symbolik erkennen welche Wortbreite?
Aber am Schleifenzähler wars dann klar:ROFLMAO:

Hmm, merk grad wieder, dass ich öfter mit SCL arbeiten muss :ROFLMAO:
 
Die Datentypen passen nicht zusammen. Ich kann mir auch nicht vorstellen dass es nur die eine Fehlermeldung gibt.
Die Variable IP ist ein INT, und Pos_DB.DD[x] ist ein Doppelwort. Verschiedene Datentypen kann man in SCL nur mit einer entsprechenden Konvertierungsfunktion vergleichen.

Probier mal:
Code:
IF IP < DWORD_TO_INT(Pos_DB.DD[x]) THEN

Hallo Thomas

Habe auch schon beide auf DINT gesetzt, hat nichts geändert.
An gleicher Stelle bringt er noch die fehlermeldung Unzulässige Operantentypen
 
Hallo Thomas

Habe auch schon beide auf DINT gesetzt, hat nichts geändert.
An gleicher Stelle bringt er noch die fehlermeldung Unzulässige Operantentypen

Wo hast du beide auf DINT gesetzt ? In der Abfrage mit einem Typecast oder in dem Datenbaustein die Zelle ?
Wenn du absolut auf einen externen DB zugreifst so bekommst du die Inhalte immer im Rohformat (also je nach Breite in BOOL, BYTE, WORD oder DWORD) auch wenn die Werte im DB eigentlich anders formatiert sind. Du mußt also bei so etwas IMMER den Typecast (DWORD_to_DINT z.B.) einsetzen ...

Gruß
Larry
 
Code:
FUNCTION FC100 : void
VAR_INPUT
    IP: INT;  
    [COLOR="red"]Pos_DB : BLOCK_DB;[/COLOR]
    erste_adr: INT;
    letzte_adr: INT;
END_VAR
VAR_TEMP
    Pos_dif: DINT ;
    x_1: INT ;
    x: INT ;
    IP_DB: INT ;
    Pos_X: DINT ;
    Pos_Y: DINT ;
END_VAR
VAR_OUTPUT
        Koordinate: DINT ;
END_VAR
[...]
BEGIN
//Schleife hochzählen 
FOR x :=erste_adr TO letzte_adr BY 4 DO
    IF IP < [COLOR="Red"]Pos_DB.Dd[x][/COLOR] THEN IP_DB := 1 ;
Mal eine Frage:
Woher kennt der SCL-Compiler die Struktur des übergebenen Datenbausteins? Woher weiß er, daß da ein Array ist?

Harald
 
Mal eine Frage:
Woher kennt der SCL-Compiler die Struktur des übergebenen Datenbausteins? Woher weiß er, daß da ein Array ist?
Das weiß er eben garnicht, der Zugriff .DD[x] heißt Datendoppelwort Adresse x.
Mal angenommen er hat einen Datenbaustein mit Namen "Daten" in dem ein Array mit Namen DD liegt, müsste er mit "Daten".DD[x] zugreifen, also man kann es nur an den Anführungszeichen sehen.

Meines Erachtens ist es absolut nicht notwendig SCL noch mit absoluten Adressen zu arbeiten, und ganz schlechter Stil. Man muss seine Daten so strukturieren dass ich sowas nicht mehr brauche. Wenn ich um sowas nicht herumkomme sind die Daten falsch strukturiert.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das weiß er eben garnicht, der Zugriff .DD[x] heißt Datendoppelwort Adresse x.
Mal angenommen er hat einen Datenbaustein mit Namen "Daten" in dem ein Array mit Namen DD liegt, müsste er mit "Daten".DD[x] zugreifen, also man kann es nur an den Anführungszeichen sehen.

Es kommt sogar noch anders:
Habe ich ein Array mit Namen DD in einem Datenbaustein, so wird mit "Daten".DD[x] auf die Absolutadresse anstatt des Array-Elementes zugegriffen.
Könnte verfänglich werden, eine Compilerwarnung wäre hier imho angebracht.
 
Warum machst du das mit absoluter Adressierung? Mach das doch einfach mit einem Int-Array:

DB:
Code:
Data_Block "MyPos"
    nPos    :Array[1..10] of int;
End_Data_Block

FB:
Code:
...
IF IP < "MyPos".nPos[x] THEN
 
mmh

Jungs, ihr macht mir das Leben schwer :ROFLMAO:

ich bin doch völlig neu auf dem Gebiet.. hab nur (Outing) FUP Erfahrung...
aber ich bin willig und für alle tipps dankbar.

Deswegen nochmals meine Frage, was gibt es schriftliches was einem der Sache SCL etwas näher bringt ??

MfG
Sascha
 
Zurück
Oben