Per PHP COM Schnittstelle ansprechen

#2222954
Lesenswert?

Hallo

Vielleich hat jemand von euch eine Idee oder Hinweis.

Problembeschreibung: Soll über COM2 (USB/UART) Daten aus MC Board 
lesen/schreiben. Über Terminal klappt es wunderbar, über PHP gibts ein 
Problem.

1
<?php
2
$fp=`mode com2: BAUD=9600 PARITY=N data=8 stop=1 DTR=off  RTS=off`; 
3
echo $fp; 
4
if (!$fp = fopen ("com2:", "w+")) 
5
{ 
6
echo "<br>";
7
echo ' Anschluss konnte nicht geoeffnet werden!!!'; 
8
} 
9
?>

Liefert mir "COM2 ist momentan nicht verfügbar" und
Warning: fopen(com2:) [function.fopen]: failed to open stream: 
Permission denied

Danke für eine Hinweis in voraus.
Gast #2222955
Lesenswert?

Helmut Kn schrieb:
> Permission denied
was wird da wohl das Problem sein?

Ich finde  es eine blöde idee aus php auf die com schnittstelle 
zuzugreifen, weil php durch mehre Benutzer gleichzeigt aufgerufen werden 
kann. Die schnittstelle kann aber immer nur von einem Prozess verwendet 
werden.
Sotwas macht man über einen Serverprozess der die zugriffe regelt.
Gast #2222965
Lesenswert?

Helmut Kn schrieb:
> Zugriff verweigert-Meldungen vom Server...mir ist nicht klar wo ich zum
> Suchen anfangen soll.
der apache/php user  hat keine rechte auf com2

> Peter II:
> Serverprozess der die zugriffe regelt...wie genau?
man man für sotwas ein Prozess (ein eingene Programm z.b. mit 
Perl/C/sonstetwas) der die Com-Schnittstelle öffnet und dort mit dem MC 
Board redet. dann kannst du von php z.b. per namespipe auf den Prozess 
zugreifen. (ja das ist am ende etwas komplizierter aber technisch 
besser)
Gast #2222993
Lesenswert?

Helmut Kn schrieb:
> Wo/Wie müsste ich Rechte im Apache einstellen.
dort überhaupt nicht.

Geht es eigentlich um Linux oder Windows?

Linux:
du musst dir die rechte von /dev/ttyS0 (oder wie auch immer es bei dir 
heist) ansehen und dann eventuell den apache user in die passende gruppe 
eintragen.

Windows:
da müssten die Recht eigentlich immer stimmem, weil jeder nutzer darauf 
zugreifen kann.

Bist du eigentlich sicher mit

 fopen ("com2:", "w+")) ?

denn unter windows kenn ich das nur ohne den ":" und unter linux sollte 
es doch dev... sein.
#2223143
Lesenswert?

Langsam komme ich der Sache näher. Der Hinweis mit com2: war gut.

Die COM unter Windows - wird schon mal angesprochen.
1
<?php
2
/**
3
* EIN/AUSGABE ueber COM
4
*
5
* Einfache Ein/Ausgabe ueber COM Schnittstelle
6
*
7
* @V0.1      2011.06.13 Schnittstelle angesprochen
8
*/
9

10

11
/**
12
* Set serial port parameters. Laut Doku: 9600 8-N-1
13
* Baud rate: 9600
14
* Parity (das "N" in "8-N-1") - Datenblock auf korrekten Inhalt zu überprüfen
15
* data - Character length (die "8" in "8-N-1")
16
* Stop bits (die  "1" in "8-N-1") 
17
* DTR - Data Terminal Ready 
18
* RTS - Request to Send [Sendeanforderung]
19
*/
20
$fp=`mode com2 BAUD=9600 PARITY=N data=8 stop=1 DTR=off  RTS=off`; 
21

22
echo $fp; 
23

24
if (!$fp = fopen ("com2", "r+")) 
25
{ 
26
echo "<br>";
27
echo ' Anschluss konnte nicht geoeffnet werden!!!'; 
28
} 
29
 
30
while (!feof($fp))
31
{
32
$line=fgets($fp, 512);
33
echo $line."<br/>";
34
}
35
fclose($fp);
36

37

38
?>

Ich suche eine besser Lösung zum Datenlesen - Die Schleife habe ich 
übernommen nur fehlt das Verständnis für 512.

Eine Idee.....?
Gast #2223186
Lesenswert?

> $line=fgets($fp, 512);
[..]
> nur fehlt das Verständnis für 512

Das kannst Du im Datenplatt^W^Hn der Doku finden. Evtl. wär auch 
stream_get_line() (ebenfalls in der Doku dokumentiert) was für Dich.

HTH
#2223397
Lesenswert?

Bin ein Stück weiter

Habe auf MC Board ein kleiner File gelade. Aufgabe eingehende Zeichen 
zurückzuschicken. Klappt über Terminal perfekt.

Leider bekomme ich über PHP kein Ergebnis:

OUTPUT:
Status von Ger„t COM2: ----------------------

Baudrate: 9600 Parit„t: None Datenbits: 8 Stoppbits: 1 Zeitlimit: OFF 
XON/XOFF: OFF CTS-Handshaking: OFF DSR-Handshaking: OFF DSR-Prfung: OFF 
DTR-Signal: OFF RTS-Signal: OFF

Status von Ger„t COM2: ---------------------- Baudrate: 9600 Parit„t: 
None Datenbits: 8 Stoppbits: 1 Zeitlimit: OFF XON/XOFF: OFF 
CTS-Handshaking: OFF DSR-Handshaking: OFF DSR-Prfung: OFF DTR-Signal: 
OFF RTS-Signal: OFF

Ergebnis:

Leider leeres Ergebnis

1
<?php
2
/**
3
* EIN/AUSGABE ueber COM
4
*
5
* Einfache Ein/Ausgabe ueber COM Schnittstelle unter Windows
6
*
7
* @V0.1      2011.06.13 Schnittstelle angesprochen
8
*/
9

10

11
/**
12
* Set serial port parameters. Laut Doku: 9600 8-N-1
13
* Baud rate: 9600
14
* Parity (das "N" in "8-N-1") - Datenblock auf korrekten Inhalt zu überprüfen
15
* data - Character length (die "8" in "8-N-1")
16
* Stop bits (die  "1" in "8-N-1") 
17
* DTR - Data Terminal Ready 
18
* RTS - Request to Send [Sendeanforderung]
19
*/
20
$fp=`mode com2 BAUD=9600 PARITY=N data=8 stop=1 DTR=off  RTS=off`; 
21
$fp2=`mode com2 BAUD=9600 PARITY=N data=8 stop=1 DTR=off  RTS=off`; 
22

23
echo $fp; 
24
echo $fp2;
25

26
 
27
function senden($comport,$zeichen)
28
{
29
  $fp = fopen ("$comport", "w+");
30
  if (!$fp){
31
     echo "Port zum Schreiben nicht geöffnet!";
32
     }
33
     else {
34
     fputs ($fp, $zeichen);
35
     fclose ($fp);
36
     }
37
}
38

39
function lesen($comport2,$sekunden)
40
{
41
  $buffer = "";
42
  $fp2 = fopen ("$comport2", "r+");
43
  if (!$fp2){
44
   echo "Port zum lesen nicht geöffnet";
45
   }
46
   else{
47
     sleep($sekunden);
48
     $buffer .= fgets($fp2, 4096);
49
   }
50
   return $buffer;
51
   fclose ($fp2);
52
}
53
 
54
senden("COM2","X"); // den Text X senden
55
$lese = lesen("COM2","2"); // 2 Sekunden lang Daten von COM2
56
echo "Ergebnis:".$lese;
57
 
58
?>


Hat jemand eine Idee?
Gast #2223504
Lesenswert?

So ausm Bauch raus würd ich sagen nimm nur ∗einen∗ Stream (das was fopen 
zurückliefert). Gut möglich dass beim zweite Öffnen (in lesen()) schon 
alles vorbei ist. Zum Testen also sowas wie
[pseudocode]
1
fp = fopen(..);
2
fputs(fp, ..);
3
echo fgets(fp, ..);
4
fclose(fp);
[/pseudocode]

Fehlerbehandlung natürlich nicht unterschlagen.

HTH
#2224289
Lesenswert?

Danke für den Hinweis.


Habe jetzt alles in einen

* oCOM (OOP) sauber verpackt
* mit einen Errorlogger versehen
* ein HTML Formular zum einfachen Testen angehängt


Senden klappt perfekt / Empfang hängt sich PHP auf (Endlosschleife)


Dank für jeden Hinweis


1
<?php
2
/**
3
* EIN/AUSGABE ueber COM
4
*
5
* Einfache Ein/Ausgabe ueber COM Schnittstelle unter Windows
6
*
7
* @V0.1 2011.06.12 Schnittstelle angesprochen
8
* @V0.2 2011.06.13 Lesen, Schreiben , OOP, Error
9
* @V0.3 2011.06.14 HTML Ein/Ausgabe
10
*/
11

12

13
/**
14
* Error Message Stack
15
*/
16
class errorMsg {
17
 static private $aMsg = array();
18
 static public function setError($p_sMsg = null) {self::$aMsg[] = $p_sMsg;}
19
 static public function getError() {return self::$aMsg;} 
20
 static public function isError() {return count(self::$aMsg) ? true : false;}  
21
}
22

23

24

25
/**
26
* I/O uber Schnittstelle
27
*/
28
class oCOM{ 
29

30

31
/**
32
* Konstruktor
33
*
34
* Set serial port parameters. Laut Doku: 9600 8-N-1
35
* Baud rate: 9600
36
* Parity (das "N" in "8-N-1") - Datenblock auf korrekten Inhalt zu überprüfen
37
* data - Character length (die "8" in "8-N-1")
38
* Stop bits (die  "1" in "8-N-1") 
39
* DTR - Data Terminal Ready 
40
* RTS - Request to Send [Sendeanforderung]
41
*
42
*/
43
 public function __construct()   {
44
 
45
$fp1=`mode com2 BAUD=9600 PARITY=N data=8 stop=1 DTR=off  RTS=off`; 
46
$fp2=`mode com2 BAUD=9600 PARITY=N data=8 stop=1 DTR=off  RTS=off`; 
47
errorMsg::setError($fp1);
48
errorMsg::setError($fp2);
49
}
50

51

52
/**
53
* Klasse wird zerstört
54
*
55
*/
56
 public function __destruct() {
57
 }
58

59

60
/**
61
* Senden der Daten ueber UART
62
*/
63
public function send($comport,$zeichen) {
64
  $this->fp1 = fopen ("$comport", "w+");
65
  if (!$this->fp1){
66
   errorMsg::setError("Port zum Schreiben nicht geöffnet!");  
67
     }
68
     else {
69
     fputs ($this->fp1, $zeichen);
70
     fclose ($this->fp1);
71
     }
72
}
73

74

75
/**
76
* Lesen der Daten ueber UART
77
*/
78
public function read($comport2,$sekunde) {
79
  $buffer = "";
80
  $this->fp2 = fopen ("$comport2", "r+");
81
  if (!$this->fp2){
82
   errorMsg::setError("Port zum lesen nicht geöffnet");  
83
   }
84
   else{
85
     sleep($sekunden);
86
     $buffer .= fgets($this->fp2, 4096);echo $buffer;echo "x";
87
   }
88
   return $buffer;
89
   fclose ($this->fp2);
90
}
91
} //END io
92

93

94
/**
95
* 
96
*/
97

98
$com="COM2";
99
$input="1";
100

101
if(isset($_GET["com"]))$com=$_GET["com"];
102
if(isset($_GET["input"]))$input=$_GET["input"];
103

104
$oCOM = new oCOM;
105
$oCOM->send($com,$input);                   // den Ziffer 2 senden
106
$lese = $oCOM->read($com,"3");       // 2 Sekunden lang Daten von COM2 abfragen
107

108
?>
109

110

111

112

113

114

115

116

117
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
118
     "http://www.w3.org/TR/html4/loose.dtd">
119
<html>
120
<head>
121
<title>IO Test</title>
122
</head>
123
<body>
124
<h3>Senden auf COM</h3>
125
<p>
126

127
  <form action="com_schnittstelle.php" method="get" enctype="MIME-Typ">
128
     <label>Schnittstelle: </label>
129
    <input name="com"type="text" value="COM2">
130
    <label>Sende Ziffer 0- 9: </label>
131
    <input name="input"type="text" value="1">
132
  <input type="submit" value="senden">
133
  </form>
134

135

136
<h3>Empfangen von COM</h3>
137
<code style="white-space:pre-wrap !important;">
138
<?php
139
echo "Ergebnis:".$lese;
140
?>
141
</code>
142
<h3>Error/Log</h3>
143
<p>
144
<?php
145
/**
146
* wenn Fehlermeldungen existieren, diese ausgeben
147
*/
148
if (errorMsg::isError()) {
149
 var_dump(errorMsg::getError());
150
}
151
?>
152
</p>
153
</body>
154
</html>
#2224648
Lesenswert?

Habe jetzt eine minimal Version geschrieben.
1
<?php
2

3
$fp=`mode com2 BAUD=9600 PARITY=N data=8 stop=1 DTR=off  RTS=off`; 
4

5
$comport="COM2";
6
$zeichen="3";
7

8
$fp = fopen ("$comport", "w+");
9
if (!$fp){
10
     echo "Port zum Schreiben nicht geöffnet!";
11
     }
12
     else {
13
     fputs ($fp, $zeichen);
14
     fclose ($fp);
15
}
16

17

18

19

20
$fp2=`mode com2 BAUD=9600 PARITY=N data=8 stop=1 DTR=off  RTS=off`; 
21

22
$buffer = "";
23
$sekunden=1;
24
$fp2 = fopen ("$comport", "r+");
25
if (!$fp2){
26
   echo "Port zum lesen nicht geöffnet";
27
   }
28
   else{
29
     sleep($sekunden);
30
     $buffer .= fgets($fp2, 4096);
31
}
32
fclose ($fp2);
33

34
echo "Ergebnis:".$buffer;
35
 
36
?>



Funktioniert bei jeden zweiten Start.....seltsam und unstabil.
#2225700
Lesenswert?

Erstmal vielen Dank für eure Unterstützung.

Konklusion:
Per PHP COM Schnittstelle ansprechen kann man mit JAEIN beantworten.

Anscheinend ist PHP nicht geeignet, stabile Ergebnisse zu liefern. 
Senden klappt einwandfrei, der Empfang ist ein Problem.

In der Demo klappt er nicht.
1
<?php
2
/**
3
* EIN/AUSGABE ueber COM
4
*
5
* Einfache Ein/Ausgabe ueber COM Schnittstelle unter Windows
6
*
7
* @V0.1 2011.06.12 Schnittstelle angesprochen
8
* @V0.2 2011.06.13 Lesen, Schreiben , OOP, Error
9
* @V0.3 2011.06.14 HTML Ein/Ausgabe
10
*/
11

12

13
/**
14
* Error Message Stack
15
*/
16
class errorMsg {
17
 static private $aMsg = array();
18
 static public function setError($p_sMsg = null) {self::$aMsg[] = $p_sMsg;}
19
 static public function getError() {return self::$aMsg;} 
20
 static public function isError() {return count(self::$aMsg) ? true : false;}  
21
}
22

23

24

25
/**
26
* I/O uber Schnittstelle
27
*/
28
class oCOM{ 
29

30

31
/**
32
* Konstruktor
33
*
34
* Set serial port parameters. Laut Doku: 9600 8-N-1
35
* Baud rate: 9600
36
* Parity (das "N" in "8-N-1") - Datenblock auf korrekten Inhalt zu überprüfen
37
* data - Character length (die "8" in "8-N-1")
38
* Stop bits (die  "1" in "8-N-1") 
39
* DTR - Data Terminal Ready 
40
* RTS - Request to Send [Sendeanforderung]
41
*
42
*/
43
 public function __construct(){}
44
 public function __destruct(){}
45

46
 
47
/**
48
* Senden der Daten ueber UART
49
*/
50
public function send($comport,$zeichen) { 
51
  `mode com2: BAUD=9600 PARITY=N data=8 stop=1 xon=off`;
52
  $fp = fopen ("$comport", "w+");
53
  if (!$fp)
54
  {
55
  errorMsg::setError("Port zum Schreiben nicht geöffnet!");
56
  }
57
  else {
58
  fputs ($fp, $zeichen);
59
  fclose ($fp);
60
  }   
61
}
62

63
/**
64
* Lesen der Daten ueber UART
65
*/
66
public function read($comport2,$sekunde) {
67
  `mode com2: BAUD=9600 PARITY=N data=8 stop=1 xon=off`;
68
  $buffer = "";
69
  $fp2 = fopen ("$comport2", "r+");
70
  if (!$fp2)
71
  {
72
  echo "Port zum lesen nicht geöffnet";
73
  }
74
  else
75
  {
76
  sleep($sekunden);
77
  $buffer .= fgets($fp2, 4096);
78
  }
79
  return $buffer;
80
  fclose ($fp2);
81
}
82
  
83
  
84
} //END io
85

86

87
/**
88
*  MAIN
89
*/
90
$com="com2";
91
$input="1";
92
$lese = "kein Ergebnis";
93

94
if(isset($_GET["com"]))$com=$_GET["com"];
95
if(isset($_GET["input"]))$input=$_GET["input"];
96

97
$oCOM = new oCOM;
98
$oCOM->send("com2","9"); 
99
$lese = $oCOM->read("com2","2"); 
100
echo $lese;
101
?>
102

103

104

105

106

107

108

109

110
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
111
     "http://www.w3.org/TR/html4/loose.dtd">
112
<html>
113
<head>
114
<title>IO Test</title>
115
</head>
116
<body>
117
<h3>Senden auf COM</h3>
118
<p>
119

120
  <form action="com_schnittstelle.php" method="get" enctype="MIME-Typ">
121
     <label>Schnittstelle: </label>
122
    <input name="com"type="text" value="COM2">
123
    <label>Sende Ziffer 0- 9: </label>
124
    <input name="input"type="text" value="1">
125
  <input type="submit" value="senden">
126
  </form>
127

128

129
<h3>Empfangen von COM</h3>
130
<code style="white-space:pre-wrap !important;">
131
<?php
132
echo $lese;
133
?>
134
</code>
135
<h3>Error/Log</h3>
136
<p>
137
<?php
138
/**
139
* wenn Fehlermeldungen existieren, diese ausgeben
140
*/
141
if (errorMsg::isError()) {
142
 var_dump(errorMsg::getError());
143
}
144
?>
145
</p>
146
</body>
147
</html>


Hier eine Link wo es klappt (aber nicht immer)
Beitrag "RS232 mit PHP"

Nur Senden klappt
http://www.phpclasses.org/package/3679-PHP-Communicate-with-a-serial-port.html#download

Nicht uninteressant
http://www.communitymx.com/content/article.cfm?page=2&cid=8658A


Falls noch jemand noch eine Idee oder Anregung hat bitte mitteilen. 
Danke im voraus.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren