首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Arduino UNO中读取没有IDE的USB数据

在Arduino UNO中读取没有IDE的USB数据
EN

Stack Overflow用户
提问于 2021-04-17 09:26:40
回答 1查看 434关注 0票数 0

我有个阿迪诺·尤奥。我写了一个脚本来控制我的Arduino上连接到PIN 2,3,4的灯。电灯可以关了,也可以用我的笔记本电脑关掉:

  • 0关闭所有的LED
  • 1导通管脚1
  • 2导通管脚2
  • 3管脚2

<代码>H 194转LED管脚3<代码>H 210<编码>H 1115转LED管脚1和3<码组>H 212<编码>H 1136转LED管脚2和3<<编码>H 1157转所有LED。<代码>H 216<代码F代码>>

实际上,我只对从我的笔记本电脑发送数据并相应地闪烁灯感兴趣。

这是我的节目:

代码语言:javascript
复制
# pragma GCC optimize ("Ofast")

# define LED1 2
# define LED2 3
# define LED3 4

char buf[4] ;
unsigned char inp, len ;

void setup() {
    pinMode(LED1, OUTPUT) ;
    pinMode(LED2, OUTPUT) ;
    pinMode(LED3, OUTPUT) ;

    Serial.begin(115200) ;
    Serial.setTimeout(1) ;
}

void loop() {
    if (Serial.available() > 0) {
        len = Serial.readBytes(buf, 3) ;
    
        if (len) {
            buf[3] = '\0' ;
            inp = atoi(buf) ;
    
            // Illuminate LEDs
            digitalWrite(LED1, 1 & inp ? HIGH : LOW) ;
            digitalWrite(LED2, 2 & inp ? HIGH : LOW) ;
            digitalWrite(LED3, 4 & inp ? HIGH : LOW) ;
        }
    }
}

当我打开IDE的串行监视器并编写printf 1 > /dev/ttyUSB0时,它工作得很好。

但当我关闭串行显示器,和printf 1 > /dev/ttyUSB0,它不工作,我得到的唯一的东西是闪烁的车载发光二极管。

所以每次我需要点亮LED时,我必须确保IDE是打开的。

有没有一种在不打开IDE的情况下从任何Linux计算机写入Arduino串口的方法?

EN

回答 1

Stack Overflow用户

发布于 2021-04-22 18:08:23

好的,问题是arduino有Serial.read()代码。除非打开Arduino IDE的串行监视器,否则我发送的数据将失败。换句话说,如果我想要创建一个热插拔设备,我的笔记本电脑在循环中搜索,当插入时,将数据写入它,这是不可能的。

为了解决这个问题,我需要看看IDE的Serial做什么,它设置baudrate,并在所选端口上打开文件描述符3。

因此,为了解决热插拔问题,我首先需要设置波特率和匹配标志。然后,我需要使用fcntl文件描述符3打开文件,就像IDE的串行监视器一样。

因为我用Ruby编写发送字节,所以我有机会编写C Ruby。我用以下代码设置了baudrate:

代码语言:javascript
复制
VALUE setBaudRate(volatile VALUE obj, volatile VALUE dev, volatile VALUE speed) {
    char *device = StringValuePtr(dev) ;
    unsigned int spd = NUM2UINT(speed) ;

    int serial_port = open(device, O_RDWR) ;
    struct termios tty ;

    char status = tcgetattr(serial_port, &tty) ;

    // IDE sets these flags
    // speed 57600 baud; line = 0;
    // min = 0; time = 0;
    // -brkint -icrnl -imaxbel
    // -opost
    // -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke

    if(status != 0) return Qnil ;
    tty.c_cflag &= ~CSIZE ;
    tty.c_cflag |= CS8 ;
    tty.c_cflag |= CREAD | CLOCAL ;
    tty.c_oflag &= ~OPOST ;

    tty.c_lflag &= ~ECHO ;
    tty.c_lflag &= ~ECHOCTL ;
    tty.c_lflag &= ~ECHOK ;
    tty.c_lflag &= ~ECHOE ;
    tty.c_lflag &= ~ECHOKE ;
    tty.c_lflag &= ~ISIG ;
    tty.c_lflag &= ~ICRNL ;
    tty.c_lflag &= ~IEXTEN ;
    tty.c_lflag &= ~ICANON ;

    tty.c_cc[VTIME] = 0 ;
    tty.c_cc[VMIN] = 0 ;

    cfsetispeed(&tty, spd) ;
    cfsetospeed(&tty, spd) ;
    status = tcsetattr(serial_port, TCSANOW, &tty) ;

    if (status == 0) return Qtrue ;
    else return Qfalse ;
}

如果您正在编写C,则只需将值函数名称替换为任何您想要的名称。如果失败了,它可以是0,失败可以是1和2。

现在,确保波德率与阿迪诺完全匹配。在这里,在我的Ruby扩展中,我实际上是从Ruby获得了volatile VALUE speed的波特率。然后它设定速度。纯C实现不会有太大的不同。

然而,在BASH中,您可以只使用stty

代码语言:javascript
复制
sudo stty -F /dev/ttyUSB0 -cread -clocal -isig -iexten -echo -echoe -echok -echoctl -echoe -brkint -icrnl -imaxbel -opost -icanon min 0 time 0 57600

无论如何,要写入文件,需要以读-写模式打开文件。Ruby提供了这样的功能,我会附加代码,以防它帮助到某人:

代码语言:javascript
复制
require 'fcntl'
device = '/dev/ttyUSB0'

fd = IO.sysopen(device, Fcntl::O_RDWR | Fcntl::O_EXCL)
file = IO.open(fd)
file.syswrite("Hello world!")
file.close

在BASH中,只需使用以下命令:

代码语言:javascript
复制
exec 3<> /dev/ttyUSB0

现在,如果您不想硬编码/dev/ttyUSB0 0,则需要从arduino发送一些字节,并在使用arduino设置正确的波德率匹配之后读取该字节。

通过这种方式,我们可以从arduino读取和写入该值!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67136611

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档