我可以在后台运行我的Python脚本,通过使用sudo crontab -e在启动时自动启动脚本来控制两个伺服器。我修改了脚本,所以我现在不断地将servos当前位置写入horz.txt和vert.txt文件并使用这些文件将步进器初始化到它们的原始位置,这样我就可以在断电后再次找到原点位置。使用sudo python mystepper6.py从黑色屏幕上的命令行手动启动脚本时,我添加的horz.txt和vert.txt代码可以正常运行该脚本,但它不会在启动时自动启动,也不会在启动时自动启动当我在命令行输入ps ax时它会显示为运行状态。我添加了一些额外的代码,只是为了在主程序启动之前摆动伺服器,并且伺服器在sudo crontab -e中按照编程自动摆动但是它只是停止并且不会继续找到原始位置。它似乎与新代码有关,但我不知道它可能是什么。我的sudo crontab -e行是@reboot(sleep2; python /home/pi/mystepper6.py)&。下面是mystepper6.py的脚本。
由于此帖中可用空间有限,下面的脚本缩短了以显示相关行。 sudo重新启动挂起,底部附近没有任何错误消息,它被评论并移动到原始位置' (它不会移动)。我能够在该点之前打印adjustv和adjusth整数,以便在该点为.txt文件中的变量分配一个值。当我从命令行手动运行mystepper6.py时,它运行得很好。
我花了太多时间来解决这个问题并购买了两本电子书无济于事。请帮忙。
import RPi.GPIO as gpio # import library RPi.GPIO gpio=use general purpose input output pin names
import time # import time library
PINSh = [27,10,18,23] # variable 'PINS' holds a list of gpio pin numbers
SEQAh = [(27,),(10,),(18,),(23,)]
PINSv = [4,17,22,24] # variable 'PINS' holds a list of gpio pin numbers
SEQAv = [(4,),(17,),(22,),(24,)]
DELAY = 0.01 # time between motor steps (too small of a number then the motor stalls)
alpha = 140 # horizontal full scale viewing angle in motor counts 128 counts = 360 degrees
beta = 30 # was 15 vertical full scale viewing angle in motor counts 128 counts = 360 degrees
gpio.setmode(gpio.BCM) # tells RPi.GPIO we want to use pin names (BCM is the mfg)
for pin in PINSh: # pin is a variable name assigned a new value each loop; PINS is a list
gpio.setup(pin, gpio.OUT) # this says we want to use 'pin' as an output
for pin in PINSv: # pin is a variable name assigned a new value each loop; PINS is a list
gpio.setup(pin, gpio.OUT)
def stepper(sequence, pins): # def says 'stepper' is the function name (like a variable), then parameters are inside ()
for step in sequence:
for pin in pins:
if pin in step:
gpio.output(pin, gpio.HIGH)
else:
gpio.output(pin, gpio.LOW)
webcam_horz_home = open("horz.txt", "a")
webcam_horz_home.close()
webcam_vert_home = open("vert.txt", "a")
webcam_vert_home.close()
# load last position prior to power down
webcam_horz_home = open("horz.txt", "r")
rows = webcam_horz_home.readlines();
for row in rows:
adjusth = int(row)
webcam_horz_home.close()
webcam_vert_home = open("vert.txt", "r")
rows = webcam_vert_home.readlines();
for row in rows:
adjustv = int(row)
webcam_vert_home.close()
counter = 0 # move to home position
while counter < adjustv:
stepper(SEQAv, PINSv)
counter = counter + 1
# CONTINUAL PAN AND TILT OPERATION (box pattern):
答案 0 :(得分:1)
我刚刚在运行Raspbian的Pi上进行了测试,结果很有效。
首先,我在主用户的主目录中创建了一个名为some_script.py的python脚本。 脚本内容:
import sys
import time
with open("/home/username/some_script.py.out", "w") as f:
f.write(str(time.time()) + " " + "some_script.py RAN!\n")
然后,在终端中,我在文件上设置允许执行的可执行位:
sudo chmod +x some_script.py
然后,在终端中,我输入了sudo crontab -e
并在root
用户的crontab底部添加了以下行:
@reboot sleep 2; /usr/bin/python /home/username/some_script.py
然后我重新启动,cd
转到/home/username/
并确认python已在重启时运行并写入文件:
cat some_script.py.out
1458062009.53 some_script.py RAN!
更新/解决方案
在确认OP能够成功复制上述步骤之后,我相当确信这不是源于不同* nix系统或其他边缘情况下cron的不同实现的问题。正如预期的那样,他可以通过cron运行python,他可以使用@reboot
功能,他可以写入磁盘而不会出现任何类型的权限问题。
然而,它仍然没有奏效。 解决问题的方法只是使用绝对路径而不是相对路径。
更改
webcam_horz_home = open("horz.txt", "a")
到
webcam_horz_home = open("/home/pi/horz.txt", "a")
和
webcam_vert_home = open("vert.txt", "a")
到
webcam_vert_home = open("/home/pi/vert.txt", "a")
让p的步进者再次发出声响:)
说明/背景
当通过其他用户的crontab执行脚本或命令时(在这种情况下为root
),相对于普通用户的主目录(例如~/.bashrc
)的路径将不再是有效或将指向具有相同文件名的不同文件(如果存在)。同样的问题&#34;有时会看到人们运行调用PHP等脚本语言的服务器(通常由www-data
用户执行)。
在Raspberry Pi上,这些东西在使用GPIO时可能会引起一些问题-22因为GPIO设备被锁定而没有更改权限和组的情况下无权访问非特权用户。
如果OP通过root
添加cron条目将其脚本作为sudo crontab -e
运行,则他可以访问GPIO设备(因为root
几乎可以访问所有内容)。但是,他的python脚本中隐含引用非特权用户pi
的主文件夹的相对路径将不再有效(因为home
现在意味着文件夹/root
是root
用户的主文件夹。
如果OP通过pi
用户的crontab通过crontab -e
添加cron条目(没有sudo
)来运行他的脚本,则路径将是有效的( home
或~/
现在意味着/home/pi/
),但由于pi
非常没有特权,因此他无法访问GPIO设备。注意:@reboot
功能并非在所有cron实现中都可用(某些嵌入式和精简版* nix发行版不具备它)并且通常它不适用于{{1}以外的用户}。
这意味着OP有两种选择(可能还有更多;我没有Linux大师):
root
和vert.txt
放入horz.txt
用户的主文件夹中。root
的crontab中继续运行脚本@reboot。 没有。 2可能更好,因为它保持root
的主文件夹为空并将OP文件保存在root
的主文件夹中。除非没有其他选项,例如使用pi
,否则root
通常不会被混淆。