【问题标题】:Serial interface initialisation with arduino and C使用arduino和C进行串行接口初始化
【发布时间】:2012-07-08 19:14:57
【问题描述】:

我想在我的 Mac 上使用 C 与我的 arduino “交谈”。我首先使用了arduino官网给出的链接中的代码:http://todbot.com/blog/2006/12/06/arduino-serial-c-code-to-talk-to-arduino/

使用“闪烁”示例它根本不起作用,我知道较新的 arduinos 在串行端口打开时会重置,但即使添加延迟(最多 4 秒),它只会在我发送的任何字符时闪烁。

我还尝试通过在 termios 标志中禁用 HUPCL(应该防止重置)来更改代码,但它不会改变任何东西。

有趣的事情是,如果我在后台加载 Arduino 官方应用程序的串行监视器,它就可以工作。命令屏幕也功能齐全。所以我想这与串行通信的初始化有关。然后,我尝试使用 stty -a 获取监视器使用的标志(l、i、o 和 c),并在我的 C 程序中使用它们......没有运气!

感谢您的帮助!

PS:这是在 ebay 上购买的中国克隆...也许它可能是相关的

编辑:我尝试使用 python 对 pyserial 做同样的事情,它做同样的事情:只有在 arduino 应用程序的串行监视器同时运行时才有效

【问题讨论】:

  • 没有 arduino 的“克隆”之类的东西 - 硬件是开源的,任何人都可以构建和分发它。
  • 另外,插入 arduino 后在终端中运行此命令:ls /dev/ |grep tty.usbserial
  • 我知道硬件是开源的,但我看过论坛帖子,人们在使用便宜的 arduino 时遇到了麻烦......该命令让我得到这个 'tty.usbserial-A5006HGR'
  • arduino 正在连接到计算机并打开成功的连接然后...您应该能够将字节写入该文件并将它们发送到 arduino。
  • 我知道,就像我写的那样,它正在使用串行监视器工作,但如果我使用 C 或 python 就不行,这是我想做的。

标签: c macos serial-port arduino


【解决方案1】:

嗯,我想我找到了。

我可以尝试使用 arduino Uno,结果是一样的。然后我意识到,由于某种模糊的原因,我的 arduino 正在通过串行端口进行每次通信时重置,而不仅仅是在第一次连接时。由于在 windows 下结果是一样的,我猜这与我的笔记本电脑有关(MBP 15",2011 年初,10.7.4)。

然后我搜索了一下,发现实际上有一种方法可以使用 C 或 Python 禁用 DTR(使电路板复位的信号)。

import serial, time

#open the serial port
s = serial.Serial(port='/dev/tty.usbserial-A5006HGR', baudrate=9600)

#disable DTR
s.setDTR(level=False)

#wait for 2 seconds
time.sleep(2)

#send the data
s.write("7")

在C中你需要从串口加载参数,禁用DTR然后更新参数,这是使用ioctl完成的(来自http://www.easysw.com/~mike/serial/serial.html#5_1_2

//load status
int status;
ioctl(fd, TIOCMGET, &status);

//disable DTR
status &= ~TIOCM_DTR;

//update the status
ioctl(fd, TIOCMSET, &status);

这可以在端口打开后放在代码中。但是板子在第一次连接时仍然会重启,那么第一次延迟仍然是必要的。

我希望这将帮助处于相同(不寻常)情况的人们。

【讨论】:

  • 对我来说非常不寻常的同样问题。谢谢
  • 这是否消除了使用arduino-serial 命令时的延迟?例如,当我调用“./arduino-serial -b 9600 -p /dev/tty.usbmodemfa131 -d 2000 -s 1”或当我调用无延迟且 arduino 串行监视器打开时,我的项目会立即响应...
【解决方案2】:

最后,我发现对于 Linux 中的 Python(在我的例子中是 2.7.3)你必须这样做:

ser = serial.Serial('/dev/ttyACM0', 9600)
ser.dsrdtr=False
ser.setDTR(level=False)

不会有重置

【讨论】:

    【解决方案3】:

    我还没有发现这种方法对于在 mac 上打开串口来说太可靠了。我建议使用 ioctl,因为它更加健壮并提供许多优点,主要是使用任意波特率。

    #import <IOKit/serial/ioss.h>
    #import <sys/ioctl.h>
    
    - (int)serialInit:(const char*)path baud:(int)baud;
    {
        struct termios options;
    
        // open the serial like POSIX C
        int serialFileDescriptor = open(path, O_RDWR | O_NOCTTY | O_NONBLOCK);
    
        // block non-root users from using this port
        ioctl(serialFileDescriptor, TIOCEXCL);
    
        // clear the O_NONBLOCK flag, so that read() will
        //   block and wait for data.
        fcntl(serialFileDescriptor, F_SETFL, 0);
    
        // grab the options for the serial port
        tcgetattr(serialFileDescriptor, &options);
    
        // setting raw-mode allows the use of tcsetattr() and ioctl()
        cfmakeraw(&options);
    
        // specify any arbitrary baud rate
        ioctl(serialFileDescriptor, IOSSIOSPEED, &baud);
    
        return serialFileDescriptor;
    }
    

    【讨论】:

    • 感谢您的回答,我尝试了您的代码,如果我保留 'fcntl' 行,它就会挂起。如果我删除它,那么它不会改变任何东西并且表现得像以前一样:它只闪烁一次。我也尝试在 Windows 上使用 python(arduino 网站上给出的非常简单的脚本)来做它,它只是做同样的事情。我想这与板子和我的电脑有关,我会尝试再买一个,看看我是否幸运。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多