大家上午好!最近我买了一个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);
}

之后,我用pySerial从Python解释来控制管脚,并且一切都正常工作。这里是一块解释器的输出:

Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import serial
>>> ser = serial.Serial('/dev/ttyUSB0', 9600)
>>> ser.write(chr(12))
>>> # The light turned on here
... 
>>> ser.write(chr(256-12))
>>> # The light turned off here
...

然后,我决定写一个简单的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下运行的程序,一切工作正常。甲Heisenbug。

更新:我做了控制器送我回它接收的数据,它看起来像它不接受任何东西,当我运行的脚本,但收到的一切,当我从解释发送数据。固件的代码现在看起来像这样:

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);
  }
}
有帮助吗?

解决方案

我想这可能是当串口打开,当数据被发送之间的竞争条件。我可能会坚持在开放和写入调用之间的睡眠。

另外,而不是使用这个库“串行”你可能只想开放和直接写入设备,也许它很有趣,做一些事情(见其他帖子中提到的双开)

其他提示

我的猜测是它有话与环境。

import os
print os.environ['PS1']

这将不会被设置的脚本。 (也许别的东西了。)

TTY的将取决于他们是否想在终端是交互的缓冲不同。这应该是你的两个方法的工作方式之间的唯一区别。很多应用程序决定这个就是否PS1(终端提示符)设置。如果设置了此在您的环境手动可以启动行为以同样的方式,因为它确实交互式。

另外,我想拨打呼叫的pyserial清空命令手动在脚本中。 (这将是优选的方式做到这一点,而是伪装成一个交互式终端的。)

您strace的输出显示它打开串口读/写的两次的。它将仅写入CHR(12)在第二时间,然后关闭该文件。我没有足够的信息来解决问题的你,但也许这会有所帮助?还是你已经明白这一点?

你能仔细检查,如果Arduino的复位,当您打开串行连接?如果它确实重置您发送的引导加载程序,而不是由你的代码被接收的第一个串行字节。然后引导加载程序可以假设要对控制器进行编程,并等待进一步的命令和/或数据。

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

为了测试这个写一个小的草图LED闪烁13,看看你的初始化Python脚本影响闪烁。如果是这样有一个自举程序。

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

1)确保没有引起初始化串行接口复位。 1a)中做到这一点上Python端 图1b)这样做的Arduino的侧   图1b硬件溶液)断开电路板上的迹线冒犯   图1b的软件解决方案)摆脱引导加载程序的

2)不同时,引导加载器正在做的工作发送数据。

在简单的解决方案是(2)我的首选溶液摆脱引导加载程序的。然而,在这种情况下,你需要一个在系统编程(这是一个好主意,反正)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top