0

I have a code which sends commands to a relay board over a virtual serial port attached to one of the USB connectors on the PC, and reads the response.

Syntax:

send:

command\r

response:

command\r
answer\r
>

On my dev PC, it works fine. (Lubuntu 13.10) but on the target PC (Lubuntu 12.04 LTS) it reads only the command I have sent. For example:

Send:

gpio read 0\r

Correct response (on my dev env it works like this):

gpio read 0\r
1\r
>

It also works well on other machimes too. But, unfortunatelly on that PC which I want to develop for, the response is like:

gpio read 0

And here the stream ends without the real response.

My code is:

public static String command(String command) throws Exception  {
    byte[] buffer = new byte[1024];
    int len = 0;
    out.flush();
    try{
        out.write(command.getBytes());
        out.write('\r');
        out.flush();
        int data;
        Thread.sleep(100);
            while (in.available() > 0)
        {
            data = in.read();
            if ( (char) data == '>') {
                break;
            }
                        buffer[len++] = (byte) data;
        }           


    } catch (IOException ex){
    }
    return new String(buffer);
}

Some parameters which might be useful:

dev machine:

kernel: 3.11.0-12 generic
java version: 1.7.0_51 OpenJDK IcedTea 2.4.4, 7u51-2.4.4-0ubuntu0.13.10.1

target machine:

kernel 3.7.1-030701-generic
java version: 1.7.0_55 OpenJDK IcedTea 2.4.7, 7u55-2.4.7-1ubuntu1~0.12.04.2

In both cases I use RXTX-2.2-pre2

Any ideas? Thanks for advance!

dsolimano
  • 8,870
  • 3
  • 48
  • 63

1 Answers1

0

It could be a timing problem. You have a Thread.sleep(100), but that is not very safe unless you know that the full response will always be available within 100ms. It is possible that in.available() is returning 0 before you expect because the full response has not been sent yet, even though you have read the first part of it.

An alternative could be this:

    do
    {
        data = in.read();
        if ( (char) data == '>') {
            break;
        }
        buffer[len++] = (byte) data;
    } 
    while(data != -1);

This will block indefinitely if there is no data or if your response never returns '>'. Depending on your device protocol, that might be the only way to safely make sure you've read everything. Ideally though, you could calculate exactly how many bytes you expect to receive and then do a readFully or similar.

Note that Rxtx can be configured so that read does not block, in which case you'd have to code this differently. (And certain older versions of rxtx have a bug such that read never blocks regardless of configuration.)

You should output the exception stacktrace in your catch handler, if you are not already, just-in-case there is an IO error occurring.

Also, per your code, your output would never include the '>' character in output. Just clarifying because you state that it does in your question.

Community
  • 1
  • 1
kaliatech
  • 17,579
  • 5
  • 72
  • 84
  • You got the one half of the solution. The other thing I missed, that the device accepted an LF CR (and not CR or CR LF) sequence as a command delimiter, so I had to send it out by hand. Thanks for the help! – Balazs Lehotai May 31 '14 at 19:11