使用 Linux 与 Arduino 通信

Communication with Arduino using Linux

这是我第一次用我的电脑与Arduino交流。我使用 Ubuntu 14.04。这是用于写入文件的 C 程序。 Arduino 显示 ttyACM0。

使用 gcc 编译时,编译器显示错误消息:

Segmentation fault(core dumped)

如何纠正这个错误。

#include<unistd.h>
#include<stdio.h>
int main() {
  char data[] = {'f','b','r'};  //Random data we want to send
  FILE *file;
  file = fopen("/dev/ttyACM0","w");  //Opening device file
  int i = 0;
  for(i = 0 ; i < 3 ; i++) {
    fprintf(file,"%c",data[i]); //Writing to the file
    fprintf(file,"%c",','); //To separate digits
    sleep(1);
  }
  fclose(file);
}

原谅我的无知。我试着研究它。无法让它发挥作用。预先感谢您的帮助。

您没有对 fopen("/dev/ttyACM0","w"); 的 return 值进行任何成功检查。如果 fopen() 失败,进一步使用 file 是未定义的行为,导致分段错误。做一些像

file = fopen("/dev/ttyACM0","w");  //Opening device file
if (file)
{
        //do something with file
}
else
     return 0;

另外,在结束main()之前添加一个return 0

您从 fopen() 得到一个 NULL return,NULL 被传递给 fprintf(),它需要一个有效的 FILE* 和搞砸导致 SEGV.

如果您使用 fopen,您应该检查它 return 的内容,以便为用户提供比 "segmentation fault".

更有用的东西

fopen()失败的可能原因是您没有使用串口的权限。

一般需要dialout组才能访问串口

作为 root 执行:

usermod -a -G dialout你的用户名

然后注销并重新登录,这样您就可以获得新组。

考虑使用 minicom 或 microcom(在其他几个串行终端程序中的任何一个上)访问串行端口,而不是自己编写。

我还建议你让 Arduino 在启动时发送一条问候消息,这样你就可以确保你有正确的波特率等...

失败 fopen returns NULL,因此您可能会取消引用 NULL 指针,正确的做法是检查 fopen。然而,我会为这种事情建议低级 IO,例如

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>

int main()
{
    char data[] = {'f','b','r'};  //Random data we want to send
    int fd;
    int i;

    fd = open("/dev/ttyACM0", O_WRONLY);  //Opening device file
    if (fd == -1)
    {
        perror("cannot open /dev/ttyACM0");
        return -1;
    }

    for(i = 0 ; i < 3 ; i++)
    {
        write(fd, &(data[i]), 1);
        write(fd, ",", 1);

        sleep(1);
    }
    close(fd);

    return 0;
}

错误 open returns 一个特殊值 -1 所以你应该中止写入它。

我很确定你的情况会出现 permission denied 错误,因为通常 /dev/tty* 属于组 dialout 并且默认情况下它们具有组写权限,但是因为您的用户可能不属于该组,所以您没有 /dev/ttyACM0.

的写入权限
// the following code:
//  compiles cleanly
//  performs appropriate error checking
//  has proper return statement

#include <unistd.h> // sleep()
#include <stdio.h>  // fopen(), fclose(), fprintf(), perror()
#include <stdlib.h> // exit() and EXIT_FAILURE

int main()
{
    char data[] = {'f','b','r'};  //Random data we want to send
    FILE *file;
    if( NULL == (file = fopen("/dev/ttyACM0","w") ) )  //Opening device file
    { // then fopen failed
        perror("fopen failed for ttyACM0" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    int i = 0;
    for(i = 0 ; i < 3 ; i++)
    {
        if( 0 >= fprintf(file,"%c",data[i]) ) //Writing to the file
        { // fprintf failed
            perror("fprintf data failed" );
            exit( EXIT_FAILURE );
        }

        // implied else, fprintf successful for data

        if( 0 >= fprintf(file,"%c",',') ) //To separate digits
        { // then, fprintf failed
            perror( "fprintf for comma failed");
            exit( EXIT_FAILURE );
        }

        // implied else, fprintf successful for comma

        sleep(1);
    } // end for
    fclose(file);
    return(0);
} // end function: main