Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BufferedReader skipping random characters when reading from USB

I'm using a BufferedReader to read data from an USB gateway which periodically receives ZigBee network frames from an Arduino device.

This is what the frame is supposed to look like:

~f�}3�@v<-,R#}3�@v<--mac:0013A20040763C2D -H:-25.80 -T:22.58 -L:2.6451 -N:100.00 -D:0.0290 -B:35 

But instead, it's always missing some characters near the end of the MAC address, like so:

~f�}3�@v<-,R#}3�@v<--mac:0013A2004076D -H:-25.80 -T:22.58 -L:2.6451 -N:100.00 -D:0.0290 -B:35 

Or

~f�}3�@v<-,R#}3�@v<--mac:0013A2004076C2:-25.80 -T:22.58 -L:2.6451 -N:100.00 -D:0.0290 -B:35 

The garbage at the beginning is low-level network header info, I guess.

I'm on Ubuntu, and the frames show perfectly fine when reading from a terminal, using

cat /dev/ttyUSB0

The code I use to read from the USB port looks like this. It runs in its own Thread.

public void run() {
    Boolean keepRunning = true;
    BufferedReader br = new BufferedReader(new InputStreamReader(portReader.getInputStream()));
    String line;

    while (keepRunning) {
        try {   
            while ((line = br.readLine()) != null) {
                handleData(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

I'm using RXTXcomm.jar, available here http://rxtx.qbang.org/wiki/index.php/Main_Page

This is where I open the port.

while (!connected && !timedOut) {
                System.out.print("\n\nConnecting to " + portName);
                //Open Ports
                CommPort commPort = portIdentifier.open(this.getClass()
                        .getName(), 9600);

                //TODO Should we rule out other kinds?
                if (commPort instanceof SerialPort) {

                    //Pass the open port
                    SerialPort serialPort = (SerialPort) commPort;
                    serialPort.enableReceiveTimeout(15000);

                    //Configure the port communication interface
                    serialPort.setSerialPortParams(bauds,
                            SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
                            SerialPort.PARITY_NONE);

                    //Open a stream and read from the port
                    inputStream = serialPort.getInputStream();
                    int portBuffer = inputStream.read();

                    //Check if there is something in the buffer, which
                    //means that a connection was established
                    if (portBuffer > -1) {
                        connected = true;                           
                    } else {
                        System.err.println("Connection to " + portName
                                + " timed out");
                        serialPort.close();
                        inputStream.close();
                        timedOut = true;
                    }
                } else {
                    System.err
                            .println("Error: Only serial ports are handled by this application.");
                }
            }

Any ideas on what could be going wrong?

like image 439
cangrejo Avatar asked Apr 30 '26 00:04

cangrejo


1 Answers

well, I'm not sure if that was the problem, but you shouldn't cat on the serial port char device, as it won't setup the serial device properly (with the correct speed reading, parity etc.. and unbuffered). Always use instead screen /dev/ttyUSB0 SPEED, or python -m serial.tools.miniterm or minicom.

The garbage you're talking about that you prints out is indeed the frame data. You can find in the XBee manuals how it is built (the ~ character marking the beginning of a new frame in API mode, followed by the frame type, length, content and CRC). Given the CRC you can check whether the frame is correctly read, if there are no missing bits.

I wrote a XBee datagram parser in C++:

  • https://github.com/guyzmo/polluxnzcity/blob/master/PolluxGateway/src/xbee/xbee_communicator.C

and participated in one in C:

  • https://github.com/guyzmo/xbee-comm/blob/master/src/lib/xb_buffer.c

that you may use for inspiration to get things right.

And finally, I had really often contacts problems between the XBee and the board (making all incoming datagrams erroneous etc..). You may want to power cycle and/or replug the xbee dongle each time the data is getting wrong (hence the need of checking the incoming datagrams).

like image 133
zmo Avatar answered May 02 '26 14:05

zmo