USBConnection USBSend/USBReceive example issue?

This is where you talk about the NXJ software itself, installation issues, and programming talk.

Moderators: 99jonathan, roger, imaqine

USBConnection USBSend/USBReceive example issue?

Postby RoboPAL » Fri Mar 14, 2008 6:54 pm

I want to try to setup a bi-directional communication channel with the NXT and the USBSend/USBReceive example seems a good place to start.

I can get the example working with USBReceive on the NXT and USBSend on the PC.

The way it works is the the USBSend (pc) sends some data and then waits for the response from the NXT. ie ithe pc is effectively polling the NXT and I have been able to setup a buffer so data is requested by the PC and then sent by the NXT and that works although not entirely reliably.

Now, what I really want is for the NXT to be able to send data whenever it wants, without waiting first for data from the PC. But if say I comment out the read and replace it with a sleep and just try to send data every 500ms.
Code: Select all
//USBReceive inner loop
      while (true)
      {
         //int b = dIn.readInt();
try{Thread.sleep(500)}catch(Exception e);
         dOut.writeInt(100);
         dOut.flush();
           LCD.drawInt((int)b,8,0,1);
      }

Then if I modify the USBSend on the pc to just receive then it all seems to freeze up and I get no data being sent by the NXT or received by the PC just a bunch of time-out's it seems.

It really appears like I need to receive data in the NXT before I can send data and while I can work around this by polling for data I really would like to send it asynchronously from the NXT.

Has anyone seen something like this before? suggestions?
RoboPAL
New User
 
Posts: 23
Joined: Sun Mar 09, 2008 10:26 am

Postby RoboPAL » Fri Mar 14, 2008 7:21 pm

Interestingly, it seems only the first readInt() is needed. After that I can send asynchronously. Not sure why that is but I can live with it for now
RoboPAL
New User
 
Posts: 23
Joined: Sun Mar 09, 2008 10:26 am

Postby RoboPAL » Sat Mar 15, 2008 8:42 am

I am still really struggling to create a reliable 2 way connection to exchange data in both directions. One thing I am finding is that immediately after programming the NXT the USB connection seems to behave differently as to when I restart the application by resetting the NXT and selecting the program from the menu list in the LCD.

For example the USBSend/USBReceive example immediately after programming usually returns very long numbers instead of echoing the correct numbers. It seems the buffer is shifted by a few bytes. When resetting the program it runs correctly echoing the integer sent.

Funny how writing these posts gives you ideas. I just added USB.usbReset(); before creating the USBConnection() and it fixed this problem and the data is exchanged correctly just after programming.

I wonder now if this will fix some other issues I have.. keep you posted.
RoboPAL
New User
 
Posts: 23
Joined: Sun Mar 09, 2008 10:26 am

Postby gloomyandy » Sat Mar 15, 2008 9:14 am

Some things that may help explain what you are seeing...
1. The current USB interface is not interrupt driven. All of the initialization/handshaking code is handled as a side effect of making calls to the read call. so if you don't call read then nothing will happen....
2. The USB connection (unlike Bluetooth), is not reset (by the firmware), when a program is run. So if your program uses USB and does not call reset then there is a chance you are picking up some data "left over" from the program download.

I have on my list of things "to take a look at" changes to the USB code to extend the packet size. I may also try and clean up the notion of a USB connection...

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 3881
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Postby RoboPAL » Sat Mar 15, 2008 8:45 pm

Thanks for the insights,

I have been working my way through the various source codes to find out what's going. I kind of got lost when I got into the JVM natives but it looks like the USB is handled as some sort of UDP? I will really have to roll up my sleeves if it comes to it but I am sort of getting there now.

It does seem quite unpredictable when it works. For example if I use USB.resetUSB() and try to use USB.usbRead/USB.usbWrite directly then on the PC side I get a no NXT found. Yet if I use it before a USBConnection and use the USBConnection Input/Output streams it clears the "left over" data and works ok. Looking at the source of USBConnection and USBInputStream/USBOutputStream it's not obvious why my attempt to use the USB raw terminated the USB connection.

Alot of my early attempts to make it work ( and I haven't got it fully working yet ) failed because of trying to use things like available() on the inputstream which is not supported. THis means you cannot look at the underlying buffer to decide when to do a read() so you are forced to enter a blocking routine to do a read()

Also the performance varies quite dramatically, as does including a sleep() in a loop that contains a USB read() but there may be a couple of things interplaying with each other confusing the issue.

A couple of questions
? How big is the underlying input buffer
? Is it possible to detect if the USB connector has been disconnected/reconnected.
RoboPAL
New User
 
Posts: 23
Joined: Sun Mar 09, 2008 10:26 am

Postby gloomyandy » Sat Mar 15, 2008 9:34 pm

The USB code is setup to use 64 byte packets... However the stream calls use 1 byte packets.

I don't think there is any easy way to tell if a connection has been established.

You may want to take a look at the debug class (on the nxt side) and the DebugMonitor tool (in the PCtools source tree), for an example of code that uses the lower level USB calls to send/rec data between the nxt and the PC.

Out of interest why are you using the USB connection rather than the Bluetooth connections? For most things using Bluetooth is a better option (noi wires!)....

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 3881
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Postby lawrie » Sat Mar 15, 2008 9:36 pm

I wrote most of the leJOS USB code, and it does need a lot of improvement.

UDP stands for USB Device Port and is nothing to do with the TCP/IP meaning of UDP.

The next only implements the device port protocol (UDP) not the host protocol. A host will try to "enumerate" a USB device connected to the bus. Only after this is sucessful will it recognise a device. This only works if you call usbReset and then call usbRead is a fairly tight loop.

The NXT supports a maximum USB packet size of 64 bytes.

There is currently no way of detecting a USB disconnection.
lawrie
leJOS Team Member
 
Posts: 909
Joined: Mon Feb 05, 2007 1:27 pm

Postby RoboPAL » Wed Mar 19, 2008 8:25 am

Just to clarify, the underlying input AND output buffers are 64 bytes. No shared buffer or anything like that.

I have managed to get it working pretty well now. Diconnecting and reconnecting the USB doesn't seem to upset the USB which is good. I also ported the USB communication driver to .NET so I can communicate without needing the JRE to be installed/configured. I haven't ported the programming protocol yet but I plan to do that too.

UDP - Ok that makes sense. I was thinking the tcp/ip meaning.

I will get to bluetooth next, this is to be used by others and I have had reports that bluetooth, while great when it works, can be difficult to get working in all situations so the USB is the reliable fallback and bluetooth the prefered method when available.
RoboPAL
New User
 
Posts: 23
Joined: Sun Mar 09, 2008 10:26 am


Return to NXJ Software

Who is online

Users browsing this forum: No registered users and 3 guests

more stuff