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
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.
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.
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....
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
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).
Lass doch anstelle des uC mal einen anderen PC Gegenstelle spielen und schau was PHP den tatsächlich sendet.
Php sendet definitiv das, was es soll (Einen String "?log"), sonst würde der Mikrocontroller nicht reagieren und seine Messwerte ausspucken :)
Bist du den sicher das PHP 'nichts' liest oder wird das Skript einfach abgebrochen weil die maximale Skriptlaufzeit überschritten ist?
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.
Na dann zeig doch einfach mal deine Ausleseroutine...
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 | ?>
|
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.
http://www.phpmag.de/itr/online_artikel/psecom,id,470,nodeid,62,_language,de.html http://www.php.net/manual/en/function.dio-tcsetattr.php Die Ansätze ähneln sich in etwa...
@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.
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?
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.