So! Progress has been made! I didn't expect this, but here we are.
The COM11 thing is resolved - Device Manager turns out to be remarkably intuitive and powerful, and let me reassign whatever-the-fuck it was on COM5 to COM11, and COM5 has now been set to be my Arduino board. So that's happy, even if it is a gotcha for running on any other machine. But fuck it, there's only one headband, how much can portability matter? (I fully expect to eat these words)
The other problem was Mono hating to do things with this Firmata library. My first thought was "Fucking threads, how do they work?". After understanding them a little more, I concluded they were most likely not to blame. Instead, I decided to blame it on Mono's SerialPorts module sucking big floppy donkey dick. More precisely, asking for port.BytesToRead on Windows will crash your program. Luckily Unity's crash report contains the Editor.Log, so I could painfully add debug statements and narrow down the problem. Then followed rewriting of the Firmata library code I had scavenged before. Before, the code was like this:
while(port.isOpen){
if (port.BytesToRead){
lock(this){
int data = port.ReadByte();
//do a buncha stuff with data
}
}
}
Now it's like this:
while(port.isOpen){
lock(this){
try{
int data = port.ReadByte();
//do the same buncha stuff
}
catch(TimeoutException) {
continue;
}
}
}
Which has the downsides of being a bit more retarded, and persisting the lock for stupid quantities of time. But has the upside of not crashing Unity to the ground every time it is run.
I also edited the constructors so that they default to not auto-starting the port. Unity seems to have the wonderful knack of calling constructors when in the Editor, so the serial connection was running every time, not just when the game was started. Now they only autostart when I pass in that option in Start() (Unity runs this when an object is first run in the gameworld.)
I also spent like an hour wondering why the existing headband vibrate-near-a-wall functionality which I wanted to show off wasn't wondering. Eventually I realized I was loading up an old, retarded version of the sketch. Good work, George! I also soldered a vibraton motor back on, as it had come loose. The wires coming from them are really thin, they don't have much strength in themselves. The whole prototype is flakey - wires fall out all the time. It's also an intimidating thing to put on someone's head. I'm all about accessibility, and I will admit that the way it looks now, it don't look inviting. Also, for non virtual-world use, it needs a battery pack.
Anyway, the Firmata-in-mono part seems to be working to some extent (there was some time before I got the baud rate the same on both ends). I have turned an LED on and off. And then when I tried to turn it on again, Unity appears to have died...
So, what next? Well, first thing, future George, is to set the timeout of waiting for a byte to be crazy short. It'll make that thread a lot snappier, and hence block the port for shorter periods of time. Next is to actually encapsulate the vibrating-a-patch-of-head thing, so I can forget this serial stuff exists.
Oh, and,
Tim who made Firmata.NET? Thank you for doing that. It's not your fault Mono is occasionally poopy. (Oh, and thank you Mono authors. I totally get why SerialPorts is a bit poopy, and I know that I should really go in and fix it. The trouble is, I can't change what runs within Unity, so this proper fix will only help me years from now... which doesn't seem as fun as moaning.)
(modified Firmata.NET)
Thu Oct 21, 2010