从 IRobot Create 2 打印串行数据
Printing serial data from IRobot Create 2
我正在为 irobot create 2 开发接口,但在读取单个传入数据包时遇到问题。在哪里可以找到有关通过使用 termios、read()、write() 和 printf() 执行此操作的更多详细信息?除了大学期间的一些机器人项目外,我对这种编程还很陌生,而且可能遗漏了一些关键点。请原谅我的无知。
到目前为止,我已经成功确认发送初始化机器人、以各种模式启动它、start/stop IO 和关闭机器人的命令。为了读取以单个字节形式出现的数据,我发送了命令以通过写入函数定位指定的传感器数据包,这就是我感到困惑的地方。我已经为单个字节分配了一个向量,并试图 read() 返回值,然后 printf() 它。我不确定在打印值时使用哪种数据类型,或者我是否得到了我想要的。
*yungBot.cpp*
#include "yungBot.h"
#include <iostream>
/*initialize robot*/
int yungBot::init(const char *yungin){
fd = open(yungin, O_RDWR | O_NOCTTY | O_NDELAY);
if(fd == -1){
perror("Error, failed to connect");
}
else{
fcntl(fd,F_SETFL,0);
tcflush (fd, TCIFLUSH);
}
struct termios parameters;
int get = tcgetattr(fd, ¶meters);
if(get == -1){
perror("Error getting attributes");
}
else{
printf("%s\n", "Get attributes: success");
}
cfmakeraw (¶meters);
//sets input and output baud rate
cfsetispeed(¶meters,B115200);
cfsetospeed(¶meters,B115200);
// or forces values to 1; and forces all values to 0 (off);
parameters.c_iflag &= ~(IXON | IXOFF); //flow control off;
parameters.c_cflag |=(CLOCAL | CREAD);
parameters.c_cflag &= ~(PARENB | CSTOPB);//no parity
parameters.c_cflag &= ~CSIZE; //mask the character bits
parameters.c_cflag |= (CS8); //8 bit character size
parameters.c_oflag = 0;
parameters.c_lflag = 0;//ICANON=canonical mode
parameters.c_cc[VMIN] = 0; // 1 input byte is enough to return from read()
parameters.c_cc[VTIME] = 1;// Timer off
//set attribute immediately
int set = tcsetattr(fd, TCSANOW, ¶meters);
if(set == -1){
perror("Error setting attributes \n");
}
if (fd == -1){
perror(yungin);
return -1;
}
usleep(200000);
return fd;
}
/*stream desired data packets of 1 unsigned byte*/
int yungBot::stream(int packet){
unsigned char command[]={142,packet};
if(write(fd, command, sizeof(command))==-1){
perror("failed to retrieve data packet");
return -1;
}
unsigned char response[1];
if(read(fd,response,sizeof(response))!=1){
perror("failed to write data packet");
return -1;
}
//shift through the byte for individual bits
/*unsigned char bit = response[1];
for(int i = 0; i < CHAR_BIT; i++){
printf("%d", (bit>>i)&1);
}
*/
printf("%i",response[0]);
return response[0];
}
老实说,我不确定会发生什么。如果我读到诸如充电状态之类的内容,它似乎可以在未充电时返回 0 值,而在电池充满电时返回当前 3 值。当返回诸如碰撞和车轮跌落传感器之类的东西时(它们作为单个字节发送并且范围为 0-15,我不知道该怎么做。当按下不同的部分时,我在该范围内得到不同的值bumper etc..but 4 bits of the byte corresponding to 4 different values and other 4 are "reserved".我该如何去读这样的东西?我注意到车轮 drop/bump 传感器我根据 press/lift 机器人的位置获得某些值,例如:
right bump=1
left bump=2
middle bump=3
right drop=4
left drop =8
both dropped = 12
这就是我需要的吗?
哦,这很简单。您可以使用类似...
的方式读取这些位
#define LEFT_BUMPER 1
#define RIGHT_BUMPER 2
#define REAR_BUMPER 4
#define FRONT_BUMPER 8
if(bumper_state & LEFT_BUMPER){ printf("left bumper actuated\n") }
if(bumper_state & RIGHT_BUMPER){ printf("right bumper actuated\n") }
我们使用的最佳数据类型通常是与您正在阅读的内容大小相同的无符号类型,在这种情况下 uint8_t 会很好。
此外,您不需要数组,如果需要,您可以读入单个字节。它可能有助于以后避免混淆。
我正在为 irobot create 2 开发接口,但在读取单个传入数据包时遇到问题。在哪里可以找到有关通过使用 termios、read()、write() 和 printf() 执行此操作的更多详细信息?除了大学期间的一些机器人项目外,我对这种编程还很陌生,而且可能遗漏了一些关键点。请原谅我的无知。
到目前为止,我已经成功确认发送初始化机器人、以各种模式启动它、start/stop IO 和关闭机器人的命令。为了读取以单个字节形式出现的数据,我发送了命令以通过写入函数定位指定的传感器数据包,这就是我感到困惑的地方。我已经为单个字节分配了一个向量,并试图 read() 返回值,然后 printf() 它。我不确定在打印值时使用哪种数据类型,或者我是否得到了我想要的。
*yungBot.cpp*
#include "yungBot.h"
#include <iostream>
/*initialize robot*/
int yungBot::init(const char *yungin){
fd = open(yungin, O_RDWR | O_NOCTTY | O_NDELAY);
if(fd == -1){
perror("Error, failed to connect");
}
else{
fcntl(fd,F_SETFL,0);
tcflush (fd, TCIFLUSH);
}
struct termios parameters;
int get = tcgetattr(fd, ¶meters);
if(get == -1){
perror("Error getting attributes");
}
else{
printf("%s\n", "Get attributes: success");
}
cfmakeraw (¶meters);
//sets input and output baud rate
cfsetispeed(¶meters,B115200);
cfsetospeed(¶meters,B115200);
// or forces values to 1; and forces all values to 0 (off);
parameters.c_iflag &= ~(IXON | IXOFF); //flow control off;
parameters.c_cflag |=(CLOCAL | CREAD);
parameters.c_cflag &= ~(PARENB | CSTOPB);//no parity
parameters.c_cflag &= ~CSIZE; //mask the character bits
parameters.c_cflag |= (CS8); //8 bit character size
parameters.c_oflag = 0;
parameters.c_lflag = 0;//ICANON=canonical mode
parameters.c_cc[VMIN] = 0; // 1 input byte is enough to return from read()
parameters.c_cc[VTIME] = 1;// Timer off
//set attribute immediately
int set = tcsetattr(fd, TCSANOW, ¶meters);
if(set == -1){
perror("Error setting attributes \n");
}
if (fd == -1){
perror(yungin);
return -1;
}
usleep(200000);
return fd;
}
/*stream desired data packets of 1 unsigned byte*/
int yungBot::stream(int packet){
unsigned char command[]={142,packet};
if(write(fd, command, sizeof(command))==-1){
perror("failed to retrieve data packet");
return -1;
}
unsigned char response[1];
if(read(fd,response,sizeof(response))!=1){
perror("failed to write data packet");
return -1;
}
//shift through the byte for individual bits
/*unsigned char bit = response[1];
for(int i = 0; i < CHAR_BIT; i++){
printf("%d", (bit>>i)&1);
}
*/
printf("%i",response[0]);
return response[0];
}
老实说,我不确定会发生什么。如果我读到诸如充电状态之类的内容,它似乎可以在未充电时返回 0 值,而在电池充满电时返回当前 3 值。当返回诸如碰撞和车轮跌落传感器之类的东西时(它们作为单个字节发送并且范围为 0-15,我不知道该怎么做。当按下不同的部分时,我在该范围内得到不同的值bumper etc..but 4 bits of the byte corresponding to 4 different values and other 4 are "reserved".我该如何去读这样的东西?我注意到车轮 drop/bump 传感器我根据 press/lift 机器人的位置获得某些值,例如:
right bump=1
left bump=2
middle bump=3
right drop=4
left drop =8
both dropped = 12
这就是我需要的吗?
哦,这很简单。您可以使用类似...
的方式读取这些位#define LEFT_BUMPER 1
#define RIGHT_BUMPER 2
#define REAR_BUMPER 4
#define FRONT_BUMPER 8
if(bumper_state & LEFT_BUMPER){ printf("left bumper actuated\n") }
if(bumper_state & RIGHT_BUMPER){ printf("right bumper actuated\n") }
我们使用的最佳数据类型通常是与您正在阅读的内容大小相同的无符号类型,在这种情况下 uint8_t 会很好。
此外,您不需要数组,如果需要,您可以读入单个字节。它可能有助于以后避免混淆。