将十六进制发送到 xbee 无线电模块
Sending Hexadecimal to a xbee radio module
我目前正在尝试向 xbee 无线电模块(API 模式)发送十六进制命令。
这是我的代码:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main()
{
int fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0 ){
cout << "Error " << errno << " opening /dev/ttyUSB0: " << strerror(errno) << endl;
}
else
{
struct termios tty;
struct termios tty_old;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0){
cout << "Error " << errno << " from tcgetattr: " << strerror (errno) << endl;
}
tty_old = tty;
cfsetispeed(&tty, B57600);
cfsetospeed(&tty, B57600);
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS;
tty.c_lflag = 0;
tty.c_oflag = 0;
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 50;
tty.c_cflag |= CREAD | CLOCAL;
cfmakeraw(&tty);
tcflush(fd, TCIFLUSH);
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
cout << "Error " << errno << " from tcsetattr" << endl;
}
unsigned char cmd1[] = {"[=10=]x7E[=10=]x00[=10=]x04[=10=]x08[=10=]x69[=10=]x43[=10=]x54[=10=]xF7"};
sleep(1);
int wr1 = write(fd, cmd1, 8);
sleep(1);
int rd;
int spot = 0;
char buff = '[=10=]';
char resp[128];
memset(resp, '[=10=]', sizeof(resp));
do {
rd = read(fd, &buff, 1);
sprintf(&resp[spot], "%c", buff);
spot += rd;
} while (buff != '\r' && rd > 0);
if (rd<0){
cout << "Error reading: " << strerror(errno) << endl;
}
else if (rd==0) {
cout << "Read nothing!" << endl;
}
else {
cout << "Read: " << resp << endl;
}
close(fd);
}
return 0;
}
我也这样试过:
unsigned char cmd1[8];
cmd1[0] = 0X7E;
cmd1[1] = 0X00;
cmd1[2] = 0X04;
cmd1[3] = 0X08;
cmd1[4] = 0X69;
cmd1[5] = 0X43;
cmd1[6] = 0X54;
cmd1[7] = 0XF7;
sleep(1);
int wr1 = write(fd, cmd1, 8);
当我使用 AT 命令模式时,它工作得非常好,这是在 AT 命令模式下完全相同的代码(问蜜蜂它在“+++”之后在命令模式下持续多长时间):
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main()
{
int fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0 ){
cout << "Error " << errno << " opening /dev/ttyUSB0: " << strerror(errno) << endl;
}
else
{
struct termios tty;
struct termios tty_old;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0){
cout << "Error " << errno << " from tcgetattr: " << strerror (errno) << endl;
}
tty_old = tty;
cfsetispeed(&tty, B57600);
cfsetospeed(&tty, B57600);
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS;
tty.c_lflag = 0;
tty.c_oflag = 0;
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 50;
tty.c_cflag |= CREAD | CLOCAL;
cfmakeraw(&tty);
tcflush(fd, TCIFLUSH);
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
cout << "Error " << errno << " from tcsetattr" << endl;
}
unsigned char cmd1[] = {"+++"};
sleep(1);
int wr1 = write(fd, cmd1, sizeof(cmd1) -1);
sleep(1);
//printf("%d \n", wr1);
unsigned char cmd2[] = {"ATCT\r"};
int rd;
int spot = 0;
char buff = '[=12=]';
char resp[32];
memset(resp, '[=12=]', sizeof(resp));
do {
rd = read(fd, &buff, 1);
sprintf(&resp[spot], "%c", buff);
spot += rd;
} while (buff != '\r' && rd > 0);
if (rd<0){
cout << "Error reading: " << strerror(errno) << endl;
}
else if (rd==0) {
cout << "Read nothing!" << endl;
}
else {
cout << "Read: " << resp << endl;
}
int wr2 = write(fd, cmd2, sizeof(cmd2) -1);
//printf("%d \n", wr2);
spot = 0;
buff = '[=12=]';
sleep(1);
do {
rd = read(fd, &buff, 1);
sprintf(&resp[spot], "%c", buff);
spot += rd;
} while (buff != '\r' && rd > 0);
if (rd<0){
cout << "Error reading: " << strerror(errno) << endl;
}
else if (rd==0) {
cout << "Read nothing!" << endl;
}
else {
cout << "Read: " << resp << endl;
}
close(fd);
}
return 0;
}
我得到的错误是
"Error reading: Resource temporarily unavailable".
我确定该设备没有被其他东西使用,因为使用 AT 命令的代码工作正常...就好像 Xbee 无法理解十六进制...
我希望其他人已经遇到过这个问题...
好吧,有点笨...
我试图阅读以 \r 结尾的答案,但真正的答案并没有以它结尾...
我更改为:
do {
rd = read(fd, &buff, 1);
sprintf(&resp[spot], "%c", buff);
spot += rd;
} while (buff != 0x13 && rd > 0);
现在一切正常。它只是试图读取不存在的字符。
编辑:
@VenushkaT 就这段代码中的一些问题问了我一个问题。由于我做了一些现在运行良好的事情,我 post 我的新代码 :
void R1logger::listenPort()
{
// Creation of a buffer to store data from radio module
fill_n(buff, 2048, '[=11=]');
this->ind = 0;
while(this->fd > 0)
{
// Creation of a buffer that stores data from serial port
char mes[1024];
fill_n(mes, 1024, '0');
// read is a blocking call so this function will not return until it effectively reads some data or if there is a problem
int rd = read(this->fd, &mes, sizeof(mes));
/*struct timeval tv;
gettimeofday(&tv, NULL);
unsigned long long check1 = (unsigned long long)(tv.tv_sec) * 1000 + (unsigned long long)(tv.tv_usec) / 1000;*/
if (rd > 0)
{
storeInBuff(mes, rd);
fill_n(mes, 1024, '0');
// If some data are read, we can have only a part of the frame so we call "poll" to wait for the rest of the data with a 10ms timeout
struct pollfd fds;
fds.fd = this->fd;
fds.events = POLLIN | POLLPRI;
int slct = 1;
while (slct > 0)
{
slct = poll(&fds, 1, 10);
if (slct > 0)
{
rd = read(this->fd, &mes, sizeof(mes));
if (rd > 0)
{
storeInBuff(mes, rd);
}
else
{
close(this->fd);
serialConfig();
}
}
}
/*gettimeofday(&tv, NULL);
unsigned long long check2 = (unsigned long long)(tv.tv_sec) * 1000 + (unsigned long long)(tv.tv_usec) / 1000;
unsigned long tmps = check2 - check1;
cout << "Temps de lecture : " << tmps << endl;*/
/*gettimeofday(&tv, NULL);
check1 = (unsigned long long)(tv.tv_sec) * 1000 + (unsigned long long)(tv.tv_usec) / 1000;*/
// Once the message is entirely read, we extract the radio frames
findFrame(0);
/*gettimeofday(&tv, NULL);
check2 = (unsigned long long)(tv.tv_sec) * 1000 + (unsigned long long)(tv.tv_usec) / 1000;
tmps = check2 - check1;
cout << "Temps calcul + ecriture sur disque : " << tmps << endl;*/
this->ind = 0;
fill_n(buff, 2048, '[=11=]');
}
else
{
close(this->fd);
serialConfig();
}
}
}
此代码使用较少 CPu 因为有阻塞调用(读取,select),并且没有设置 O_NONBLOCKING 选项。
我也考虑了读取失败的情况。
在另一个 post 中,有些人向我提出串行配置的建议(某些选项存在一些错误,他们给了我更多 POSIX 兼容的建议,所以在这里:
void R1logger::serialConfig()
{
// Open Serial Port
this->fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);
if (this->fd < 0 )
{
cout << "Error " << errno << " opening /dev/ttyUSB0: " << strerror(errno) << endl;
}
else
{
//Configure Serial Port
struct termios tty;
if (tcgetattr (this->fd, &tty) != 0)
{
cout << "Error " << errno << " from tcgetattr: " << strerror (errno) << endl;
}
cfsetispeed(&tty, B57600);
cfsetospeed(&tty, B57600);
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 50;
tty.c_cflag |= CREAD | CLOCAL;
cfmakeraw(&tty);
tcflush(this->fd, TCIFLUSH);
if (tcsetattr(this->fd, TCSANOW, &tty) != 0)
{
cout << "Error " << errno << " from tcsetattr" << endl;
}
}
}
我目前正在尝试向 xbee 无线电模块(API 模式)发送十六进制命令。
这是我的代码:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main()
{
int fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0 ){
cout << "Error " << errno << " opening /dev/ttyUSB0: " << strerror(errno) << endl;
}
else
{
struct termios tty;
struct termios tty_old;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0){
cout << "Error " << errno << " from tcgetattr: " << strerror (errno) << endl;
}
tty_old = tty;
cfsetispeed(&tty, B57600);
cfsetospeed(&tty, B57600);
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS;
tty.c_lflag = 0;
tty.c_oflag = 0;
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 50;
tty.c_cflag |= CREAD | CLOCAL;
cfmakeraw(&tty);
tcflush(fd, TCIFLUSH);
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
cout << "Error " << errno << " from tcsetattr" << endl;
}
unsigned char cmd1[] = {"[=10=]x7E[=10=]x00[=10=]x04[=10=]x08[=10=]x69[=10=]x43[=10=]x54[=10=]xF7"};
sleep(1);
int wr1 = write(fd, cmd1, 8);
sleep(1);
int rd;
int spot = 0;
char buff = '[=10=]';
char resp[128];
memset(resp, '[=10=]', sizeof(resp));
do {
rd = read(fd, &buff, 1);
sprintf(&resp[spot], "%c", buff);
spot += rd;
} while (buff != '\r' && rd > 0);
if (rd<0){
cout << "Error reading: " << strerror(errno) << endl;
}
else if (rd==0) {
cout << "Read nothing!" << endl;
}
else {
cout << "Read: " << resp << endl;
}
close(fd);
}
return 0;
}
我也这样试过:
unsigned char cmd1[8];
cmd1[0] = 0X7E;
cmd1[1] = 0X00;
cmd1[2] = 0X04;
cmd1[3] = 0X08;
cmd1[4] = 0X69;
cmd1[5] = 0X43;
cmd1[6] = 0X54;
cmd1[7] = 0XF7;
sleep(1);
int wr1 = write(fd, cmd1, 8);
当我使用 AT 命令模式时,它工作得非常好,这是在 AT 命令模式下完全相同的代码(问蜜蜂它在“+++”之后在命令模式下持续多长时间):
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main()
{
int fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0 ){
cout << "Error " << errno << " opening /dev/ttyUSB0: " << strerror(errno) << endl;
}
else
{
struct termios tty;
struct termios tty_old;
memset (&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0){
cout << "Error " << errno << " from tcgetattr: " << strerror (errno) << endl;
}
tty_old = tty;
cfsetispeed(&tty, B57600);
cfsetospeed(&tty, B57600);
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS;
tty.c_lflag = 0;
tty.c_oflag = 0;
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 50;
tty.c_cflag |= CREAD | CLOCAL;
cfmakeraw(&tty);
tcflush(fd, TCIFLUSH);
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
cout << "Error " << errno << " from tcsetattr" << endl;
}
unsigned char cmd1[] = {"+++"};
sleep(1);
int wr1 = write(fd, cmd1, sizeof(cmd1) -1);
sleep(1);
//printf("%d \n", wr1);
unsigned char cmd2[] = {"ATCT\r"};
int rd;
int spot = 0;
char buff = '[=12=]';
char resp[32];
memset(resp, '[=12=]', sizeof(resp));
do {
rd = read(fd, &buff, 1);
sprintf(&resp[spot], "%c", buff);
spot += rd;
} while (buff != '\r' && rd > 0);
if (rd<0){
cout << "Error reading: " << strerror(errno) << endl;
}
else if (rd==0) {
cout << "Read nothing!" << endl;
}
else {
cout << "Read: " << resp << endl;
}
int wr2 = write(fd, cmd2, sizeof(cmd2) -1);
//printf("%d \n", wr2);
spot = 0;
buff = '[=12=]';
sleep(1);
do {
rd = read(fd, &buff, 1);
sprintf(&resp[spot], "%c", buff);
spot += rd;
} while (buff != '\r' && rd > 0);
if (rd<0){
cout << "Error reading: " << strerror(errno) << endl;
}
else if (rd==0) {
cout << "Read nothing!" << endl;
}
else {
cout << "Read: " << resp << endl;
}
close(fd);
}
return 0;
}
我得到的错误是
"Error reading: Resource temporarily unavailable".
我确定该设备没有被其他东西使用,因为使用 AT 命令的代码工作正常...就好像 Xbee 无法理解十六进制...
我希望其他人已经遇到过这个问题...
好吧,有点笨...
我试图阅读以 \r 结尾的答案,但真正的答案并没有以它结尾...
我更改为:
do {
rd = read(fd, &buff, 1);
sprintf(&resp[spot], "%c", buff);
spot += rd;
} while (buff != 0x13 && rd > 0);
现在一切正常。它只是试图读取不存在的字符。
编辑:
@VenushkaT 就这段代码中的一些问题问了我一个问题。由于我做了一些现在运行良好的事情,我 post 我的新代码 :
void R1logger::listenPort()
{
// Creation of a buffer to store data from radio module
fill_n(buff, 2048, '[=11=]');
this->ind = 0;
while(this->fd > 0)
{
// Creation of a buffer that stores data from serial port
char mes[1024];
fill_n(mes, 1024, '0');
// read is a blocking call so this function will not return until it effectively reads some data or if there is a problem
int rd = read(this->fd, &mes, sizeof(mes));
/*struct timeval tv;
gettimeofday(&tv, NULL);
unsigned long long check1 = (unsigned long long)(tv.tv_sec) * 1000 + (unsigned long long)(tv.tv_usec) / 1000;*/
if (rd > 0)
{
storeInBuff(mes, rd);
fill_n(mes, 1024, '0');
// If some data are read, we can have only a part of the frame so we call "poll" to wait for the rest of the data with a 10ms timeout
struct pollfd fds;
fds.fd = this->fd;
fds.events = POLLIN | POLLPRI;
int slct = 1;
while (slct > 0)
{
slct = poll(&fds, 1, 10);
if (slct > 0)
{
rd = read(this->fd, &mes, sizeof(mes));
if (rd > 0)
{
storeInBuff(mes, rd);
}
else
{
close(this->fd);
serialConfig();
}
}
}
/*gettimeofday(&tv, NULL);
unsigned long long check2 = (unsigned long long)(tv.tv_sec) * 1000 + (unsigned long long)(tv.tv_usec) / 1000;
unsigned long tmps = check2 - check1;
cout << "Temps de lecture : " << tmps << endl;*/
/*gettimeofday(&tv, NULL);
check1 = (unsigned long long)(tv.tv_sec) * 1000 + (unsigned long long)(tv.tv_usec) / 1000;*/
// Once the message is entirely read, we extract the radio frames
findFrame(0);
/*gettimeofday(&tv, NULL);
check2 = (unsigned long long)(tv.tv_sec) * 1000 + (unsigned long long)(tv.tv_usec) / 1000;
tmps = check2 - check1;
cout << "Temps calcul + ecriture sur disque : " << tmps << endl;*/
this->ind = 0;
fill_n(buff, 2048, '[=11=]');
}
else
{
close(this->fd);
serialConfig();
}
}
}
此代码使用较少 CPu 因为有阻塞调用(读取,select),并且没有设置 O_NONBLOCKING 选项。 我也考虑了读取失败的情况。
在另一个 post 中,有些人向我提出串行配置的建议(某些选项存在一些错误,他们给了我更多 POSIX 兼容的建议,所以在这里:
void R1logger::serialConfig()
{
// Open Serial Port
this->fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);
if (this->fd < 0 )
{
cout << "Error " << errno << " opening /dev/ttyUSB0: " << strerror(errno) << endl;
}
else
{
//Configure Serial Port
struct termios tty;
if (tcgetattr (this->fd, &tty) != 0)
{
cout << "Error " << errno << " from tcgetattr: " << strerror (errno) << endl;
}
cfsetispeed(&tty, B57600);
cfsetospeed(&tty, B57600);
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 50;
tty.c_cflag |= CREAD | CLOCAL;
cfmakeraw(&tty);
tcflush(this->fd, TCIFLUSH);
if (tcsetattr(this->fd, TCSANOW, &tty) != 0)
{
cout << "Error " << errno << " from tcsetattr" << endl;
}
}
}