Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RXTX: provide a wait option after opening the serial port #957

Closed
wants to merge 1 commit into from

Conversation

jeje
Copy link

@jeje jeje commented Jan 18, 2013

I'm not sure why this pause might be needed for some devices, but this
is at least something which works with the devices I had trouble with.
One of the "known" device is an Arduino on Mac OS X (Lion). Perhaps the
virtual serial device is too slow compared to "native" ones.

I'm not sure why this pause might be needed for some devices, but this
is at least something which works with the devices I had trouble with.
One of the "known" device is an Arduino on Mac OS X (Lion). Perhaps the
virtual serial device is too slow compared to "native" ones.
@lw346
Copy link
Member

lw346 commented Jan 18, 2013

Blocking the core thread here seems a little bit scary.

Would it be better to create a new class, RxtxUnsafe (extending AbstractUnsafe) that instead of calling Thread.sleep() schedules with its eventLoop() the initialisation of the serial port?

@jeje
Copy link
Author

jeje commented Jan 18, 2013

I'm not sure I fully understand what you mean.

What code would you put in the RxtxUnsafe class?
Would it be the code after the current Thread.sleep() (and of course get rid of the sleep)?
If so, how would you use this RxtxUnsafe from the actual connect method?

Maybe I could simply create a Runnable with the code after the sleep and in the actual connect() method simply do something like:

eventLoop().schedule(<the runnable code>,
                     config().getOption(WAIT_AFTER_CONNECT), TimeUnit.MILLISECONDS);

@normanmaurer
Copy link
Member

@jeje @lw346 yeah I think blocking is not an option. I also wonder if we should really build that in the core or not let the user handle it in his handler which sounds "better" for me... WDYT ?

@jeje
Copy link
Author

jeje commented Jan 21, 2013

How would you do it in an handler?
The issue I had was that I needed to wait for a while after I open the serial port, but before we create the input and output streams from the serial port.

I can't see how you'd enable a handler to "inject" some wait between those two steps of the channel :-(
Did I miss something?

@normanmaurer
Copy link
Member

@jeje so the problem is that before the timeout elapsed it return null for the InputStream ?

@jeje
Copy link
Author

jeje commented Jan 21, 2013

This is actually weirder than that: both in and out are non-null, but then we can't send any message to the serial port...
I really don't understand the underlying issue. I couldn't find anything on Internet.
I even tried different RXTX libraries but no luck. Something specific to Mac OS X?
However, using an Arduino, this is 100% reproducible: without the wait the RXTX example fails, with a 1.5 seconds wait it works (1 second does not seem to be enough).

@normanmaurer
Copy link
Member

How it fails ?

Sent from my iPhone. Excuse any typos....

Am 21.01.2013 um 08:34 schrieb Jerome Bernard notifications@github.com:

This is actually weirder than that: both in and out are non-null, but then we can't send any message to the serial port...
I really don't understand the underlying issue. I couldn't find anything on Internet.
I even tried different RXTX libraries but no luck.
However, using an Arduino, this is 100% reproducible: without the wait the RXTX example fails, with a 1.5 seconds wait it works (1 second does not seem to be enough).


Reply to this email directly or view it on GitHub.

@jeje
Copy link
Author

jeje commented Jan 21, 2013

Well, the RXTX example simply sends an "AT\n" command on the serial port and waits for an "OK\n" string to exit.

From what I see on the Arduino RX/TX activity LEDs, the RXTX example does seem to send something (RX lights up for a short time) but nothing is sent back (no TX LED turned on).

But I know for sure that my Arduino sketch is okay because when adding the wait time, it works fine!!

When adding breakpoints on doReadBytes(...) and doWriteBytes(...), I can see that it seems to behave in the same way when sending the "AT\n" string, but when the wait is turned off, in doReadBytes(...) I always have in.available() equal to 0.

I tried changing baud rate (9600 instead of 57600) on both the RXTX example and the Arduino sketch but this does not change anything to the issue. I also tried with various waits in the Arduino sketch but nothing works.

@lw346
Copy link
Member

lw346 commented Jan 21, 2013

I've had a look into this using some of the serial devices I have (mainly GSM modems) available to me, and have been able to reproduce the problem with certain microcontrollers.

The sequence events goes something like this:

  1. Port is opened
  2. Port opening triggers reset in serial microcontroller
  3. Write happens while the microcontroller is resetting, and is effectively discarded
  4. Reset completes

This is very easily repeatable - I've tried various different wait timeouts, and 1s - 1.5s seems to be the minimum bound before the microcontroller has finished resetting and is capable of receiving data.

However, the sleep doesn't need to be in the connect phase; I was able to make it work by putting the sleep in the handler in all cases.

@jeje Can you try putting the sleep() in before the first write and see if that works?

@normanmaurer
Copy link
Member

I wonder if this also is fixed by #962 ... Could both of you retest with latest master ?

@jeje
Copy link
Author

jeje commented Jan 21, 2013

This probably has nothing to do with #962. My last tests were made using my own fork having a different solution than #962 but doing quite the same thing ;-)

I'll check that asap and also test @lw346 solution and report back to you both.

@jeje
Copy link
Author

jeje commented Jan 21, 2013

I can confirm that #962 does not help on this issue.

Also, I tried with a modified RXTXClientHandler doing Thread.sleep(2000) in channelActive(...) before writing the message, no success.

I did also another test by modifying RXTXClient right after ChannelFuture f = b.connect().sync();:

Thread.sleep(2000);
f.channel().write("AT\n");

This does not work too, but in this last case, there is no RX LED activity...

@lw346
Copy link
Member

lw346 commented Jan 21, 2013

Boo :(

I do wonder then if this is due to the arduino requiring a delay before the configuration options are coordinated too, in which case we do potentially need a pause of some kind between the open and the init. I'll do a pull request that shouldn't block the eventLoop main thread...

normanmaurer pushed a commit that referenced this pull request Jan 21, 2013
…the serial port but before configuration to allow the serial microcontroller to reset itself after opening.
@normanmaurer
Copy link
Member

@jeje please retest with latest master and report back.. thanks!

@jeje
Copy link
Author

jeje commented Jan 21, 2013

Works fine!

Thanks to both of you @normanmaurer and @lw346

@ghost ghost assigned normanmaurer Jan 21, 2013
@jeje jeje deleted the rxtx-wait branch January 21, 2013 16:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants