Ok, I've got what seems to be a solution. If you don't want to wade through the process I used to get there, skip to the bottom.
First some cultural enrichment (obviously not for Mr. Swan - but perhaps useful to some FTC kids):
The description of Bluetooth on the NXT and the interface (aka API) for the Fantom.dll can be found in the software development kit here:http://mindstorms.lego.com/en-us/suppor ... fault.aspx
Fantom.dll is library of functions useful for communicating to a NXT over Bluetooth or USB. It is written by National Instruments and uses some of their VISA or VXI interface libraries also. I'm willing to believe it doesn't really need to be this complicated.
Using the Fantom.dll, you can write programs that discover what NXTs are in the neighborhood (on USB or BT) and send them commands, or reprogram their firmware, or load files on, etc.
The functions are things like (names simplified to protect the innocent):
CreateIterator -- get a list of NXTs you can talk to. If you have a BT paired one, you will get it even if it is off.
GetName -- get the "BTH::Hacksaw::00:16:53:06:A8:DC::5" sort of name
isPaired -- Is the NXT already paired with Windows? (i think it just checks if there is a ::5 com port suffix on the name)
pairBluetooth -- Do the same thing as "Add" in the Bluetooth control panel (almost: it only sets up the outgoing COM port). Note this actually uses the bluetooth control panel, bthprops.cpl via OLE automation (i think).
getNXT -- This gets an object that can be used to send NXT commands, transfer files, etc. After you call it, you will see the "<>" symbol in the bluetooth display on NXT.
sendDirectCommand -- for example, make it beep
createFile -- make a file on the NXT - same as API exposed for same in RobotC pretty much.
There are others, but these are in the example C++ program in the documetation of the fantom.dll referenced above.
A couple of notes about using the example:
If you want to use Bluetooth, change the false to true in the CreateIterator and make the timeout not 0. 3 still seemed too short, but 5 works for me.
The help files say something like this for most of the functions: "The pairing is not done if the specified status is fatal".
That isn't awkward engineerspeak for "If it fails, we didn't do it". It really means if the status parameter you pass in already has an error code in it, then this function will return without doing anything. I think the intention of that is that you could string a big sequence of Fantom functions together and if the first on fails, the others won't bother to try. This alleviates the need to check the return status of every function, but also makes it so when you get to the bottom and you have a failure status, you have no clue which function was the one that failed. You can status.clear() to get rid of the error number so status can be passed in to a new function.
A good example of this "feature" is when you get an Iterator for your NXTs in range, and then Advance() through the list until you reach the end. At that point, your status variable will have an error code in it that means you reached the end of the list. If you re-use that status variable without status.clear() ing it, then subsequent functions won't attempt to do anything.
The Fantom.dll functions return 3 categories of error status values. Some are described in tStatus.h:
//! Error: Bluetooth pairing operation failed.
//! Warning: You have already paired with that Bluetooth device.
kStatusPairingFailed = (kStatusOffset + -5), // 0x54B
others are in the NI VISA Programmer Reference:
I ran more or less the example fantom program right out of the help file, and it works OK on one of my computers and not on the other. As when using RobotC, the bad one ONLY works if I manually Remove the NXT from Bluetooth ControlPanel and Reset BT and trash My Contacts on the NXT.
In my case, on my troublesome computer (Dell D410 XP SP2), I notice 2 things:
From the Unpaired condition, a pair() call will go through the "found new hardware" noise in the system tray, and it will return a 0 status (ok), but if I don't wait a few seconds after that before re-creating the Iterator and calling getNXT, then getNXT will fail with error 0xBFFF0000, which means "Unknown system error (miscellaneous error)." which I don't find particularly illuminating.
On a subsequent run, from the Paired condition (whether paired using the Fantom pair() function, or using the bluetooth control panel), the Iterator works fine, but getNXT fails with 0xBFFF0000.
So, at this point, we have reproduced the problem I see in RobotC without using RobotC at all. (I am getting a different error number than reported by RobotC, but I can imagine a lot of reasons that might be the case).
I did not achieve my goal of understanding exactly what
gets out of sync or whatever.
This led to questions about versions of the pertinent DLLs, but I found them to be the same on both machines:
fantom.dll -- 220.127.116.11152
visa32.dll -- 18.104.22.168152
NiViAsrl.dll -- 22.214.171.124152
NiViUsb.dll -- 126.96.36.199153
(note: I didn't think to check the NiVi...dll file versions until later - so I'm not 100% sure this is what was there at the beginning).
Both machines had the same version of Microsoft Bluetooth drivers:
bluetooth enumerator 5.1.2600.5512
bluetooth radio 5.1.2600.5512
So I wondered if NXT-G would have this same problem with Bluetooth communication. I installed NXT-G from the disk that comes with the FTC kit this year, and voila, my example Fantom client program works. Works starting from unpaired state, paired by ControlPanel, and paired by Fantom pair() function.
The versions installed with NXT-G are:
fantom.dll -- 188.8.131.52153
visa32.dll -- 184.108.40.206152
NiViAsrl.dll -- 220.127.116.11152
NiViUsb.dll -- 18.104.22.168152
The dates on these are in 2007.
1. Something is wrong with the NI dll's that causes a getNXT to fail if already paired (on some machines).
2. It has been fixed for a couple years, and Lego is currently shipping the fixed version.
Mentor, FTC Team 1001
p.s. i posted the example project with Visual Studio 2008 project files as an attached .zip file (in case anyone wants to tinker).