Step 7 Verarbeitung von String Variablen

CZach001

Level-1
Beiträge
65
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo, ich stehe vor folgendem Problem.

Ich erhalte von einem Sick Lector 620 einen Code die Länge des Codes variiert je nach Leseergebniss Good Read 18Byte No Read 6 Byte.
Die Daten werden in einem Datenbaustein als Zeichen eingetragen.
z.B. Code = 1234

im DB

DB72.dbb290 = 1
DB72.dbb291 = 2
DB72.dbb292 = 3
DB72.dbb293 = 4


oder im Fall das der Lector 620 den Code nicht lesen konnte wird als Ergebniss NoRead übertragen.

das sieht dann so aus.

DB72.dbb290 = N
DB72.dbb291 = o
DB72.dbb292 = R
DB72.dbb293 = e
DB72.dbb294 = a
DB72.dbb295 = d


Diese zeichenfolge schiebe ich mit SFC 20 blockmove in eine String Variable, die ich dann Vergleichen kann.


In der Anlage sind zwei Codeleser Verbaut, deren Ergebniss verglichen wird.
Das hab ich auch schon so weit Realisiert.

Ich möchte jetzt die je nach Codelänge entstehenden freien Variablen mit dem Platzhalter ( ' ' ) auffüllen, so das in der Stringvariable nur immer der Letzte gelesene Wert steht.

Bei einem Good Read des Lectors werden ab DB72.dbb


Da ich das ganze abhängig von der Codelänge machen möchte hätte ich das ganze gerne Berechnet.

Die Anzahl der Bytes des Leseergebnisses wird vom Lector in einer Variablen übergeben.

d. h. Startadresse (z.b. Db72.dbb290) + anzahl der aktuell eingelesenen Bytes (z.B. 6) = Startadresse ab der der Platzhalter in die Stringvariable geschrieben werden soll. (z.B. DB72.DBB296)


Ab dieser Startadresse soll die Stringvariable mit dem Platzhaltersymbol ( ' ' ) gefüllt werden.


Ich hab in diese Richtung wenig bis gar keine erfahrung, und hoffe das ihr mir ein bisschen auf die sprünge helfen könnt.

Mfg

CZach
 
#ZeichenLeer := #maxStringLaenge - #LectorLaenge;
#Ausgabestring := DELETE(IN:= #Eingabestring, L:= #ZeichenLeer, P:= #LectorLaenge+1);
 
Wenn nicht SCL, dann bleibt eigentlich nur AWL, also indirekte Adressierung
Lies dazu mal hier: http://www.sps-forum.de/faq/8887-pointer-zeiger-fifo-lifo.html

in Deinem Fall dann etwa so:

Code:
  Auf DB72 // DB72 aktivieren 
  L     290               // hier beginnt der String
  L #MyStrLen             // die Länge deines Strangs (z.Bsp. 6)
  +I
  L 1                     // das nächste Byte
  +I
  SLD   3                 // Pointer erzeugen
  LAR1                    // im ar1 steht p#297.0
  L     ''                // Leerzeichen 
  T     DBB [AR1,P#0.0]

Hier fehlt nun aber noch die Schleife, es wird nur 1 Byte befüllt!
 
Zuletzt bearbeitet:
PS: Zur Schleife suchst du mal in der Step7-Hilfe nach "Loop" oder hier im Forum.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn nicht SCL, dann bleibt eigentlich nur AWL, also indirekte Adressierung
Lies dazu mal hier: http://www.sps-forum.de/faq/8887-pointer-zeiger-fifo-lifo.html

in Deinem Fall dann etwa so:

Code:
  Auf DB72 // DB72 aktivieren 
  L     290               // hier beginnt der String
  L #MyStrLen             // die Länge deines Strangs (z.Bsp. 6)
  +I
  L 1                     // das nächste Byte
  +I
  SLD   3                 // Pointer erzeugen
  LAR1                    // im ar1 steht p#297.0
  L     ''                // Leerzeichen 
  T     DBB [AR1,P#0.0]

Hier fehlt nun aber noch die Schleife, es wird nur 1 Byte befüllt!

Hallo, danke für die Unterstützung,
ich hab das jezt mal so probiert, und funktioniert auch wie du beschrieben hast.

Ich hab mir jetzt die Anzahl der Freien Bytes berechnet (siehe anhang NW 5) und möchte nun eine Loop schleife erstellen, die entsprechend der anzahl der Freien Bytes durchlaufen wird.
Leider hab ich keine Ahnung wie der Syntax dafür aussehen soll.
In Rot mal mein Ansatz.
Ist der Gedanke Richtig die Schleife nur so oft zu durchlaufen bis alle freien stellen mit dem Leerzeichen gefüllt sind, oder spielt das keine Rolle.

der Schleifenzähler wird ja von der Loopanweisung automatisch dekrementiert oder das wird mit der Sprungmarke auf den schleifenzähler erreicht oder?



L #FreieBytes
schl: T # Schleifenzähler
Auf DB72 // DB72 aktivieren
L 290 // hier beginnt der String
L #MyStrLen // die Länge deines Strangs (z.Bsp. 6)
+I
L 1 // das nächste Byte
+I
SLD 3 // Pointer erzeugen
LAR1 // im ar1 steht p#297.0
L '' // Leerzeichen
T DBB [AR1,P#0.0]

LAR1 ein Byte hochzählen
L1
+I

L #Schleifenzähler
Loop schl

SPA end

end: NOP0


Mfg
CZach
und schon mal danke fürs Grübeln, wobei die meisten von euch wohl gar nicht lange grübeln müssen.
 
Zuletzt bearbeitet:
Schon mal nicht so schlecht, aber die Adresse rechnest du 1. falsch hoch und 2. bildest du in der Schleife am Anfang jedes Mal eine Neue Adresse, überschreibst also die hochgezählte.
Daher mal folgende Änderungen:

#My_Pointer ist eine Dword (kann Temp sein)
Du addierst auf diesen Pointer gleich einen 1 Byte "langen" Pointer, so schiebst du den Zeiger immer weiter

Code:
[COLOR=#333333]Auf DB72 // DB72 aktivieren [/COLOR]
[COLOR=#333333]L 290 // hier beginnt der String[/COLOR]
[COLOR=#333333]L #MyStrLen // die Länge deines Strangs (z.Bsp. 6)[/COLOR]
[COLOR=#333333]+I[/COLOR]
[COLOR=#333333]L 1 // das nächste Byte[/COLOR]
[COLOR=#333333]+I[/COLOR]
[COLOR=#333333]SLD 3 // Pointer erzeugen
[/COLOR][COLOR=#0000ff]T #My_Pointer[/COLOR]

[COLOR=#ff0000]L #FreieBytes[/COLOR]
[COLOR=#ff0000]schl: T # Schleifenzähler
[/COLOR]
[COLOR=#0000ff]L #My_Pointer[/COLOR]
[COLOR=#333333]LAR1 // im ar1 steht p#297.0[/COLOR]
[COLOR=#333333]L '' // Leerzeichen [/COLOR]
[COLOR=#333333]T DBB [AR1,P#0.0][/COLOR][COLOR=#ff0000]

[/COLOR][COLOR=#0000ff]L My_Pointer
L P#1.0
+D
T My_Pointer[/COLOR][COLOR=#ff0000]

L #Schleifenzähler
Loop schl

SPA end

end: NOP0
[/COLOR]
 
Hallo, und danke
ich hab das jetzt mal so umgsetzt und getestet, sieht aus als ob es funktionieren würde.

ich denke auch das ich es so grob verstanden habe.

Ich hab mal das Netzwerk kommentiert und hier angehängt, währe nett, wenn sich jemand meine Gedanken ansehen würde, ob ich richtig liege.

Noch eine Frage zum Trasferieren des Leerzeichens.
wir haben jetzt geschrieben.

L ' '
T DBB [AR1,P0.0]

weil wir ja vorher den wert von MyPointer mit LAR1 in das Adressregister 1 geschoben haben.

könnte ich mir das nicht sparen, und direkt schreiben.

L ' '
T DBB [#MyPointer]

der Untershied liegt ja nur daran, das ich im Fall 1 mit verändern von P#0.0 die Bitadresse des Datenbereichs beeinflussen kann.
da ich aber in meinem Fall nur Byteweise springe, würde das wie im Fall 2 auch Funktionieren.

Mfg

CZachAnhang anzeigen SPS_Forum_Loop.pdf
 
Hey
Das ist alles schön was man machen kann aber der lector kann doch bestimmt ein gelesen Bit beziehungsweise ein nicht gelesen Bit schicken. Wir haben den Lector 420 und benutzen den Baustein vom Sick wo diese Bits vorhanden sind.

Gesendet von meinem Nexus 4 mit Tapatalk
 
Ich mache mir das immer viel Leichter...

Immer wenn ich den empfangenen String ausgelesen und verarbeitet habe, lösche ich den gesamten Empfangspuffer ab.

In AWL im einfachsten Fall:

L ' '
T DB1.DBB0
T DB1.DBB1
...

Grüße

Marcel
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich mache mir das immer viel Leichter...

Immer wenn ich den empfangenen String ausgelesen und verarbeitet habe, lösche ich den gesamten Empfangspuffer ab.

In AWL im einfachsten Fall:

L ' '
T DB1.DBB0
T DB1.DBB1
...

Grüße

Marcel


Sehe ich auch so. :s12:

Damit ist der Empfangsbereich schon mit den gewünschten Platzhalter vorbelegt
und werden gleich mit in den String übertragen.
Musst aber die Anfangswerte im DB schon in dem Platzhalter versorgt haben.



P.S. @Matze: Du meinst sicher DB72 ?
 
Ja genau... Die DB-Nummer wollte ich jetzt nicht nochmal nachgucken, auch der Byteoffset wird nicht stimmen... aber so viel kreativität traue ich den Leuten schon zu.
Beim ersten Übertragen des Bausteins steht eh überall ' ' drin (das fasse ich nie an) und spätestens nach einem Bausteindurchlauf (Oder wenn die Auswertung auf mehrere Zyklen verteilt ist natürlich am Ende der Auswertung) wird wieder abgenullt. Man muss gucken was bei jedem Anwendungsfall die richtige Methode ist. Mal passen die Daten sofort, mal hat man die ersten 3-10 Nachrichten ASCII-Salat... alles schon gehabt... und alles hinbekommen.

Grüße

Marcel
 
Hey
Das ist alles schön was man machen kann aber der lector kann doch bestimmt ein gelesen Bit beziehungsweise ein nicht gelesen Bit schicken. Wir haben den Lector 420 und benutzen den Baustein vom Sick wo diese Bits vorhanden sind.

Gesendet von meinem Nexus 4 mit Tapatalk

Das hätte ich mir auch gewünscht, leider hat uns der Sick Vertriebler einen LECTOR 620 ECO mit einer Profinetanschaltung CDF 600-2200 verkauft.
Dieser ist nach meinem jetzigen wissensstand von der Funktionalität her leider auch ECO. Kann somit kein GoodRead/NoRead bit Ausgeben, und kann auch das angepriesene Parametercloning nicht.
Wir haben zwar noch ein Modul mit der Bezeichnung CDB 620 dazu bekommen, das für das Parametercloning in Frage kommen würde (Wurde auch zu diesem zweck gekauft) ich hab aber noch niemanden gefunden, der mir sagen konnte wie das zusammengebastelt gehört.
Laut Sick Service Hotline ergibt dieses Modul in meinem anwendungsfall keinen sinn, und der Vertriebler ist momentan Verschollen, so kann man den auch nicht Fragen, was er sich dabei gedacht hat.

Mfg
CZach
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo CZach,

nach meinem Wissensstand kann der CDF600 als Gateway (Mode=2) oder als Proxy (Mode=0) verwendet werden. Im Proxymode steht Dir dann auch das Parametercoloning zur Verfügung. Du benötigst allerdings eine andere GSD. Mit der Pro-Version hat es auf jeden Fall funktioniert.
 
Hallo CZach,

nach meinem Wissensstand kann der CDF600 als Gateway (Mode=2) oder als Proxy (Mode=0) verwendet werden. Im Proxymode steht Dir dann auch das Parametercoloning zur Verfügung. Du benötigst allerdings eine andere GSD. Mit der Pro-Version hat es auf jeden Fall funktioniert.


Das kann ich so bestätigen, leider gibt es für den Anschluss Lector 620 Eco am CDF600 noch keine Passende GSDML Datei, ist laut Doku des CDF600 "geplant".
Somit hab ich nur die möglichkeit den Lector im Gatewaymodus zu betreiben, und da ist leider die Funktionalität eingeschränkt.

Für meien geschmack ist da die Produkt und Optionsvielfalt zu groß, so das sich die Vertriebs und Servicemannschaft selbst schwer tut den überblick zu behalten.

Mfg
Czach
 
Hallo, ich hab jetzt die Variable so aufbereitet, das immer nur der zuletzt gelesene wert in der String Variable steht.
Danke nochmal an alle die dazu beigetragen haben.

Jetzt möchte ich diese Stringvariabel im Programmablauf vergleichen. Einmal ob sie am anfang der Schrittkette auf 0 gesetz worden ist,
einmal nach dem Einlesen der Daten vom Lector mit der Zeichenkette "NoRead" es darf kein NoRead in den Daten stehen das die schrittkette weitermacht.
Und einmal mit der Variable in der der Wert des Zweiten Lectors steht.

Für Punkt 3 Verwende ich den FC10 und Vergleiche die beiden Stringvariablen miteinander.
Diese Variablen werden immer mit der max. Bytezahl, der aktuellen Bytezahl (Information vom Lector) und dem eigentlichen Leseergebniss beschrieben.

Will ich nun die Stringvariable mit der Zeichenkette "NoRead" vergleichen, hab ich nur die möglichkeit in einem Datenbaustein eine Variable Typ String[25], mit dem Anfangswert "NoRead" zu erstellen, um diese dann mit der Stringvariable in der das Leseergebniss steht zu vergleichen.
Mit dieser lösung bin ich aber nicht ganz glücklich, da ich immer von diesem 1x beschriebenen wert abhängig bin.

Hat da jemand eine Idee wie man das eleganter lösen könnte??
 
Zurück
Oben