Отправка шестнадцатеричного в радиомодуль xbee

В настоящее время я пытаюсь отправить шестнадцатеричную команду радиомодулю 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;
}

Я получаю ошибку

Msgstr «Ошибка чтения: ресурс временно недоступен».

Я уверен, что устройство не используется чем-то другим, потому что код, который использует команду AT, работает нормально … Это как если бы Xbee не смог понять шестнадцатеричный код …

Я надеюсь, что кто-то еще уже сталкивался с этой проблемой …

0

Решение

Хорошо, так что это было немного адиот …

Я пытался прочитать ответ, заканчивающийся на \ 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, '\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();
}
}
}

Этот код использует меньше CPu, поскольку есть блокирующий вызов (чтение, выбор) и не установлена ​​опция O_NONBLOCKING.
Я также рассматриваю случай, когда чтение не удается.

В другом посте некоторые люди разыгрывают мне советы по настройке последовательного порта (были некоторые ошибки в некоторых опциях, и они дали мне совет быть более совместимыми с 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;
}
}
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]