将十六进制发送到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[] = {" x7E x00 x04 x08 x69 x43 x54 xF7"};
sleep(1);
int wr1 = write(fd, cmd1, 8);
sleep(1);
int rd;
int spot = 0;
char buff = ' ';
char resp[128];
memset(resp, ' ', 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[] = {"ATCTr"};
int rd;
int spot = 0;
char buff = ' ';
char resp[32];
memset(resp, ' ', 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 = ' ';
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;
}
我得到的错误是
"读取时出错:资源暂时不可用"。
我确信这个设备没有被其他人使用,因为使用AT命令的代码运行良好。。。就好像Xbee无法理解十六进制。。。
我希望其他人已经遇到了这个问题。。。
好吧,这有点像收音机。。。
我试着读一个以\r结尾的答案,但真正的答案并没有以它结尾…
我换成:
do {
rd = read(fd, &buff, 1);
sprintf(&resp[spot], "%c", buff);
spot += rd;
} while (buff != 0x13 && rd > 0);
现在它运行良好。它只是试图读取不存在的字符。
编辑:
@VenushkaT问了我一个关于这个代码中一些问题的问题。由于我现在做了一些预处理好的事情,我发布了我的新代码:
void R1logger::listenPort()
{
// Creation of a buffer to store data from radio module
fill_n(buff, 2048, ' ');
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, ' ');
}
else
{
close(this->fd);
serialConfig();
}
}
}
由于存在阻塞调用(读取、选择),并且没有设置O_NONBLOCKING选项,因此此代码使用较少的CPu。我还考虑了读取失败的情况。
在另一篇文章中,一些人向我提出了串行配置的建议(有些选项上有一些错误,他们建议我更符合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;
}
}
}
相关文章:
- 使用 PYbombs 安装软件包 GNU 无线电时出错
- 如何使用C++通过xbee传输数据?
- 软件定义无线电 USRP X310 的测试程序
- 在 gnu 无线电中编译树模型时出现 CMake 错误
- 二进制表达式的操作数无效("无线电设备"和"常量无线电设备")
- 如何在GNU无线电中确定noutput_items
- 将十六进制发送到xbee无线电模块
- 20x4 lcd with arduino and xbee
- GNU 无线电值错误:无法强制端点
- XBee DigiMesh帧中的奇怪位和错误的校验和
- 使用Xbee PRO S1时,Arduino和Qt之间的通信错误
- XBee、外部库和作为参数的传递结构
- Xbee arduino通讯编程