使用 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
这是我第一次用我的电脑与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