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?
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++:
and participated in one in 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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With