Gewichtswert einer Waage mit der CP-340 auslesen.

Tigerkroete

Level-1
Beiträge
245
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute,
ich hatte die Frage schon vor ca. 2 Monaten mal gestellt, es haben auch ein paar Leute geantwortet, doch ich komme leider bisher nicht zurecht.

Ich rüste eine Anlage auf S7 um, dort befindet sich eine kleine Waage, die den am Display angezeigten Gewichtswert an die SPS schickt. Leider kann ich in diese SPS nicht reingucken. Ich habe zum Glück durch den Hersteller Unterlagen zu fast dieser Waage gefunden. Es ist zwar ein anderer Typ, aber das Übertragungsprotokoll soll identisch sein. Man findet es auf den Seiten 25 und 26 im folgenden PDF-File.

http://www.sps-forum.de/attachment.php?attachmentid=814&d=1150109959

Für jemanden, der damit schon zu tun hatte, ist die Sache bestimmt sofort klar, aber ich blicke da leider nicht richtig durch.
Meine erste Frage wäre, falls man es aus den Unterlagen erkennen kann, ob die Waage die ganze Zeit sendet und ich demnach nur den FB_2 benötige um die Daten zu empfangen oder ob ich durch eine Sendesequenz die Waage erst dazu animieren muss, etwas zu senden?

Dann weiß ich nicht genau, wie ich was anlegen und ansprechen muss.
Z.B., wenn ich nun "nur" die Daten empfangen müsste, würde ich den FB2 und seinen Instanzbaustein anlegen. Wo werden dann die Werte hingeschrieben? Muss ich mir noch einen Baustein anlegen?

Ich habe mich wirklich schon einige Stunden mit den Unterlagen auseinandergesetzt, aber ich könnte wirklich ein paar Tipps in die richtige Richtung gebrauchen.

Vielen Dank,
Tigerkroete
 
Vielleicht so:

CP sendet Kommando P0, Waage antwortet einmalig mit dem aktuellen Wert.

Oder:

CP sendet Kommando P2, Waage sendet ab sofort selbstständig, wenn sich der Messwert ändert.

Such Dir was aus, es gibt da ja noch mehr Kommandos; ich würde die erste Variante wählen. Wie man allerdings den CP programmiert wissen andere sicherlich besser als ich...
 
Wie ich das so sehe, brauchst Du einen Wandlerbaustin der die Werte welche gesendet und empfangen werden in/von ASCII von/in die S7 Werte wandelt. Dabei ist beim Empfang CR (war das nicht 12hex?) eine wichtige Information. CR schliesst den Empfang ab.
 
Also, was ich bis jetzt verstehe ist, dass ich den FB2 (empfangen der Daten) und den FB3 (senden der Daten) brauche. Zu beiden lege ich die Instanz-DBs an und auch noch jeweils einen extra DB wo die empfangen und gesendeten Daten reingeschrieben werden.
Nur wie stelle ich mir dass nun vor? Muss ich z.B. im DB-Senden einen String von 2 anlegen und dort P0 reinschreiben?
Und wie ist es mit dem Rest?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Falls die SPS vorgibt wann die Daten gesendet werden sollen dann schickt sie einen String "PO[CR]". Empfangen wird dann ein String [ASCII Zeichen wie beschrieben [CR]. Wie das aussieht hat der String der empfangen wird auch eine Konstante Länge.
Halt da fällt mir doch noh ein CR = 0Dh = 13 dezimal.
 
Zuletzt bearbeitet:
Also es werden ja 20 Zeichen a 7-Bit-ASCII empfangen. Wie muss ich da denn meinen Empfangsspeicher anlegen?

Und auch zum senden, ich verstehe das immer noch nicht, wie ich nun "genau" das P0 anlegen und senden soll.

Sorry, aber ich kriegs nicht in meinen Schädel.
 
Ein 7-Bit ASCII Zeichen belegt ein Wort. Weil Du das so an der CP so eingestellt hast.
Beim Senden würde ich das so machen:
L W#16#4F //O
T DBW 0
L W#16#44 //D
T DBW 2
L W#16#D //CR
T DBW 4
und das wegschicken.
Meinst Du das geht nicht?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich würde einen Sende/Empfangs DB machen in dem die aktuelle Anfrage an die Waage und die Antwort steht.Jeweils 30 Byte lang als Char deklariert.
Da du ja an die Waage verschiedene "Anfragen" senden kannst würde ich die auch in einem DB als Array of Char ablegen.
Je nach Aktion was du von der Waage wissen willst schiebst du per Blockmove dein Array in den Sende DB oder das Sende-Array.

Wenn das mal klappt kannst dir gedanken machen wie du den Empfang weiter verarbeitest.

Gruss Zefix

bin erst ab Montag wieder Online....
 
Guten Morgen Leute.
Sorry, dass ich jetzt erst antworte. Ich hatte Freitagmittag Feierabend und war weg über´s WE.
Jedenfalls habe ich am Freitag noch mit Hyperterminal was wichtiges rausfinden können:
Die Waage ist offensichtlich so eingestellt, dass ich alle paar Sekunden den aktuellen Wert gesendet bekomme, ohne dass ich anfragen muss. Ich kannte Hyperterminal vorher garnicht *schäm*, bin aber begeistert. Ich habe bei den Einstellungen von wegen Parität und Baudrate usw. so lange rumgespielt, bis mein Gewichtswert erschien. Ich habe also gerade Parität, Baudrate 4800, 7 Datenbits und das Stopbit.
Jetzt muss ich mir also "nur" überlegen, wie ich die ganze Sache einlese.
Ich hatte erst gedacht, dass ich für jedes übertragene Zeichen ein "Char" nehme, aber die sind ja 2 MB groß. Das Problem ist ja, dass ich beim Aufruf von FB_2 (Daten empfangen) einen Datenanfangspunkt und die Datenlänge angebe, wohin geschrieben werden soll. Dann wäre doch meine Befürchtung richtig, dass ich die einzelnen, übertragenen Zeichen garnicht in jeweils einem "char" speichern kann?
Ich denke ich muss es irgendwie mit nem String machen und mir anschließend manuell meine Werte rausprokeln. Das dumme ist auch, dass der Dezimalpunkt immer an einer anderen Stelle stehen könnte.
Es gibt ja die Funktion "String nach Int" oder so ähnlich. Stört sich diese Funktion an dem Dezimalpunkt oder interpretiert sie ihn richtig mit?

Ich melde mich wieder, sobald ich mehr weiß und bin auch weiterhin für gute Tipps sehr dankbar!
 
Hi,
wenn die Waage eh schon von allein sendet hast eh schon die halbe Miete:)

Leg dir einen Empfangsbereich eines Array mit 50 Chars an (1 Char = 1 Byte) und gebe diesen Bereich an deinem FB2 an.

Über die Auswertung kannst dir später gedanken machen..

Gruss Zefix
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Zefix.
Ich komme grad von der Anlage, leider klappt es noch nicht. Ich habe jetzt erst Deinen Post gelesen.
Ich hatte es auch gerade mit "char" versucht, da ich festgestellt hatte, dass ein "char" ja doch nur ein Byte belegt. Also hatte ich mit 20 Bytes vom Typ Char angelegt, nicht als Array. Eigentlich wollte ich einen String nehmen, aber dort kann man den Aktualwert nicht beobachten.
Jedenfalls konnte ich nur im ersten Character ein Zeichen sehen. Es ging sehr schnell, aber es schien so, also würden alle Daten nacheinander nur in den ersten Charakter geschrieben. Es überschrieb sich also immer. Außerdem geschah überhaupt nur etwas, wenn ich in der Parametrierung die Enderkennung des Empfangstelegramms auf "Nach Ablauf der Zeichenverzugszeit" eingestellt hatte. Natürlich dachte ich zunächst, dass mein FB-Aufruf falsch sei und ich die Datenlänge falsch angegeben hätte, aber ich finde keinen Fehler.

Code:
      L     20
      T     "DB_Wiegeeinheit".DW_Laenge_Daten
 
      CALL  "P_RCV" , "Waage (ausl)" //Aufruf von FB2+Instanzbaustein
       EN_R  :=TRUE                       
       R     :="ZM_Keine_Restmenge"
       LADDR :=368                        //Baugruppenadresse als INT
       DB_NO :=14                         //DB in dem meine Chars liegen
       DBB_NO:=0                          //Anfangsbyte
       NDR   :=M300.1
       ERROR :=M300.3
       LEN   :="DB_Wiegeeinheit".DW_Laenge_Daten  //Länge in Bytes
       STATUS:=MW310

Nun zu Deinem Vorschlag. Warum gerade 50 chars? Einfach nur so, um sicher zu gehen? Und wie kann ich dann die Werte in diesem Array am besten beobachten?

Danke und viele Grüße,
Tigerkroete
 
O.K., ich hab´s geschafft. Ich hatte die Zeichenverzugszeit zu kurz eingestellt.
Also, ich haben nun 20 Character in denen sich mein Wert befindet. Das Komma bleibt zum Glück doch immer an der gleichen Stelle.
Ich will nun mal schauen, wie ich die wichtigen Dinge als Integerwert in eine Int-Variable kriege.
Ich werd´s bestimmt irgendwie nach ner Zeit und Hilfe durchforsten hinkriegen. Aber falls es jemand so ausm Stehgreif weiß, wie ich es am besten machen sollte, dann wäre ich für eine Antwort sehr dankbar.

Viele Grüße und Danke,
Tigerkroete
 
Hi,
na Super geht doch :)

Wenn dir INT reicht isses nicht tragisch.
Du bekommst die Werte als ASCII, am besten suchst mal im Netz nach einer Tabelle. Kann man immer mal brauchen ;)

Von der ASCII Zahl eines deiner Bytes nur 48 abziehen und du hast den Wert dieses einen Zeichens.
Beispiel:
ASCII 0 entspricht 48 Dez.
ASCII 1 entspricht 49 Dez.
ASCII 2 entspricht 50 Dez. usw.

Um nun mehrere Stellen wieder zu einem Wert zusammen zu fassen
multipliziere ich je nach Stelle mit 10,100, oder 1000 usw.
und addiere dann die Werte miteinander. Fertig...

Viel Spass

Zefix
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zahl minus 48
auf Lokalbyte
Zahl minus 48
auf Lokalbyte
...usw
BCD zu INT Wandlung - vor dem Komma
itd
dtr
und auf Local-real
bcd zu INT nach dem Komma
itd
dtr
/100 (oder ... je nach dem wo das Komma ist)
und auf Local-real
beide Realzahlen addieren
fertig
 
Tschuldigung habe Scheisse geschrieben...

Also BCD belegt ja pro Ziffer 4 Bit
Höchste Ziffer LB0
LW 0 = LB0_LB1

Somit muss die Wandlung von BCD zu INT so lauten:
L 0
T LW0 //erst mal alles löschen .....

L hoechste Ziffer, die Hunderte
T LB 0 //und ablegen

L jetzt die Zehner-BCD-Ziffer laden
SLW 4 // und hoch schieben
L Einer-BCD
OW //und zusammenbauen
T LB 1

L LW 0
BTI //jetzt kann das Wort gewandelt werden
...und jetzt steht im ACCU1 der Wert in INT (Wertebereich von 0...999)
ITD //in 32 - bit wandel
DTR // real...
... durch 1000 = hintern Komma, oder falls nur 2 Kommastellen, dann LB0=0
und durch 100
... und so wies iss bleibts vorm Komma
... und dann plus
 
Vielen Dank Leute, ich hab´s hinbekommen.

Ich habe den Character in dem das ASCII zeichen steht geladen, die 48 abgezogen und mit ITD und DTR in eine Realzahl gewandelt.
Dann je nach Stelle vor oder nach dem Komma mit z.B. 100 dividiert bzw. multipliziert und alle Realwerte addiert, fertig.

Vielen, vielen Dank, für die tollen Hinweise.
 
Zurück
Oben