Step 7 DB bearbeiten?

spirit

Level-1
Beiträge
961
Reaktionspunkte
23
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi,

ich lese über einen Handscanner einen 15stelligen Barcode ein und schreibe diesen in einen DB. Der DB ist als Array [1..15] of CHAR deklariert. Später sollen die Daten dann über ein CP340 (oje ;) ) an einen Drucker gesendet werden.

Nun werden aber tatsächlich nur 6 der 15 Zeichen benötigt und sollen auf der Visu zur Anzeige gebracht werden. Habe etwas geforscht und die FC26 "MID" gefunden, mit der man den DB entsprechend "beschneiden" könnte; leider geht das aber nur bei String.


Frage:

Wie könnte ich das nun für CHAR lösen?


Lieben Dank!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke René,

du meinst also die gescannten Daten in einen String verschieben und dann die FC26 anwenden?


Wie sieht es dann aber aus, wenn die Daten an einen Scanner geschickt werden sollen - das müsste ja auch als CHAR passieren, oder?
 
Ich lese Ascii auch immer als Array of Char. Dann schiebe ich das in einen String.

Mit Strings lässt es sich leichter arbeiten und anzeigen da es dafür n haufen IEC Funktionen gibt.

zum versenden der so erhaltenen daten kopiere ich den String wieder in eine Struktur bestehend aus zwei Bytes und einem Array of Byte (um aktuallänge und maximallänge des Strings abzuschneiden)
Code:
      Snd : STRUCT         
         MaxLengt : Byte;
         ActLengt : Byte;
         Sendebereich : ARRAY[0..256] OF BYTE; // String
      END_STRUCT;

Also blockmove vom string nach "Snd"

am Sendebaustein hänge ich dann aber nur "Sendebereich" an. Der braucht üblicherweise keine informationen wie lange der String ursprünglich war (Ich hatte aber mal einen Empfänger der einen String im S7 format wollte. Da mussten also die Infobytes mitgeschickt werden).

PS: Bytearray kann natürlich auch ein Chararray senden. Ist egal für mich ist das einfach ein Buffer bestimmter Grösse.

mfG René
 
Hm, irgendwie ist es mir noch nicht ganz klar ...

Also,

1) Ich scanne den Barcode in ein Array of Char. So wie ich es jetzt schon habe!
2) Ich kopiere das Ganze in einen String
3) Jetzt bearbeite ich den String mittels der FC26 und zeige es auf der Visu an
4) Jetzt käme ja das Senden über CP340 an den Drucker an die Reihe - aber wie gehe ich da jetzt vor?

Es gibt hier ja den Sende-Baustein P_SEND; der Barcode muss aber als Ascii an den Drucker gesendet werden! Da kann ich ja dann nicht, wie von dir vorgeschlagen, ein Array of Byte senden oder ...


Müsste da dann erst wieder von String nach CHAR geschoben werden - ist aber sehr aufwändig? :confused:


Und was ist das bei dir für ein Sendebaustein - wo kommt der her?
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich nehme den Sende oder Empfangsbaustein der halt angesagt ist. Wenn ich Openuser fahre TSEND und TRCV. Ueber einen CP nehme ich halt AG_Send AG_RCV (dann muss aber eine Stehende Verbindung projektiert sein.)

Der Drucker erwartet Ascii. Er kann aber nicht erkennen wie das Paket bei dir deklariert ist. Die Deklaration ist für dich rein zur Anzeige und dass dein Kompiler weiss was damit zu tun ist.
Ob du nun ein Array of Byte, Char, DWORD etc sendest ist egal, Hauptsache die absolute Länge des Paket ist die welche erwartet wird. Der inhalt der Speicherplätze ist identisch ob du die nun als Byte oder Char deklarierst.

Ein String beansprucht immer mehr speicherplätze als ein CHAR du kannst also einen String nicht nach CHAR schieben sondern immer nur in eine struktur bestehend aus Länge und Maximallänge in byte gefolgt von einem array of CHAR/Byte/word whatever.

mfG René
 
Ich nehme den Sende oder Empfangsbaustein der halt angesagt ist. Wenn ich Openuser fahre TSEND und TRCV. Ueber einen CP nehme ich halt AG_Send AG_RCV (dann muss aber eine Stehende Verbindung projektiert sein.)

Beim CP340 projektiert man imho keine Verbindung und die genannten Bausteine glaub ich waren für Ethernet, oder?
 
korrekt. Quintessenz daraus. Man nimmt den Baustein der angesagt ist für Aufgabe, CP und Protokoll.
Trotzdem ist üblicherweise die Anbindung der Schnittstelle ziemlich dieselbe.

mfg René
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der Drucker erwartet Ascii. Er kann aber nicht erkennen wie das Paket bei dir deklariert ist. Die Deklaration ist für dich rein zur Anzeige und dass dein Kompiler weiss was damit zu tun ist.
Ob du nun ein Array of Byte, Char, DWORD etc sendest ist egal, Hauptsache die absolute Länge des Paket ist die welche erwartet wird. Der inhalt der Speicherplätze ist identisch ob du die nun als Byte oder Char deklarierst.

mfG René

1)
Eben das verstehe ich nicht so ganz! Der Drucker benötigt Ascii - aber hinter Ascii steht doch der Datentyp CHAR und nicht Byte oder DWORD.

2)
Ich nehme an, dass ich zum Schieben meiner Struktur in einen String (mittels Blockmove) immer zwei DB`s brauche und das nicht in einem einzigen händeln kann, richtig?

3)
Warum kann ich den DB, in den ich die Daten mittels Blockmove verschoben habe, nicht online beobachten?

DB.jpg
 
1)
Eben das verstehe ich nicht so ganz! Der Drucker benötigt Ascii - aber hinter Ascii steht doch der Datentyp CHAR und nicht Byte oder DWORD.

Wie groß ist ein CHAR? Geht doch von 0- 255 also ein Byte.

2)
Ich nehme an, dass ich zum Schieben meiner Struktur in einen String (mittels Blockmove) immer zwei DB`s brauche und das nicht in einem einzigen händeln kann, richtig?
Oder du macht die Aktion in einem FB und STAT Variablen.



Warum willst du deine CHAR in einen String umbauen?
Du bekommst Char geliefert, brauchst für den Drucker Char?
Du kannst aus deinem Array mit indirekter Adressierung dir die Buchstaben die für dich wichtig sind in einen anderen DB schreiben.

Du kannst dir auch selbst aus den Char einen String bauen.
Im Kopf ist Byte 0 die Anzahl der Zeichen und das zweite ist die maximale Anzahl der Zeichen. Ab dem dritten stehen deine Char drin.
Also geht auch ohne SFC.

Dein Drucker hängt an einem CP340. Für diese Baugruppe gibt es Bausteine, die mitgeliefert werden, damit du alles einstellen und übertragen kannst.



bike
 
Zuletzt bearbeitet:
Warum willst du deine CHAR in einen String umbauen?
Du bekommst Char geliefert, brauchst für den Drucker Char?
Du kannst aus deinem Array mit indirekter Adressierung dir die Buchstaben die für dich wichtig sind in einen anderen DB schreiben.

Du kannst dir auch selbst aus den Char einen String bauen.
Im Kopf ist Byte 0 die Anzahl der Zeichen und das zweite ist die maximale Anzahl der Zeichen. Ab dem dritten stehen deine Char drin.
Also geht auch ohne SFC.

bike


Danke bike,

nun das war ja ursprünglich der Vorschlag von vollmi, dass ich CHAR in STRING wandle mittels Blockmove!

Bin da jetzt mal wieder etwas überfordert - wie müsste ich das denn machen, wenn ich z.B. nur die Zeichen von Adresse 4 bis 9 benötige? :confused:

char.jpg

Könntest du mir da vielleicht mit einem Bsp. etwas weiterhelfen?
 
1)
Eben das verstehe ich nicht so ganz! Der Drucker benötigt Ascii - aber hinter Ascii steht doch der Datentyp CHAR und nicht Byte oder DWORD.

Ueber die Datenleitung werden aber nur Bits geschoben. Da gehen keinerlei Informationen welchen Datentyp die darstellen mitgegeben.
Ein Char besteht aus 8 Bit, also einem Byte. 1 Byte is 1 Byte und gibt keinerlei Auskunft ob das nun ein CHAR, INT, UINT etc sein könnte. Es wird daraus was der Empfänger erwartet.

2)
Ich nehme an, dass ich zum Schieben meiner Struktur in einen String (mittels Blockmove) immer zwei DB`s brauche und das nicht in einem einzigen händeln kann, richtig?

Du brauchst nicht mal einen. Eigentlich kannst du das auch in eine Temp Struktur laden. Und dann in einen Temporären String kopieren.

3)
Warum kann ich den DB, in den ich die Daten mittels Blockmove verschoben habe, nicht online beobachten?

Das geht so halt nicht. Da würde ich dann wieder die Stelle im VAT anschauen und zwar zeichen für zeichen.

Bin da jetzt mal wieder etwas überfordert - wie müsste ich das denn machen, wenn ich z.B. nur die Zeichen von Adresse 4 bis 9 benötige? :confused:

Kommt drauf an. In SCL wärs eine codezeile.

Code:
#zwischenstring  := MID(IN:=#Empfangsstring, L:=5, P:=4);

Wobei Zwischenstring ein String ist und Empfangsstring ebenfalls.

in AWL wärs nicht grossartig schwerer;
Code:
      CALL  "MID"
       IN     :=#Empfangsstring
       L      :=5
       P      :=4
       RET_VAL:=#zwischenstring

Aber natürlich kannst du dir da auch Pointer basteln. mit den einzelnen Chars rumwursteln und das irgendwie im Panel zusammensetzen.
Und an den Drucker ausgeben. Hat den Vorteil dass man das dann so programmieren kann das auch bestimmt keine aussagekräftige Referenzliste mehr erstellt werden kann und kein Mensch mehr sieht was da gemacht wird.

mfG René
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das ist IMHO eine typische Aufgabe, die man zuerst mit Stift und Papier löst, bevor man irgendwas programmiert.
Und wie vollmi schon schrieb: ein BYTE ist eine Speicherzelle der Größe 8 Bit, egal ob man das als BYTE, CHAR, ASCII-Zeichen oder sonstwelchen Datentyp deklariert. Was die Bits in der Bytefolge bedeuten interpretiert der Empfänger.

Code:
Barcode_CHAR CHAR-Array[1..15] (ab DB1.DBB0)
DB1.DBB0   1   2   3   4   5   6   7   8   9   10  11  12  13  14
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
      | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12| 13| 14| 15|
      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+


Teilstring STRING[6] (ab DB2.DBB0)
    DB2.DBB0   1   2   3   4   5   6   7
          +---+---+---+---+---+---+---+---+
          | ML| AL| 1 | 2 | 3 | 4 | 5 | 6 |
          +---+---+---+---+---+---+---+---+


Snd : STRUCT  //(ab DB3.DBB0)
  MaxLengt : BYTE;
  ActLengt : BYTE;
  Sendedaten : ARRAY[0..9] OF BYTE;
END_STRUCT;

    DB3.DBB0   1   2   3   4   5   6   7   8
          +---+---+---+---+---+---+---+---+---
          | ML| AL| 0 | 1 | 2 | 3 | 4 | 5 |...
          +---+---+---+---+---+---+---+---+---

Bei nur 6 Zeichen würde ich direkt die 6 BYTE/CHAR/Zeichen einzeln kopieren (statt großartiger Schleifen mit indirekter Adressierung oder SFC20 BLKMOV. Stringfunktionen funktionieren außerdem nur mit korrekt initialisierten Strings als Eingang und Ausgang).

4. bis 9. Zeichen kopieren in den String "Teilstring":
Code:
L 6
T DB2.DBB0                 //MaxLengt eintragen
T DB2.DBB1                 //ActLengt eintragen

L "DB1".Barcode_CHAR[4]    //DB1.DBB3
T "DB2".Teilstring[1]      //DB2.DBB2
L "DB1".Barcode_CHAR[5]
T "DB2".Teilstring[2]
L "DB1".Barcode_CHAR[6]
T "DB2".Teilstring[3]
L "DB1".Barcode_CHAR[7]
T "DB2".Teilstring[4]
L "DB1".Barcode_CHAR[8]
T "DB2".Teilstring[5]
L "DB1".Barcode_CHAR[9]
T "DB2".Teilstring[6]

4. bis 9. Zeichen kopieren in die Struktur "Snd":
Code:
L 9
T "DB3".Snd.MaxLengt       //DB3.DBB0
L 6
T "DB3".Snd.ActLengt       //DB3.DBB1

L "DB1".Barcode_CHAR[4]    //DB1.DBB3
T "DB3".Snd.Sendedaten[0]  //DB3.DBB2
L "DB1".Barcode_CHAR[5]
T "DB3".Snd.Sendedaten[1]
L "DB1".Barcode_CHAR[6]
T "DB3".Snd.Sendedaten[2]
L "DB1".Barcode_CHAR[7]
T "DB3".Snd.Sendedaten[3]
L "DB1".Barcode_CHAR[8]
T "DB3".Snd.Sendedaten[4]
L "DB1".Barcode_CHAR[9]
T "DB3".Snd.Sendedaten[5]

Da Du aber mit dem Baustein P_SEND über den CP340 senden mußt, brauchst Du eigentlich gar nichts kopieren sondern könntest dem P_SEND direkt die Adresse des 4. Barcodezeichens angeben, z.B. 6 Zeichen ab DB1.DBB3:
Code:
   +----------+
   |  P_SEND  |
   |...       |
 1-|DB_NO     |
 3-|DBB_NO    |
 6-|LEN       |
   |...       |

Oder die Sendedaten aus der Struktur Snd ab DB3.DBB2:
Code:
   +----------+
   |  P_SEND  |
   |...       |
 3-|DB_NO     |
 2-|DBB_NO    |
 6-|LEN       |
   |...       |

Harald
 
Bei nur 6 Zeichen würde ich direkt die 6 BYTE/CHAR/Zeichen einzeln kopieren (statt großartiger Schleifen mit indirekter Adressierung oder SFC20 BLKMOV. Stringfunktionen funktionieren außerdem nur mit korrekt initialisierten Strings als Eingang und Ausgang).

4. bis 9. Zeichen kopieren in den String "Teilstring":
Code:
L 6
T DB2.DBB0                      //MaxLengt eintragen
T DB2.DBB1                      //ActLengt eintragen

L "DB1".Barcode_CHAR[4]    //DB1.DBB3
T "DB2".Teilstring[1]           //DB2.DBB2
L "DB1".Barcode_CHAR[5]
T "DB2".Teilstring[2]
L "DB1".Barcode_CHAR[6]
T "DB2".Teilstring[3]
L "DB1".Barcode_CHAR[7]
T "DB2".Teilstring[4]
L "DB1".Barcode_CHAR[8]
T "DB2".Teilstring[5]
L "DB1".Barcode_CHAR[9]
T "DB2".Teilstring[6]

Harald

Ich danke euch für die Erklärungen ... bin ein Stückchen weiter; habe mir nun mal folgenden DB zusammengebastelt:

DB.jpg


Hierzu nun zwei Fragen:


1)
Warum muss bei Teilstring[n] als Datentyp eigentlich auch CHAR stehen; ist doch eigentlich ein STRING, oder nicht?

2)
In der Visu habe ich im Scanner-Feld eine Zeichenkette mit 13 Zeichen angelegt. Bekomme aber nur 10 angezeigt. Woran könnte das jetzt wieder liegen?
 
habe mir nun mal folgenden DB zusammengebastelt:

Anhang anzeigen 24786


Hierzu nun zwei Fragen:


1)
Warum muss bei Teilstring[n] als Datentyp eigentlich auch CHAR stehen; ist doch eigentlich ein STRING, oder nicht?
Anscheinend hast Du Teilstring als ARRAY[1..9] OF CHAR angelegt. Ich habe in meinem Beispiel Teilstring als STRING[6] angelegt.

Dem AWL-Code ist es aber sowieso egal, ob ein BYTE oder CHAR oder 1 Zeichen eines STRING gelesen oder transferiert wird, weil er nicht den Datentyp prüft sondern eine 8-Bit große Speicherstelle liest/transferiert. L und T werten nur die Größenangabe des Operanden aus, nicht dessen Typ.

In der Visu habe ich im Scanner-Feld eine Zeichenkette mit 13 Zeichen angelegt. Bekomme aber nur 10 angezeigt. Woran könnte das jetzt wieder liegen?
In welcher Visu hast Du wie eine Zeichenketten-Variable angelegt?
Ich vermute jetzt einfach mal, Du hast eine Variable als STRING angelegt und die Visu wertet deshalb das 2. Kopfbyte (aktuelle Stringlänge) aus und da steht womöglich eine 10 drin --> schreibe da doch mal eine 13 rein.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Anscheinend hast Du Teilstring als ARRAY[1..9] OF CHAR angelegt. Ich habe in meinem Beispiel Teilstring als STRING[6] angelegt.

Harald

Ja stimmt; das habe ich als Array angelegt!

ABER: Wenn ich es als STRING[9] anlege, dann erhalte ich ja nicht die Klammern hinter Teilstring[1], usw. Wie hast du das nur wieder gemacht? :confused:


In welcher Visu hast Du wie eine Zeichenketten-Variable angelegt?
Ich vermute jetzt einfach mal, Du hast eine Variable als STRING angelegt und die Visu wertet deshalb das 2. Kopfbyte (aktuelle Stringlänge) aus und da steht womöglich eine 10 drin --> schreibe da doch mal eine 13 rein.

Harald

Also es gibt in der Visu ein Eingabefeld, in das der Scanner den Barcode scannt. Dieses habe ich wie folgt definiert:

Darstellung = Zeichenkette

Feldlänge Zeichenkette = 13

Prozessvariable = Scanner


Unter Variablen habe ich dann bestimmt:

Visu.jpg


Jetzt bekomme ich aber nach dem Scannen eine seltsame Darstellung in dem Eingabefeld:

Anzeige.jpg

Irgendwie zum verrückt werden ... :-o

 
ABER: Wenn ich es als STRING[9] anlege, dann erhalte ich ja nicht die Klammern hinter Teilstring[1], usw. Wie hast du das nur wieder gemacht? :confused:
- erstelle in einem DB (z.B. DB2) an Adresse 0.0 die Variable "Teilstring" als STRING[10] (die geht dann bis 11.0)
- gib dem DB einen symbolischen Name, z.B. "DB2"
- schreibe im AWL-Editor:
Code:
L DB2.DBB0   //hierdrin muß die [COLOR="#0000FF"]Maximallänge[/COLOR] des Strings stehen: 10
L DB2.DBB1   //hierdrin steht die [COLOR="#0000FF"]aktuelle Länge[/COLOR] des Strings: am besten auch 10
L DB2.DBB2   //wird automatisch umgewandelt zu [COLOR="#0000FF"]"DB2".Teilstring[1][/COLOR]
L DB2.DBB3   //wird automatisch umgewandelt zu [COLOR="#0000FF"]"DB2".Teilstring[2][/COLOR]
...
L DB2.DBB11  //wird automatisch umgewandelt zu [COLOR="#0000FF"]"DB2".Teilstring[10][/COLOR]

Harald
 
Zurück
Oben