Mehrere Datenbausteine durchsuchen

smartie

Level-1
Beiträge
298
Reaktionspunkte
22
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich benötige gerade ein wenig Starthilfe bei meinem neuen Projekt.
Bestimmt kann mir jemand von euch einwenig auf die Sprünge helfen. :D

Über einen CP340 empfange ich von einem PC mehrere Datenstrings, die ich jeweils in einen Datenbaustein ablegen will.
In diesen Datenstrings befindet sich unter anderem eine Ziffernfolge mit einer festen Länge von 18 Zeichen (Seriennnummer).

Zu einem späteren Zeitpunkt wird mit einem Barcodescanner über einen zweiten CP340 eine dieser 18 stelligen Ziffernfolgen eingelesen.

Daraufhin muss ich die Datenbausteine nach der Seriennummer durchsuchen und anschließend den gefundenen Datenbaustein wieder über einen CP340 versenden.


Ich suche nun also nach einer Lösung mehrere Datenbausteine nach einer festen Ziffernfolge zu durchsuchen,
die irgendwo in einem String stehen kann.
Gibt es dazu eine Funktion?

Zudem bin ich noch am überlegen wie ich es anstellen kann meine Datenbausteine zu verwalten.
Ich hätte mir da überlegt ein Merkerbyte und 8 Datenbausteine zu verwenden.
Wenn ein DB beschrieben ist setze ich ein Bit in dem Merkerbyte damit ich weiß das dieser schon beschrieben ist.
Wird ein Datenbaustein dann wieder geleert (Ausgabe über CP340) dann würde ich das entsprechende Bit auch wieder zurücksetzen.

Meint ihr es wäre sinnvoll das so zu lösen?
Oder gibt es hier vielleicht eine bessere Lösung?

Wenn alle acht DB´s belegt sind und ich die Seriennummer nicht finden kann würde ich auf Störung gehen und alle acht DB´s leeren.


Als SPS setze ich eine S7-313C ein und bin schon am Grübeln ob ich da nicht an die Grenzen der SPS stoße. Was meint ihr?


Gruß smartie
 
Warum brauchst du 8 Datenbausteine, kannst du nicht alle eingelesenen Strings in einen DB ablegen und diesen durchsuchen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi marlob,

ich hab mir das auch schon überlegt, aber ich denken so ist es übersichtlicher.
Dann würde ich in jedem DB einen Datensetring haben und könnte jeden einzeln verarbeiten.

Wäre es einfacher wenn alle Strings in einem DB liegen?
Und was wäre wenn die Strings unterschiedliche Längen haben.
 
Also einen DB zu durchsuchen macht die Sache auf jeden Fall ein wenig einfacher. Du kannst in deinem DB ja 8 Strings definieren, die alle die max. vorkommende Länge haben. Die Länge des Strings ist sowiesoa m Anfang des Strings hinterlegt.
 
Die maximale Länge des Strings ist mir noch nicht bekannt aber das könnte ja machbar sein.
(Wobei mir gerade einfällt das sich das aber auch irgendwann mal ändern kann !)
Und die Länge des Strings kann ich ja auslesen und dann den entsprechenden String mit BLKMOV zu Weiterverarbeitung verschieben.

Wie müsste ich es denn dann machen das ein String den ich empfange im DB als letztes abgelegt wird.
Und wie mache ich es dann wenn ein String wieder aus dem DB gelöscht wird?

Dann habe ich ja evtl. eine Lücke, das ganze ist ja ein Prozess der sich immer wieder wiederholt.
In meinem einen DB sind ja prinzipiell immer bis zu 8 Datenstrings die nicht unbedingt in der Reihenfolge verarbeitet werden wie sie eingelesen werden.
Wenn ich dann die neuen Datenstrings immer unten anhänge würden mein DB ja irgendwann immer größer werden.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Sieh dir mal in der IEC-Library die Stringfunktionen an. Da gibt es u.a. FIND, INSERT, LEN, REPLACE, DELETE, CONCAT. Die Hilfe dazu erreichst du, indem du den Baustein in der Library anwählst und dann "F1" drückst. Am besten läßt sich das natürlich in SCL lösen. Im Prinzi ist es egal, wie viele Datenbausteine du benutzt, du mußt halt in einer Schleife alle Datenbausteine öffnen und mit FIND durchsuchen. Sollten die Strings länger als 254 Byte sein, mußt du den Gesamtstring im DB entsprechend splitten, da Step7-Strings nicht länger sein können.
 
Hallo Smartie,
ich würde in der Sache auch zu Marlob's Vorschlag tendieren.
Meine Idee könnte so aussehen :

Wenn du einen neuen String einliest, dann schreibst du ihn zunächst in einen Sammelbereich. Nun käme als nächstes deine Aktion (Daten ausgeben oden ablegen). Bei Aktion = Ausgeben scannst du den DB auf Übereinstimmung, ansonsten auf freien Platz. Ein Platz wird (zusätzlich) mit einem Bit als belegt gekennzeichnet.

Prinzipiell wäre das sogar eine Aufgabe für einen FB mit zugehörigem I-DB. Dann hast du alles zusammen und kannst die Funktionen über die IN / OUT-Parameter auslösen.

Willst du das in AWL schreiben ? Im Grunde würde sich hierfür SCL geradezu aufdrängen ...

Gruß
LL
 
Wenn ich dann die neuen Datenstrings immer unten anhänge würden mein DB ja irgendwann immer größer werden.

Das geht ohnehin so nicht, der DB muß in seiner Länge von vorherein festgelegt sein. Wenn, dann mußt du den DB also verwalten. Du legst z.Bsp. fest, daß der DB 20 Stringvariablen enthält (je 254 Char). In einem Feld (Array of Byte) oder auch in einem Bitfeld schreibst du dann für jeden belegten String eine 1 oder ein True. Wenn ein neuer String kommt, wird das Feld nach einem freien Platz durchsucht, da hinein kommt dann der neue String.
 
Um die werte hintereinander in einem DB zu schreiben, kannst du dir als Anregung mal den Beitrag zum FIFO aus der FAQ durchlesen

Meinst du marlob? Dann muß er ja ständig die Strings verschieben und kann mittendrin nichts so ohne Weiteres löschen. Ich würde eher zu einer Tabelle raten, in der die belegten Strings gekennzeichnet werden.
 
Daher sollte es eine Anregung sein, wie man überhaupt Daten hintereinander in einem DB ablegt, wegen Pointer und so:rolleyes:
Aber eine Tabelle mit Kennzeichnung ist schon besser
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

also ich habe jetzt ein Muster - Datentelegramm erhalten und es hat knapp 1600 Zeichen, aber das kann sich durchaus auch noch ändern. Soll heissen es können mal mehr werden.

Kann der CP340 so viele Zeichen überhaupt am Stück einlesen?
Und wohin? Ein String kann ja nur 254 Zeichen enthalten?

Was das Suchen in den Datenbausteinen betrifft, denke ich das die Version mit mehreren DB´s fast übersichtlicher ist, auch wenn es mehr Aufwand bedeutet.

SCL sagt mir leider nichts. Klar hab ich hier und da schon mal was davon gelesen, kann ich aber eben nicht. :???:

Was mir gerade ein wenig Bauchschmerzen besorgt ist die Länge des Datentelegramms. Kann ich das überhaupt verarbeiten?

Und dann ist da noch die Sache mit der CPU: Ich bin mir fast sicher das eine S7-313C viel zu wenig Resourcen für solch eine Aufgabe hat.

Was meint ihr?

Gruß smartie
 
Siehe hier: http://support.automation.siemens.com/WW/view/de/27072372

Also max. 1024 Byte pro Telegramm. Ob die CPU reicht? Schwierig zu sagen. Zuerst mal anhand der Länge und Anzahl der zu verwaltenden Nachrichten nachrechnen, ob der Speicher ausreicht. Dann kommt es darauf an, was die CPU noch so machen soll und wie zeitkritisch das ist. Immerhin muß ja die Suchfunktion in den langen Telegrammen nach Übereinstimmungen suchen, das braucht mit Sicherheit Zykluszeit. Die S7 ist für deinen Fall sicher nicht das NonPlusUltra :???: . Auf jeden Fall mußt du die ankommenden Daten irgendwie umrangieren. Wenn du IEC-Funktionen wie FIND nutzen willst, dann muß alles in 254-Byte-Strings zerhackt und später wieder zusammengesetzt werden. In diesem Falle sollte man sich evtl. besser eine eigene Suchfunktion schreiben, die dann vorteilhafter Weise, bei Bedarf, die Suche auch über mehrere SPS-Zyklen verteilen kann, um die Zykluszeit der SPS nicht ganz in die Knie zu zwingen. Kannst auch einmal über eine VIPA-Speed7 nachdenken.
 
Hui, ich hab mal sowas ähnliches gemacht, allerdings in kleinerem Masstab.

Ich hab ein kleines Programm geschrieben, was 5 DBs durchsucht, nach einer Art Materialnummer (auch von nem Scanner), welche aus 2 CHARs und einem Integer Wert bestand.
Und die 315 hatte sehr stark zu kämpfen mit der Zykluszeit (hab alles in einen Zyklus gepackt). Und das waren nur 5 Regale (5 DBs) á 20 x 5 Stellplätze...
Um zu schauen, ob eine Mat-Nr. schon eingelagert war, musste ich die DBs auch durchsuchen, im schlechtesten Fall hat es fast eine Sekunde gedauert, bis der Zyklus beendet war.

Ich hab den Quellcode noch hier, allerdings nicht die endgültige Version, wenn du Interesse hast...

Aber, was mir grad noch auffällt... 1600 Byte großes Telegramm? Oder war das nur ein Ethernet Packet? Wenn ich das richtig in Erinnerung hab, war doch die MSS 1460 Byte + die Header, Trailer, etc...
Wäre es bei so einer Datenmenge nicht vielleicht sinnvoller das ganze in einer SQL Datenbank zu verwalten?

P.S.: Ist bei Simatic ein String nicht auch einfach nur ein CHAR Array? Ich mein, so wie in C/C++? Wenn ja, dann kannst du den String doch zerlegen und einfach immer Zeichen für Zeichen zu vergleichen, anstelle des kompletten Strings...

Oh man, ich müsste in der Richtung auch mal wieder was machen... ;)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... ich stimme da Borsti zu.
Vielleicht gibt es in dem Zusammenhang ja auch eine Visu an der Anlage, möglicherweise ein PC, der dann über Script-Befehle ohne große Schwierigkeiten in der Lage wäre, diese Daten zu bewältigen ...

Gruß
LL
 

Danke, werd mich da mal einlesen.

Kannst auch einmal über eine VIPA-Speed7 nachdenken.

Der Kunde besteht auf eine Siemens SPS, und wie es halt so ist hat unser lieber Vertrieb da mal wieder mal etwas Vorschnell was verkauft..

In diesem Falle sollte man sich evtl. besser eine eigene Suchfunktion schreiben, die dann vorteilhafter Weise, bei Bedarf, die Suche auch über mehrere SPS-Zyklen verteilen kann, um die Zykluszeit der SPS nicht ganz in die Knie zu zwingen.

Selber schreiben? Ich??? Heul!!! :cry:
Wär schön wenn ich das könnte...

Na gut mal sehen wie ich das hinbekommen kann. Selber eine Suchfunktion schreiben ist definitiv nicht drin.
Also doch die Files splitten, aber wie stell ich das denn an, wenn alles in einem Rutsch vom CP kommt, dann muss ich es doch erst mal irgendwo ablegen, oder?

Werd dann heut mal ein wenig mit einem Versuchsaufbau tüfteln..

Was jetzt noch ein Problem darstellen könnte ist die Tastsache das ich nur <=1024 Byte empfangen kann. Wie siehts denn da mit einem Ethernet CP (CP343-1) aus?

Was die SPS betrifft denke ich da muss ich einfach ausprobieren was geht. Natürlich ist da auch noch ne ganze Menge E/A - Verarbeitung dabei.. :(


Gruß smartie
 
Hallo zusammen,

ich hab mich jetzt mal an ne SPS gehängt und ein bisschen getüftelt.

Was die Datenübertragung mit dem CP340 betrifft so trifft es zu das nur <=1024 Byte in einem Rutsch übertragen werden können. :(

Aber laut Handbuch des CP340 müsste es so sein das, bei aktivierter Datenflusskontrolle XON/XOFF oder RTS/CTS, wenn der Puffer des CP340 voll ist dieser die Übertragung anhalten kann bis "die Daten von der SPS abgeholt wurden" (Zitat Handbuch).
Die nicht gesendeten Daten müssten dann also zunächst im Ausgangspuffer der COM - Schnittstelle am PC bleiben.

So verstehe ich das zumindest. Ist aber leider nicht so...
Ich warte diesbezüglich noch auf einen Rückruf von Siemens. ;)

Desweiteren habe ich mich einwenig mit der Suchfuktion beschäftigt.

Ich denke ich werde mit der SFC22 CREAT_DB einen neuen DB anlegen wenn ich neue Daten empfange. Wenn ich dann eine neue Seriennummer einlese dann kopiere ich alle mit SFC22 angelegten DB´s der Reihe nach mit SFC20 BLKMOV in einen "Search_DB" (in dem ich mehrere Strings angelegt habe welche ich dann der Reihe nach durchsuche) und durchsuche nur diesen einen DB.

Jetzt bin ich am überlegen wie ich das Durchsuchen des einen DB am besten anstelle. In diesem DB will ich 8 Strings mit je 254 Zeichen anlegen.
Diese Strings müsste ich der Reihe nach durchsuchen und dann bei negativem Ergebniss zum nächsten String wechseln und wenn ein DB durchsucht ist wird der nächste DB in den "SearchDB" übertragen.

Wie könnte ich das wechseln von einem String zum nächsten realisieren. Ich denke da gerade an eine Schrittkette mit Merkern.
Bestimmt geht das aber auch etwas eleganter, oder?

Gruß smartie
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Machs dir nicht zu schwer. Ich würde etwas anders vorgehen. Also den DB mit den getrennten Daten zu füllen ist ok, du kannst auch Strings nehmen. Ich würde nicht unbedingt DB erzeugen, sondern mir einen Pool an DB anlegen. Oder alles in einem DB, mit festen Grenzen pro "Datensatz". Beim Durchsuchen des DB würde ich aber evtl. auf die Strings pfeifen, also keine Stringfunktion nutzen und einfach mit den Daten arbeiten, wie sie im DB liegen.

Vorschlag:
Du hast einen Suchstring, das ist der 18-stellige Code. Nimm das 1. DWord daraus. Iteriere in Byteschritten durch den gesamten DB, und vergleiche das "Such-DWord" mit dem an der aktuellen Position stehenden DWord. Geht prima mit indirekter Adressierung, siehe hier im Forum. Bei Gleichheit, auch die jeweils nächsten Bytes vergleichen (Unterprogramm), bis du die 18 Stellen hast. Ist z.Bsp. die 10. Stelle anders, raus aus dem Unterprogramm, weiter mit dem Iterieren. Bei 1600 Byte Datenlänge brauchst du so ca. 1600 Schritte zu einem vollständigen Vergleich. Das kann man bei Bedarf auch leicht über mehrere Zyklen verteilen, indem man pro Zyklus immer nur 200 Byte iterriert.

PS: Du mußt in diesem Fall die Daten eigentlich gar nicht als String ablegen und auftrennen, da du zum Suchen ja keine Stringfunktion nutzt. Am besten ginge das in SCL, wie schon gesagt, aber auch in AWL kein Problem.
 
Hi Ralle,

Iterieren?
Hilfe, was soll das denn bitte bedeuten?? :confused:

Also was du mir im Prinzip sagen willst verstehe ich schon, nur die Herangehensweise ist mir noch unklar.
Du meinst ich soll ein DW (zunächst das erste) aus meiner Seriennummer mit dem ersten Doppelwort aus meinem "VergleichsDB" vergleichen. Ist dieser Vergleich negativ soll ich das nächste Doppelwort aus dem "VergleichsDB" vergleichen.

Wie stell ich das denn an?

Indirekte Adressierung meinst du wäre das Stichwort. Werde da mal die Suchfunktion bemühen.

Wo liegt da der Vorteil zu den Stringfunktionen?

Das erzeugen der DB´s würde ich machen um nicht unnötig den Ladespeicher der CPU zu belasten. (CPU313C).

Einen Pool an DB´s (ich denke da so an 8 Stück) wäre natürlich einfacher.


Gruß smartie
 
Hallo,
ohne Ralle etwas vorwegnehmen zu wollen :
Iteration in deinem Fall bedeutet :
du vergleichst aus einem Datenblock (1. String) das erste Byte (oder Doppelwort). Ist dieser vergleich mit der Vorgabe passend, dann nimmst du das nächste usw. Hast du irgendwann keine Übereinstimmung mehr, dann brichst du ab, ohne auch den Rest weiter zu prüfen - ist dann ja sinnlos ...
Hierbei wäre ein ARRAY of BYTE (z.B.) einem String gegenüber von Vorteil.


@Ralle:
Du sollst nicht immer so mit Fremdwörtern imprägnieren ...;)
 
Zurück
Oben