当PHP触发时,Python无法访问串行端口



我是目前使用带有灯泡的RaspberryPi3在项目上工作的初学者,还有一个带有一些传感器的Arduino录制遥测。
我现在就卡住了,因为我的Python脚本将数据导入MySQL can 连接到/dev/dev/ttyacm0 时,当触发在外壳内并完美工作。当触发系统(),popen()或php中的exec()无法连接到串行端口。
我知道脚本正在运行/dev/ttyAMC0
这是我第一次使用PHP,因此可能确实是愚蠢的。目前,我已经引用了我当前问题的这些网站:
在PHP中致电Python
使用OnClick
执行PHP功能php-命令行
这是我的index.php的代码:

@charset "utf-8";
body {
	background-color: rgba(233,233,233,1.00);
	font-family: Gotham, "Helvetica Neue", Helvetica, Arial, sans-serif;
	font-size: x-large;
}
h1 {
	color: rgba(233,233,233,1.00);
	background-color: rgba(55,55,55,1.00);
	padding-top: 5px;
	padding-right: 5px;
	padding-bottom: 5px;
	padding-left: 5px;
}
.button {
	display: inline-block;
	padding-top: 30px;
	padding-right: 30px;
	padding-bottom: 30px;
	padding-left: 30px;
	background-color: rgba(55,55,55,1.00);
	color: rgba(233,233,233,1.00);
	text-align: center;
	margin-top: 10px;
	margin-right: 10px;
	margin-bottom: 10px;
	margin-left: 10px;
}
<!doctype html>
<?php
function start_recording(){
	system("./getdata.py");
}
function stop_recording(){
	popen("pkill python");
}
if (isset($_GET['start'])) {
	start_recording();
}
if (isset($_GET['stop'])) {
	stop_recording();
}
?>
<html>
	<head>
		<meta charset="utf-8">
		<title>Telemetry Computer</title>
		<link href="/assets/stylesheet.css" rel="stylesheet" type="text/css">
	</head>
	<body>
		<h1>Telemetry Box OS v1.0.0</h1>
		<h4>by Jake Johnson</h4>
			<a href="?start=true">
				<div class="button">Start Recording Data</div>
			</a><br>
			<a href="?stop=true">
				<div class="button">Kill Recording</div>
			</a><br>
			<a href="/data">
				<div class="button">View Data</div>
			</a><br>
			<a href="/manage">
				<div class="button">Data Managment</div>
			</a>
			</body>
</html>


这是我的python:

#!/usr/bin/python
import serial 
import MySQLdb
#establish connection to MySQL. You'll have to change this for your database.
dbConn = MySQLdb.connect(host="localhost", user="ayylmao", passwd="ayylmao", db="telemetry") or die ("could not connect to database")
#open a cursor to the database
device = '/dev/ttyACM0' 
try:
  print "Trying...",device 
  arduino = serial.Serial(device, 9600) 
except: 
  print "Failed to connect on",device     
while True:
  cursor = dbConn.cursor()
  try:
    print("---------  Inserting Data ---------") 
    data = arduino.readline()  #read the data from the arduino
    pieces = data.split("t")  #split the data by the tab
   #insert the data into the Database
    try:
      cursor.execute("INSERT INTO telemetryData (runTime,tempF,rpm,xforce,yforce,zforce) VALUES (%s,%s,%s,%s,%s,%s)", (pieces[0],pieces[1],pieces[2],pieces[3],pieces[4],pieces[5]))
      dbConn.commit() #commit the insert
      cursor.close()  #close the cursor
    except MySQLdb.IntegrityError:
      print "failed to insert data"
    finally:
      cursor.close()  #close just incase it failed
  except:
    print "Failed to get data from Arduino!"

简短答案:

问题可能是访问开发节点的权利。Web服务器在具有非常有限的权利的不同用户ID下运行,这是有充分理由的。另外,您不仅可以chmod 777 /dev/ttyACM0,因为每次重新启动系统时,都会重置它(严重,不要这样做,因为设备节点上的exec bit可能是不安全的)。相反,您需要编写一个UDEV规则,该规则可能需要一些时间来弄清楚如何。

长答案:

Linux具有魔术组件UDEV,该组件可以从SYSFS上安装设备节点,可以从内核,DEVFS访问,用户空间文件系统可作为/dev访问。IE。udev将决定是否将设备安装到DEVF中,以及分配哪些访问权限

为了做出这些决定,UDEV提供了一组以/lib/udev/rules.d/中的配置文件编写的规则(又称UDEV规则)(可能因分发而异)。这是影响Ubuntu上串行设备的规则列表:

/lib/udev/rules.d/50-udev-default.rules
/lib/udev/rules.d/60-persistent-serial.rules
/lib/udev/rules.d/77-mm-usb-serial-adapters-greylist.rules

规则以增加的顺序处理,因此50将具有优先权。您还可以在/etc/udev/rules.d/下添加自定义规则,可能从90 开始开始是一个好主意。

最后,答案:创建一个名为(例如)/etc/udev/rules.d/90-my-serial-dev-accessfix的文件。它应该包含类似的东西:

ACTION=="remove", GOTO="accessfix_end"
SUBSYSTEM=="tty", KERNEL=="ttyACM[0-9]*", GROUP="tty", MODE="0666"
LABEL="accessfix_end"

我现在无需进行测试,因此此配置中可能会出现一个或两个错误。但是,绝对值得阅读有关UDEV规则的修复。

最新更新