我想让两个Raspberry Pi使用ZigBee协议互相发送消息。 我已经使用USB Explorer(CH430g)将XBee S2C(ZigBee)模块连接到Raspberry Pi。 我写了一个python脚本,可以完成所需的工作,
change
但是我需要一个C程序来做同样的事情, 我查看了用于C和C ++的libserial库,发现它有错误,并且从未为我编译过。
我尝试了this thread,但效果很好,但是在接收方,我需要将import serial
ser = serial.Serial('/dev/ttyUSB0', 9600)
while True:
incoming = ser.readline().strip()
print ('%s' %incoming.decode())
string = input("") + '\n'
ser.write(string.encode())
保持在read(fd, &buffer, sizeof(buffer));
循环中,以连续打开以进行监听,这与C套接字程序不同,其中{{ 1}}函数将停止运行,直到接收到数据为止,就像我的python脚本将在while
行中等待直到接收到一些消息一样。
有没有使用read()
循环的解决方案吗?
编辑1:
在上述python代码中,while循环用于接收多个消息。自incoming = ser.readline().strip()
循环以来,第while
行将捕获该消息,对其进行处理并等待下一条消息。
在C中,如果我的代码是这样的:
incoming = ser.readline().strip()
它会引发错误,因为while
在获取数据之前不会停止,而只是返回读取失败。由于读取的数据是while(1){
str = read();
//some processing
}
,因此数据的后处理将引发错误。
为了使其工作,我引入了另一个read
循环,如下所示:
NULL
我想消除此多余的循环,并使while
等待消息。
PS:我正在打开像这样的串行设备: while(1){
while(1){
str = read();
if(str!=NULL)
break;
}
//some processing
}
答案 0 :(得分:0)
从此代码中获得一些启发。这是使用C进行的非常通用的规范串行编程。
注意:规范的输入处理还可以处理擦除,删除单词和重印字符,将CR转换为NL等。
我建议您阅读这篇文章,以了解有关串行编程设置(不同模式)的更多信息。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
/* baudrate settings are defined in <asm/termbits.h>, which is
included by <termios.h> */
#define BAUDRATE B38400
/* change this definition for the correct port */
#define SERIAL_DEVICE "/dev/ttyS1"
#define FALSE 0
#define TRUE 1
volatile int STOP=FALSE;
int main(void)
{
int fd,c, res;
struct termios oldtio,newtio;
char buf[255];
/*
Open modem device for reading and writing and not as controlling tty
because we don't want to get killed if linenoise sends CTRL-C.
*/
fd = open(SERIAL_DEVICE, O_RDWR | O_NOCTTY );
if (fd <0) {perror(SERIAL_DEVICE); exit(-1); }
tcgetattr(fd,&oldtio); /* save current serial port settings */
memset(&newtio, sizeof(newtio)); /* clear struct for new port settings */
/*
BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed.
CRTSCTS : output hardware flow control (only used if the cable has
all necessary lines. See sect. 7 of Serial-HOWTO)
CS8 : 8n1 (8bit,no parity,1 stopbit)
CLOCAL : local connection, no modem contol
CREAD : enable receiving characters
*/
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
/*
IGNPAR : ignore bytes with parity errors
ICRNL : map CR to NL (otherwise a CR input on the other computer
will not terminate input)
otherwise make device raw (no other input processing)
*/
newtio.c_iflag = IGNPAR | ICRNL;
/*
Raw output.
*/
newtio.c_oflag = 0;
/*
ICANON : enable canonical input
disable all echo functionality, and don't send signals to calling program
*/
newtio.c_lflag = ICANON;
/*
initialize all control characters
default values can be found in /usr/include/termios.h, and are given
in the comments, but we don't need them here
*/
newtio.c_cc[VINTR] = 0; /* Ctrl-c */
newtio.c_cc[VQUIT] = 0; /* Ctrl-\ */
newtio.c_cc[VERASE] = 0; /* del */
newtio.c_cc[VKILL] = 0; /* @ */
newtio.c_cc[VEOF] = 4; /* Ctrl-d */
newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
newtio.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */
newtio.c_cc[VSWTC] = 0; /* '\0' */
newtio.c_cc[VSTART] = 0; /* Ctrl-q */
newtio.c_cc[VSTOP] = 0; /* Ctrl-s */
newtio.c_cc[VSUSP] = 0; /* Ctrl-z */
newtio.c_cc[VEOL] = 0; /* '\0' */
newtio.c_cc[VREPRINT] = 0; /* Ctrl-r */
newtio.c_cc[VDISCARD] = 0; /* Ctrl-u */
newtio.c_cc[VWERASE] = 0; /* Ctrl-w */
newtio.c_cc[VLNEXT] = 0; /* Ctrl-v */
newtio.c_cc[VEOL2] = 0; /* '\0' */
/*
now clean the modem line and activate the settings for the port
*/
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
/*
terminal settings done, now handle input
In this example, inputting a 'z' at the beginning of a line will
exit the program.
*/
while (STOP==FALSE) { /* loop until we have a terminating condition */
/* read blocks program execution until a line terminating character is
input, even if more than 255 chars are input. If the number
of characters read is smaller than the number of chars available,
subsequent reads will return the remaining chars. res will be set
to the actual number of characters actually read */
res = read(fd,buf,255);
buf[res]=0; /* set end of string, so we can printf */
printf(":%s:%d\n", buf, res);
if (buf[0]=='z') STOP=TRUE;
}
/* restore the old port settings */
tcsetattr(fd,TCSANOW,&oldtio);
return 0;
}
答案 1 :(得分:0)
如果您不希望连接是非阻塞的,则可能要删除添加到open
的调用中的O_NDELAY选项,该选项将打开非阻塞。就是这样...
uart0_filestream = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);
此外,read
不返回字符串,它返回读取的字节数,因此您对read
的调用应更像
bytecount = read(uart0_filestream, str, 20);
if(bytecount>0)
{
str[bytecount]='\0';
}
else
{
// Something bad happened?
}