X_ON / X_OFF-Protokoll abfragen

Hallo,

ich will ein Messgerät ansteuern um verschiedene Messungen automatisch nacheinander durchzuführen…

Die Baudrate ist fest auf 9600 eingestellt. Das verwendete Protokoll ist stets No parity, 8 Databits, 1 Stopbit (N,8,1)

Da nur zwei Leitungen zur Verfuegung stehen, wird das X_ON / X_OFF-Protokoll verwendet.

Da die Verarbeitung der Schnittstelleninformation ueber Interruptsteuerung erfolgt, ist das Pruefgeraet immer empfangsbereit.
Nach jedem CR wird ein XOFF gesendet.
Dann wird der Befehl ausgewertet und beantwortet. Antworten, die Strings oder Tabellen beinhalten, koennen durch Cntr-C abgebrochen werden. Wenn ein Befehl verarbeitet ist wird wieder XON gesendet. Das kann je nach Befehl bis zu mehreren Sekunden dauern. Ein neuer Befehl darf erst nach
XON gesendet werden.

Derzeit steuere ich das Gerät über ComPort_SendText und empfange per com-port <–> cutchars <—> register variable (mit append)

Der IPS Com-Port steht auf com1, 9600 baud, 8 data bits, 1 stop, parity: none, Flowcontrol: Software.
Muss ich da was ändern? DTR und RTS aktivieren?

Wie kann ich vor dem nächsten Befehl auf XON abfragen?

Was ich bisher gemacht habe:


$id = 20934;
// Remote Modus einschalten
ComPort_SendText($id,"tas!ron".chr(13).chr(10));
IPS_Sleep(1200);
// Tastenstellung abfragen (nicht so wichtig)
ComPort_SendText($id,"tas?".chr(13).chr(10));
IPS_Sleep(1200);
// Hochspannungsprüfung mit 500 Volt  0,5s Rampe hoch 10s halten 0,5s Rampe runter
ComPort_SendText($id,"iso!h 50,5,10,5".chr(13).chr(10));
IPS_Sleep(1200);
// Hochspannungsprüfung starten
ComPort_SendText($id,"mes!uhv".chr(13).chr(10));
IPS_Sleep(18000);
// Werte auslesen
ComPort_SendText($id,"wer?".chr(13).chr(10));
IPS_Sleep(1200);
// Remote-Modus abschalten
ComPort_SendText($id,"tas!rof".chr(13).chr(10));
IPS_Sleep(1200);
 
$inbuf = Trim(GetValueString("Messgeraet"));
echo $inbuf."
";
echo "-----------";
 
 
 

ich würde mal sagen, Du mußt solange warten, bis XON bzw XOFF zurück kommt, passender weise über eine RegisterVariable. Diesen Event kannst Du auswerten und ein Flag (Variable setzen) ob Du senden kannst (XON) oder nicht(XOFF). Dieses Flag wird dann im Script abgefragt. Das Script muss so lange warten, bis die Variable gesetzt ist.
RTS/DTR haben keinen Sinn, weil sie lt. Definition „Flusssteuerung Software“ gar nicht abgefragt werden.

Tommi

Hallo,

wie sehe ich, wann XON zurück kommt ???

Also der Output den IPS bekommt sieht z.B. so aus:

.Yx
.Yx
TASTEx=01;IDS;R;-
.Yx
.Yx
Wertx=73 UHV +02.32kV;MN +00.42kV;MX +02.32kV;wc +00.28kV

.Yx

Hier die Zeichenfolge wenn ich es mit Hyperterm ansteuere. (Alles mit > davor ist ne Eingabe, danach kommt (mit unterschiedlicher Zeitverzögerung die Antwort)
>tas!ron
.Yx
>tas?
TASTEx=01;IDS;R;-

>iso!h 50,5,10,5

.Yx

>mes!uhv

.Yx
>wer?
Wertx=73 UHV +00.80kV;MN +00.79kV;MX +00.80kV;wc +00.52kV
>Messung=STOP


Die .Yx sind vermutlich die „Fertig-Meldungen“.

Folgendes habe ich versucht:


$id = 20934; // Der COM-Port direkt
ComPort_SendText($id,"tas!ron".chr(13).chr(10));
while (GetValueString("Messgeraet")<>".Yx") {echo "warten";} // Die Register-Variable heisst Messgeraet
$inbuf = SetValueString("Messgeraet",""); // Variable leeren

// und zum nächsten Schritt.


Leider macht IPS dann garnichts mehr, das Script läuft ewig und ich muss IPS killen…

Hallo Jürgen,

dein Script läuft sich in der while-schleife tot.

setz mal ein return; ein.

http://www.phpbox.de/php_befehle/while.php

Hier nochmal der ungefilterte Output:

Com-Code.png

Also wenn Messgeraet den Wert „.Yx“ hat, sollte das doch abbrechen. Und solange was anderes drin steht, sollte „warten“ ausgegeben werden, oder?

while (GetValueString(„Messgeraet“)<>".Yx") {echo „warten“;}

Ich habe auch != statt <> versucht…

Hallo juergen852,

XON und XOFF sind „nicht-darstellbare“ Zeichen. Da sie nun mal nicht darstellbar sind, werden sie bei der Textausgabe als „.“ (Punkt) angezeigt. Es hat folglich keinen Sinn nach einem Punkt zu suchen, der in wirklichkeit keiner ist.

Üblicherweise werden folgende ASCII-Codes für XON und XOFF verwendet:
XON: DC1 (0x11)
XOFF: DC3 (0x13)

In Deinem Screenshot mit der Hexadezimal-Darstellung sind diese Zeichen sichtbar (11 und 13). Im Cutchar-Modul kannst Du Zeichen auch als Hex-Wert eingeben.

Gruß
HJH

Hallo HJH, da hast Du natürlich sehr sehr recht… Denken hilft manchmal.

Was ich aber immer noch nicht verstehe: Eigentlich müsste durch die While-Schleife ja dauernd „Warten“ ausgegeben werden, wenn ich das Script manuell starte.

Im Ausgabefenster ist aber leider garnichs zu sehen. Nicht ein einziges Zeichen…

Getestet mit:
while (GetValueString(„Messgeraet“) != chr(11).chr(13)) {echo „warten“;}
while (GetValueString(„Messgeraet“) != chr(11)) {echo „warten“;}

Anbei noch die Screenshots

Hallo juergen852,

ich beziehe mich noch mal auf Deinen Screenshot: es wäre hilfreich zu wissen, welche Session Du dabei abgehört hast.

War es die mit IPS oder die mit Hyperterm?

Leider geht daraus auch nicht hervor, wer was gesendet hat.

Dein Skript kann so nicht funktionieren, denn der String wird wahrscheinlich niemals genau so aussehen wie Du ihn abfragst. Du müsstest zumindest den String erst nach der fraglichen Zeichenkette durchsuchen.

Aber ich fürchte, dass der Ansatz bereits unbrauchbar ist. Daher bitte ich Dich erst einmal die o.g. Fragen zu beantworten.

Gruß
HJH

Hallo HJH,

der Hex-Output entstand aus IPS. Ich habe dazu CutChars abgeschaltet und bei Recieve Data auf „Append“ geschaltet.
Danach das ganze per Copy-Paste in Ultraedit und damit angeschaut.

Im „Normalbetrieb“ ist es vermutlich besser, per CutChars die CR+LF raus zu filtern. Auch der Append muss dann natürlich dem ein Overwrite sein.

Die While-Schleife wartet dann, bis die Messung beendet ist und macht dann weiter.

Nachdem das bisher nicht wirklich wollte, habe ich mal folgendes versucht:


$inbuf = SetValueString("Messgeraet","aaa");
ComPort_SendText($id,"iso!h 50,5,10,5".chr(13).chr(10));
while (GetValueString("Messgeraet") =="aaa") {echo "";}
$inbuf = Trim(GetValueString("Messgeraet"));
echo $inbuf."
";

So funktioniert das ganze, wenngleich es nicht wirklich elegant aussieht… :):):):slight_smile:

Ich werde erst mal weiter testen.
Danke für Deine Hilfe !!!

Die Registervariable, wo die Daten ankommen kann man auch direkt Zeichen für Zeichen testen.
Also Zeichenkette in eine neue Variable kopieren , länge testen, wenn >0 Regvar löschen und anschliessend mit einer Schleife über die Länge alle Zeichen einzeln abklappern, bis das Zeichen da ist oder weiter warten, bis wieder was in der RegVar drin steht und das Gleiche von vorne beginnen.

Tommi