2016-05-10 11 views
0

Ich versuche gerade, einen hexadezimalen Befehl an ein xbee-Funkmodul zu senden (API-Modus).Hexadezimal an ein xbee-Funkmodul senden

Hier ist mein Code:

#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; 
} 

Ich versuchte auch, wie folgt aus:

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); 

Wenn ich AT-Befehlsmodus verwenden funktioniert es völlig in Ordnung, hier ist der Code, der in AT-Befehl genau das gleiche tun Modus (Frage die Biene, wie lange es im Befehlsmodus nach "+++" dauert):

#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; 
} 

Der Fehler, den ich bekomme, ist

"Fehler beim Lesen: Ressource vorübergehend nicht verfügbar".

Ich bin sicher, dass das Gerät nicht durch etwas anderes, weil der Code, die AT-Befehl verwendet funktioniert gut verwendet wird ... Es ist, als ob die Xbee nicht in der Lage waren hexadezimal zu verstehen ...

Ich hoffe, dass jemand anderes bereits auf dieses Problem gestoßen ...

+0

die 'cmd1' Initialisierung sollte 'unsigned char cmd1 [] = {"\ x7E \ x00 \ x04 \ x08 \ x69 \ x43 \ x54 \ xF7"}; 'sein, auf deine Weise sendest du 8 Zeichen: null,' x ',' 7 ',' E ', Null,' x ',' 0 'und' 0 ', aber Ihr zweiter Versuch sollte in Ordnung sein, also weiß ich nicht, wo das Problem ist. – max66

+0

@ max66 Ich weiß. Mein XBee ist auf API Modus (AP 1) und ich bin in der Lage, API-Rahmen mit XCTU auf meinem Windows Laptop zu senden.Es scheitert nur unter Linux mit meinem C++ - Code.Ich bekomme den gleichen Fehler, wenn ich versuche, Dinge wie "jfhhrgohrg" zu senden, so dass die XBee don unde nicht rstand, was ich sende. Die Sache ist genau die gleichen Bytes mit dem C-Programm und XCTU senden, so bin ich sicher, dass der Befehl nicht falsch ist ... – rmilville

+0

Sie bekommen die * "Fehler beim Lesen: Ressource vorübergehend nicht verfügbar" *, weil Sie die geöffnet haben Endgerät für nicht blockierten Modus mit der Option "O_NDELAY". VMIN und VTIME werden im nicht blockierenden Raw-Modus ignoriert. – sawdust

Antwort

0

Ok, so dass es ein bisschen Adiot war ...

ich habe versucht, eine Antwort zu lesen, die mit \ r, aber die wirkliche Antwort finihed nicht mit ihm fertig. ..

ändere ich mit:

do { 
    rd = read(fd, &buff, 1); 
    sprintf(&resp[spot], "%c", buff); 
    spot += rd; 
} while (buff != 0x13 && rd > 0); 

Und jetzt funktioniert es gut. Es versucht nur, nicht vorhandene Zeichen zu lesen.

EDIT:

@VenushkaT fragte mich eine Frage zu einigen Problemen in diesem Code. Da ich etwas tat, das jetzt prerry gut funktioniert, schreibe ich meinen neuen Code:

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(); 
    } 
} 
} 

Dieser Code weniger CPU-Ressourcen, da Aufruf gibt es blockiert (lesen, wählen), und es gibt keine O_NONBLOCKING Option gesetzt. Ich betrachte auch den Fall, bei dem das Lesen fehlschlägt.

In einem anderen Beitrag, Spiel einige Leute mir Ratschläge für die serielle Konfiguration (es gab einige Fehler auf einige Optionen, und sie gaben mir Ratschläge so hier mehr POSIX-konform zu sein, es ist:

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

Ich bin neu bei xbee Ich benutze einfach Ihr Programm und speichern Sie in der Datei main.c, Und schließen Sie Xbee Pro s1 mit seriellen Konverter. Und führen Sie Ihr Programm wie folgt ------- venushka-pc @ venushkapc-ThinkPad-E460: ~/Desktop $ g ++ main.c -o Haupt venushka-pc @ venushkapc-ThinkPad-E460: ~/Desktop $ ./main Fehler beim Lesen: Ressource vorübergehend nicht verfügbar ----------- Haben Sie eine Idee über den Fehler? – VenushkaT

+0

@VenushkaT hat meine Antwort bearbeitet, um Ihnen zu helfen. Da ich eine Funktion veröffentlicht habe, kannst du sie nicht so nehmen und kompilieren, aber du kannst die Idee verstehen. Fühlen Sie sich frei zu kommentieren, wenn Sie ein anderes Problem haben. – rmilville