[英]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[] = {"\0x7E\0x00\0x04\0x08\0x69\0x43\0x54\0xF7"};
sleep(1);
int wr1 = write(fd, cmd1, 8);
sleep(1);
int rd;
int spot = 0;
char buff = '\0';
char resp[128];
memset(resp, '\0', 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 = '\0';
char resp[32];
memset(resp, '\0', 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 = '\0';
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問我一個有關此代碼中某些問題的問題。 由於我現在所做的事情在prerry上都能正常工作,因此我發布了新代碼:
void R1logger::listenPort()
{
// Creation of a buffer to store data from radio module
fill_n(buff, 2048, '\0');
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, '\0');
}
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;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.