I have a bluetooth IMU (seen as a serial device at /dev/rfcomm0) that returns the current angle in quaternions 50 times a second.
I did a test program to read data and it worked, but I have to integrate it in a while cycle where, after the reading is done, a thread is a created and a computationally expensive elaboration is done, so I cannot read keep the rate with the IMU data.
The IMU sends me a 54 bytes packet, and the first two bytes are always set to Ascii "tt".
This is the C code I'm using:
int set_interface_attribs(int fd, int speed)
{
struct termios tty;
if (tcgetattr(fd, &tty) < 0) {
printf("Error from tcgetattr: %s\n", strerror(errno));
return -1;
}
cfsetospeed(&tty, (speed_t)speed);
cfsetispeed(&tty, (speed_t)speed);
tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; /* 8-bit characters */
tty.c_cflag &= ~PARENB; /* no parity bit */
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
/* setup for non-canonical mode */
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
tty.c_oflag &= ~OPOST;
/* fetch bytes as they become available */
tty.c_cc[VMIN] = 54;
tty.c_cc[VTIME] = 1;
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
printf("Error from tcsetattr: %s\n", strerror(errno));
return -1;
}
return 0;
}
int start_serial()
{
char *portname = "/dev/rfcomm0";
int fd;
int wlen;
fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0) {
printf("Error opening %s: %s\n", portname, strerror(errno));
return -1;
}
set_interface_attribs(fd, B115200);
wlen = fwrite(fd, "?!CALIB050!?\n", 14);
if (wlen != 14) {
printf("Error from write: %d, %d\n", wlen, errno);
}
tcflush(fd,TCIFLUSH);
tcdrain(fd); /* delay for output */
return fd;
}
int read_serial(int fd)
{
char buf[54];
int rdlen;
rdlen = read(fd, buf, 54);
if (rdlen > 0)
{
struct CPacketCalib cc = CPacketCalibConvert(buf);
printf("%f %f %f %f\n",cc.q.I, cc.q.J, cc.q.K,cc.q.W);
}
else if (rdlen < 0)
{
printf("Error from read: %d: %s\r\n", rdlen, strerror(errno));
}
return 1;
}
int stop_serial(int fd)
{
int wlen = write(fd, "?!STOPSEND!?\n", 14);
if (wlen != 14)
{
printf("Error from write: %d, %d\n", wlen, errno);
}
fclose(fd);
return 1;
}
How can I flush the serial buffer at every cycle and start to get correctly my packet?
Thank you for your help.