Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
pySerial在Python解释器中工作良好,但不是独立的_Python_Linux_Serial Port_Arduino_Pyserial - Fatal编程技术网

pySerial在Python解释器中工作良好,但不是独立的

pySerial在Python解释器中工作良好,但不是独立的,python,linux,serial-port,arduino,pyserial,Python,Linux,Serial Port,Arduino,Pyserial,早上好!最近我买了一块Arduino板,在我的房间里做一种“灯光控制”。以下是我编写的固件代码: int control = 0; int pin = 0; void setup() { Serial.begin(9600); for(pin = 0; pin <= 13; pin++) pinMode(pin, OUTPUT); } void loop() { control = Serial.read(); if (control > 0 &&

早上好!最近我买了一块Arduino板,在我的房间里做一种“灯光控制”。以下是我编写的固件代码:

int control = 0;
int pin = 0;

void setup()
{
  Serial.begin(9600);
  for(pin = 0; pin <= 13; pin++) pinMode(pin, OUTPUT);
}

void loop()
{
  control = Serial.read();
  if (control > 0 && control <= 13) digitalWrite(control, HIGH);
  if (control < 256 && control >= (256-13)) digitalWrite((256-control), LOW);
}
然后,我决定编写一个简单的Python脚本来执行相同的操作:

#!/usr/bin/env python

import serial
import time

ser = serial.Serial('/dev/ttyUSB0', 9600)

ser.write(chr(12))
time.sleep(1)
ser.write(chr(256-12))
但它根本不起作用!Arduino显示在我启动脚本时收到了一些东西,但什么也没有发生。下面是脚本的一段strace输出:

open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NONBLOCK) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B9600 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B9600 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B9600 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_START or TCSETS, {B9600 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B9600 -opost -isig -icanon -echo ...}) = 0
open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NONBLOCK) = 4
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, {B9600 -opost -isig -icanon -echo ...}) = 0
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, {B9600 -opost -isig -icanon -echo ...}) = 0
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, {B9600 -opost -isig -icanon -echo ...}) = 0
ioctl(4, SNDCTL_TMR_START or TCSETS, {B9600 -opost -isig -icanon -echo ...}) = 0
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, {B9600 -opost -isig -icanon -echo ...}) = 0
write(4, "\f", 1)                       = 1
close(4)                                = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f45cf4c88f0}, {0x4d9820, [], SA_RESTORER, 0x7f45cf4c88f0}, 8) = 0
exit_group(0)                           = ?
看起来一切都应该很好,所以我不知道问题出在哪里。我将非常感谢任何帮助,非常感谢

PS当我在PDB下运行程序时,一切正常。海森堡

更新:我让控制器将它接收到的数据发回给我,当我运行脚本时,它看起来没有接收到任何东西,但当我从解释器发送数据时,它会接收到所有东西。固件的代码现在如下所示:

int control = 0;
int pin = 0;

void setup()
{
  Serial.begin(9600);
  for(pin = 0; pin <= 13; pin++) pinMode(pin, OUTPUT);
}

void loop()
{
  if (Serial.available() > 0)
  {
    control = Serial.read();
    if (control <= 13) digitalWrite(control, HIGH);
    if (control < 256 && control >= (256-13)) digitalWrite((256-control), LOW);
    Serial.println(control);
  }
}
int控制=0;
int引脚=0;
无效设置()
{
Serial.begin(9600);
用于(引脚=0;引脚0)
{
control=Serial.read();
如果(控制=(256-13))数字写入((256控制),则为低电平;
串行打印LN(控制);
}
}

您的strace输出显示它打开串行端口读/写两次。第二次只写入chr(12),然后关闭文件。我没有足够的信息为您解决这个问题,但这可能会有帮助吗?还是你已经弄明白了?

我猜这与环境有关

import os
print os.environ['PS1']
从一个不会被设置的脚本。(也许还有别的事情。)

tty将根据他们是否认为终端是交互式的而进行不同的缓冲。这应该是两种方法工作方式的唯一区别。许多应用程序决定是否设置PS1(终端提示符)。如果在您的环境中手动设置,它可能会以交互方式开始运行


另外,我会在脚本中手动调用调用pyserial flush命令。(这将是最好的方式,而不是伪装成一个交互式终端。)

我认为这可能是串行端口打开和数据发送之间的竞争条件。我可能会在开放电话和写电话之间睡一觉


或者,您可能不想使用这个“串行”库,只想直接打开并写入设备,也许它做了一些有趣的事情(请参阅其他帖子中提到的双重打开)

您可以在打开串行连接时再次检查Arduino是否复位吗?如果它确实重置了您发送的第一个串行字节,则引导加载程序将接收到它,而不是您的代码。然后,引导加载程序可能会假定您希望对控制器进行编程,并等待进一步的命令和/或数据

引导加载程序的确切行为取决于特定的Arduino

为了测试这一点,写一个LED 13闪烁的小草图,看看初始化Python脚本是否会影响闪烁。如果是这样,则有一个引导加载程序

为了解决这个问题,有几种可能的解决方案:

1) 确保初始化串行接口不会导致复位。 1a)在Python端执行此操作 1b)在Arduino侧进行此操作 1b硬件解决方案)断开电路板上有问题的记录道 1b软件解决方案)摆脱引导加载程序

2) 引导加载程序工作时不要发送数据


最简单的解决方案是(2)我更喜欢的解决方案是摆脱引导加载程序。然而,在这种情况下,您需要一个系统内程序员(无论如何这是一个好主意)。

Did
ser.write(chr(12));睡眠时间(1);ser.write(chr(256-12))
在控制台上工作正常?是的。指示灯打开、关闭,jpnevulator显示控制器返回的数据。当我对脚本执行相同操作时,jpnevulator显示没有返回任何数据,也没有发生任何事情。我升级了pySerial,但没有结果。您可以尝试:0。
print ser
是否从控制台和脚本生成相同的结果?1.将代码放入
defmain():..
并使用
if\uuuuu name\uuuu==“\uuuu main\uuuuu”:main()
2保护调用。在第一个
ser.write()之前添加
time.sleep(2)
。在每次写入()之后添加flush()。4.添加ser.close()哇,实际上在第一次写之前就把time.sleep(2)放进去了!它现在开始工作了!我不认为事情会这么简单。不过,它需要2秒或更长的睡眠时间才能工作。是的,它看起来好像打开了两次,然后写入第二个描述符。也许我可以试着用另一个版本的Python做同样的事情。我在一台没有串口的笔记本电脑上,否则我会很乐意帮你调试这个!由于脚本似乎成功地将
chr(12)
写入了端口,运行它时灯是否至少亮了?他说没有,这表明有两个句柄打开到同一个串行端口可能是问题的一部分。一些串行设备驱动程序和UART处理控制字符的方式与普通的不同,因此,可能正在拦截
chr(12)
,这是一个ASCII FF或formfeed字符。另一件事是串行通信可以是7位或8位,因此如果设置为7位,则很难通过通道发送
chr(256-12)
,或0xF4,8位字符。可能还有其他通信设置,如每个字符的数据位数、奇偶校验和每个字符的停止位数,也会导致问题。不过,这些都不能解释interp与脚本之间的差异。我比较了脚本和解释器中的os.environ内容,它们看起来很相似。是的,当我在pdb下运行脚本时,一切都正常。我尝试使用flush,但似乎不起作用。我稍后会尝试修改PS1。是的,时间到了。睡眠(2)起作用了!事实上,它不依赖于编程语言,即使在C(使用POSIX调用)和C++(使用LIB系列)之前,我也有相同的问题,直到我添加了睡眠。
import os
print os.environ['PS1']