Skip to content
Advertisement

XBee Linux Serial Port on Raspberry Pi

I have 2 Adafruit XBee 2 Modules each connected with 1 FTDI cable (ttyUSB0 and ttyUSB1)to the Raspberry Pi via a USB hub. I configure both XBee modules independently to be on the same PAN and then I try to read in a while loop with one, and write a simple message in a while loop in the other. For some reason I never read anything from the second port.

Here is the test code I am using.

Configure:

xbee::xbee(char* usbPort) {

    /*
    -> AT (check if xbee modem is responding)
    <- OK
    -> ATID (get current PAN)
    <- 3332 (default, or something else)
    -> ATID 3137 (set new id)
    <- OK
    -> ATID (check again)
    <- 3137
    -> ATWR (write the change to flash)
    <- OK
    */

    // Sleep for a little bit
    QWaitCondition waitCondition;
    QMutex mutex;

    // Get a util object
    Linuxutils util;

    // Open a serial port
    qDebug() << "Opening Serial Port:" << QString(usbPort);
    char port[] = "ttyUSB1";
    int fd = util.openSerialPort(port);
    qDebug() << "Done opening Serial Port " << QString(usbPort) << ": " << fd;
    int didConfigurePort = util.configureSerialPort(fd,9600);
    qDebug() << "Did configure port successfully? " << didConfigurePort;

    // Receive buffer
    char rxBuffer[24];

    /////////////////////////////////////////////////////////////////////////////
    // Config Mode
    memset(rxBuffer, 0, sizeof(rxBuffer));
    char *msg = "+++";
    qDebug() << "Writing config string to XBee ( +++ )";
    util.writeToSerialPort(fd,msg);
    qDebug() << "XBee written to, waiting for response of 'OK'";
    while (true) {
        int readNumberOfBytes = util.readFromSerialPort(fd,rxBuffer,4096);
        printf("Received ( %d bytes ): %sn", readNumberOfBytes,rxBuffer);
        break;
    }

    /////////////////////////////////////////////////////////////////////////////
    // AT (check if xbee modem is responding)
    memset(rxBuffer, 0, sizeof(rxBuffer));
    char *msg2 = "ATn";
    qDebug() << "Check if XBee is responding ( AT )";
    util.writeToSerialPort(fd,msg2);
    qDebug() << "XBee written to, waiting for response of 'OK'";
    while (true) {
        int readNumberOfBytes = util.readFromSerialPort(fd,rxBuffer,4096);
        printf("Received ( %d bytes ): %sn", readNumberOfBytes,rxBuffer);
        break;
    }

    /////////////////////////////////////////////////////////////////////////////
    // AT (get current PAN ID)
    memset(rxBuffer, 0, sizeof(rxBuffer));
    char *msg3 = "ATIDn";
    qDebug() << "Get XBee PAN ID ( ATID )";
    util.writeToSerialPort(fd,msg3);
    qDebug() << "XBee written to, waiting for response which is integer of current PAN";
    while (true) {
        int readNumberOfBytes = util.readFromSerialPort(fd,rxBuffer,4096);
        printf("Received ( %d bytes ): %sn", readNumberOfBytes,rxBuffer);
        break;
    }

    /////////////////////////////////////////////////////////////////////////////
    // AT (get current PAN ID <VALUE>)
    memset(rxBuffer, 0, sizeof(rxBuffer));
    char *msg4 = "ATID 3137n";
    qDebug() << "Check if XBee is responding ( ATID 3137 )";
    util.writeToSerialPort(fd,msg4);
    qDebug() << "XBee written to, waiting for response after telling it to change to PAN 3137";
    while (true) {
        int readNumberOfBytes = util.readFromSerialPort(fd,rxBuffer,4096);
        printf("Received ( %d bytes ): %sn", readNumberOfBytes,rxBuffer);
        break;
    }

    /////////////////////////////////////////////////////////////////////////////
    // AT (get current PAN ID)
    memset(rxBuffer, 0, sizeof(rxBuffer));
    char *msg5 = "ATIDn";
    qDebug() << "Get XBee PAN ID ( ATID )";
    util.writeToSerialPort(fd,msg5);
    qDebug() << "XBee written to, waiting for response which is integer of current PAN";
    while (true) {
        int readNumberOfBytes = util.readFromSerialPort(fd,rxBuffer,4096);
        printf("Received ( %d bytes ): %sn", readNumberOfBytes,rxBuffer);
        break;
    }

    /////////////////////////////////////////////////////////////////////////////
    // AT (get current PAN ID <VALUE>)
    memset(rxBuffer, 0, sizeof(rxBuffer));
    char *msg6 = "ATWRn";
    qDebug() << "Write new settings to XBee Flash ( ATWR )";
    util.writeToSerialPort(fd,msg6);
    qDebug() << "XBee written to, waiting for it to write to flash...";
    while (true) {
        int readNumberOfBytes = util.readFromSerialPort(fd,rxBuffer,4096);
        printf("Received ( %d bytes ): %sn", readNumberOfBytes,rxBuffer);
        break;
    }

    // Close the file descriptor
    close(fd);

}

Read:

void xbee::xbeeRead(char* usbPort) {

    // Sleep
    QWaitCondition waitCondition;
    QMutex mutex;
    waitCondition.wait(&mutex, 5000);

    // Utils
    Linuxutils util;

    // File descriptor
    int fd = util.openSerialPort(usbPort);

    // Continually Read
    char buffer[4096];
    while (true) {

        // Sleep
        waitCondition.wait(&mutex, 1000);

        qDebug() << "Waiting for data...";

        int readNumberOfBytes = util.readFromSerialPort(fd,buffer,4096);

        // Print results
        printf("Read ( %d bytes ): %sn", readNumberOfBytes,buffer);

    }

    // Close
    close(fd);

}

Write:

void xbee::xbeeWrite(char *usbPort) {

    // Sleep
    QWaitCondition waitCondition;
    QMutex mutex;
    waitCondition.wait(&mutex, 5000);

    // Utils
    Linuxutils util;

    // File descriptor
    int fd = util.openSerialPort(usbPort);

    // Continually Write
    char *buffer =  "Hello World!n";
    while (true) {

        // Sleep
        waitCondition.wait(&mutex, 1000);

        int readNumberOfBytes = util.writeToSerialPort(fd,buffer);
        // Print results
        printf("Wrote ( %d bytes ): %sn", readNumberOfBytes,buffer);

    }

}

I can definitely configure each module – here is the example output for configuring ttyUSB0:

Input test type:  4 
Opening Serial Port: "/dev/ttyUSB0" 
Done opening Serial Port  "/dev/ttyUSB0" :  6 
Did configure port successfully?  0 
Writing config string to XBee ( +++ ) 
XBee written to, waiting for response of 'OK' 
Received ( 3 bytes ): OK

Check if XBee is responding ( AT ) 
XBee written to, waiting for response of 'OK' 
Received ( 3 bytes ): OK

Get XBee PAN ID ( ATID ) 
XBee written to, waiting for response which is integer of current PAN 
Received ( 5 bytes ): 3137

Check if XBee is responding ( ATID 3137 ) 
XBee written to, waiting for response after telling it to change to PAN 3137 
Received ( 3 bytes ): OK

Get XBee PAN ID ( ATID ) 
XBee written to, waiting for response which is integer of current PAN 
Received ( 5 bytes ): 3137

Write new settings to XBee Flash ( ATWR ) 
XBee written to, waiting for it to write to flash... 
Received ( 3 bytes ): OK

Waiting for data... 

Even though I can see that I am writing to the ttyUSB1 device in one while loop, I am not receiving anything at ttyUSB0.

Any ideas as to why this is happening?? Thanks!

Advertisement

Answer

Looks like you still have both XBees in command mode which will prevent any RF data transfer between these radio modules. Any serial data sent to the XBee will be ignored unless the line begins with the “AT” command prefix.

After you are done configuring each XBee, issue the “ATCN” command to exit command mode (there should be no “OK” response).
Then any serial data you send to the XBee will be transmitted by its radio, and the RF data received by the (other) XBee will be output on its serial port for reading by your program.

To re-enter command mode on an XBee module, nothing should be sent to the XBee serial port for one second (which is the default guard time), send a three character string of “+++” (three plus signs within 1 second), and then silence for another one second. The XBee should respond with an “OK” prompt.

All of this is standard Hayes modem AT command behavior.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement