Forum: PC-Programmierung Com-Port mit PHP unter Win: Muss immer zuerst ein Terminalprogramm öffnen und schließen


von Chris (Gast)


Lesenswert?

Hallo,

ich lese und sende mit php über die serielle Schnittstelle unter Windows 
7. Das klappt auch, aber nur, wenn ich nach dem Hochfahren (oder nach 
dem Anstecken des USB-Seriellwandlers (FDDI)) hterm oder ein anderes 
Terminalprogramm starte, den Seriellport kurz öffne und wieder schließe.

Tue ich dies nicht, sendet das PHP-Skript zwar Daten raus, kann aber 
nichts vom Comport lesen und bricht nach rund 50 Sekunden ab (obwohl der 
Timeout ja 30 Sekunden beträgt).

Bevor das Skript startet, setze ich mit mode die entsprechenden 
Einstellungen. Ich habe auch verglichen, was das Terminalprogramm 
einstellt und den mode-Befehl entsprechend angepasst.

Woran kann das liegen?
Gibt es ein Programm, das einfach kurz einen Comport öffnet und wieder 
schließt, damit ich das Problem so umgehen kann?

Gruß,
chris

von Peter II (Gast)


Lesenswert?

Chris schrieb:
> Bevor das Skript startet, setze ich mit mode die entsprechenden
> Einstellungen. Ich habe auch verglichen, was das Terminalprogramm
> einstellt und den mode-Befehl entsprechend angepasst.
es kann eigentlich nur eine einstellung sein die du vergisst zu setzen.

Ich finde das Konzept aber sehr schlecht. Ein php-Script wird für jeden 
Abfrage neu ausgeführt, was ist wenn jetzt 2 Anfrangen gleichzeit 
reinkomen? Ein COM port kann man nur einmal öffnen.
Soetwas sollte man mit einer echten Webanwendung (ASP, JAVA) machen, 
dabei übernimmt ein Thread die steuerung der Schnittstelle und die 
webrequest arbeiten dann mit diesem Server teil.

von Chris (Gast)


Lesenswert?

Das ganze besteht auch aus 2 "Threads". Der eine wird mit dem 
Windows-Taskplaner ausgeführt, holt die Daten ab, prüft die 
Wertebereiche, String-Längen usw, schreibt in die DB und quittiert den 
Empfang, um den Datensatz von der Mikrocontroller-Platine zu löschen 
bzw. als "übertragen" zu markieren.

Auf der Platine gibt es nebenbei noch eine SD-Karte. Wenn der Puffer mit 
den Logdaten nicht schnell genug geholt wird (die Daten fallen rund um 
die Uhr alle 4 Minuten an und der PC läuft nicht durchgehend), dann wird 
auf die SD-Karte geschrieben. Der PC sieht beim Abruf nicht, ob es die 
Werte der SD-Karte sind oder die aus dem Ram-Puffer des Atmegas.

Als Benutzer greift man mit einem 2. PHP-Skript auf die DB zu und lässt 
sich die Werte anzeigen.

von Chris (Gast)


Lesenswert?

Zum Thema falsche Einstellungen:
Die Baud-Rate stimmt, denn wenn das PHP-Skript sendet, antwortet die 
Platine wie erwartet (LED blitzt kurz auf und laut Logic Analyzer kommt 
auch das erwartete zurück).

Nur empfängt php nix....

von Ingo W. (Gast)


Lesenswert?

Chris schrieb:

> Nur empfängt php nix....

Das klingt nach aktivierter HW-Flusskontrolle und nicht aktivierter 
CTS-Leitung.
Also am Besten, ersteres deaktivieren.
mfG ingo

von Chris (Gast)


Lesenswert?

Flusskontrolle sollte aus sein:
>mode com9
Baudrate: 57600
Parität: None
Datenbits: 8
Stoppbits: 1
Timeout: OFF
XON/XOFF: OFF
CTS-Handshaking: OFF
DSR-Handshaking: OFF
DSR-Prüfung: OFF
DTR-Signal: OFF
RTS-Signal: OFF

Die Pegel auf den ungenutzten Leitung sind auch alle definiert 
(gebrückt/rückgekoppelt).

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Lass doch anstelle des uC mal einen anderen PC Gegenstelle spielen und 
schau was PHP den tatsächlich sendet.

von Chris (Gast)


Lesenswert?

Php sendet definitiv das, was es soll (Einen String "?log"), sonst würde 
der Mikrocontroller nicht reagieren und seine Messwerte ausspucken :)

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Bist du den sicher das PHP 'nichts' liest oder wird das Skript einfach 
abgebrochen weil die maximale Skriptlaufzeit überschritten ist?

von Chris (Gast)


Lesenswert?

Die Antwort vom Mikrocontroller kommt sofort zurück. Ich habe auch 
testweise schon eine Sekunde Pause eingebaut um PHP genug Zeit zu geben, 
in die "Abrufschleife" zu kommen.

Wenn ich nach dem Hochfahren kurz mal mit dem Terminalprogramm den 
Seriellport öffne und schließe, funktioniert es anschließend ja auch.
Also muss durch das Terminalprogramm irgendwas passieren / umgestellt 
werden. Aber was?

Nebenbei: Mit einem Prolific (oder so...) USB-Adapter habe ich das 
gleiche Ergebnis.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Na dann zeig doch einfach mal deine Ausleseroutine...

von Chris (Gast)


Lesenswert?

1
<?php
2
3
   'mode com9: baud=57600 data=8 stop=1 parity=n xon=off rts=off dtr=off';
4
5
   $fp = fopen ("COM9", "wb+");
6
7
8
   
9
   if (!$fp) {
10
11
      echo "Fehler beim Öffnen des Ports";
12
13
      sleep(10);
14
15
      die;
16
17
   }
18
19
   
20
   //stream_set_blocking($fp, 1);
21
22
23
24
  $res = '';
25
26
  fputs ($fp, "log");
27
 //Anfrage senden
28
        
29
30
   //Auf Anfang warten:
31
32
   while ($res != '#') {
33
34
      $res = fgetc ($fp);
35
   
36
      //Hier gibt es nach 30 sec einen Timeout 
37
      //da nichts empfangen wird, es sei denn, 
38
      //man öffnet und schließt den Com-Port mit einem Terminalprogramm
39
      //nach dem Hochfahren des Rechners
40
   }
41
42
      
43
44
   //Anfang wurde erkannt:
45
46
   if ($res == '#') {
47
      //Mit fgetc einlesen bis Ende-Zeichen kommt
48
      //Prüfen, Auswerten, in die DB schreiben
49
   }
50
51
   fclose ($fp);
52
53
?>

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Und wo setzt du die Schnittstellenparameter? Dein Mode definiert einfach 
nur einen String den musst du dann noch irgendwem übergeben wenn mich 
nicht alles täuscht.

von *kopfkratz* (Gast)


Lesenswert?

Warum das Rad neu erfinen:

Beitrag "RS232 mit PHP"

von *kopfkratz* (Gast)


Lesenswert?


von Chris (Gast)


Lesenswert?

@läubi:
Ich dachte dass der Mode-Befehl dann ausgeführt wird, wobei ich das auch 
schon mit exec("mode...."); probiert habe. Ist aber für meine Versuche 
nicht von Bedeutung, da ich die Schnittstelle eh vor dem Aufruf der 
php-Datei in der Batch-Datei einrichte.

@kopfkratz: Die Beiträge kenne ich schon, bis auf die Lösung mit dem 
Seriell-Lan-Wandler. Dio habe ich nicht getestet da es unter Windows 
nicht implementiert ist.

Ich werde das ganze mal unter Linux testen.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Chris schrieb:
> Ich dachte dass der Mode-Befehl dann ausgeführt wird, wobei ich das auch
> schon mit exec("mode...."); probiert habe. Ist aber für meine Versuche
> nicht von Bedeutung, da ich die Schnittstelle eh vor dem Aufruf der
> php-Datei in der Batch-Datei einrichte.

Wie jetzt? natürlich ist das von Bedeutung. Du solltest auf jedenfall 
prüfen ob der Modeaufruf dauerhaft ist und ob eventuell Fehler 
zurückgeben werden.

Also wie ist den jetzt dein genaueres Setup?

von Chris (Gast)


Lesenswert?

Ok, dann schildere ich nochmal, was ich jetzt hier habe:

Bat-Datei:
1) mode-Aufruf wie oben angegeben
2) php.exe abruf.php mit dem obigen Quelltext.

Lasse ich den Mode-Aufruf weg, werden Daten an die Platine gesendet 
(grüne LED blinkt), aber die Platine sendet keine Antwort (rote LED 
blinkt nicht).
D.h. die Platine hat die Anfrage nicht verstanden, weil die Baudrate 
nicht stimmte.

Mit dem Mode-Aufruf werden Daten gesendet (grün blinkt auf) und die 
Platine sendet die Messwerte zurück (rot blinkt). Also stimmt die 
Baudrate nun.
Php hängt sich in der Abrufschleife auf bzw. empfängt nichts.


Starte ich ein Terminalprogramm und öffne und schließe den Port (oder 
beende das Terminalprogramm), so ist es egal, ob ich danach den 
Mode-Befehl ausführe oder nicht, die Einstellungen stimmen dann ja 
schon.
Unterschied: Php hängt sich nicht auf, sondern liest die Daten ein.

Wenn ich nach Aufruf des Terminalprogramms mode mit z.B. einer falschen 
Baudrate ausführe, reagiert die Platine nicht mehr. Wenn ich danach 
nochmal mode mit den richtigen Parametern aufrufe, funktioniert es 
wieder.

von Michael M. (mikmik)


Lesenswert?

Hallo,
will hier keine Leichen schänden, aber ich hab exakt das selbe Problem.
WInXP, PHP 5.3. Egal ob ichs mit dio oder "simpel" mach, dass selbe. 
Auch die mode einstellung überprüf ich vor dem start nochmal in der 
console, tut sich aber nix. erst wenn ich einmal das comport mit hterm 
aufgemacht hab, klappts. jetzt schreib ich grad das proggi in delphi, da 
gehts gleich. taugt mir aber nicht so.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.