Lego NXT -- NXC blocking bluetooth IO

I’ve been working on a remote-controlled robot using Lego Mindstorms NXT, NXC, and Perl. It is working well for now, but it is polling the bluetooth device for new data.

In NXC, is there any way to do blocking IO on the bluetooth device?

Thank you for any help.

It’s been a while since I’ve used nxc, but couldn’t you just put the bluetooth function in a while loop?

That’s what I have, but that is still polling, not blocking IO.

I suspect that the bluetooth chip itself has to be polled, so I probably have no choice but to keep polling it.

I do a Yield() in the loop (if no data has been returned yet), so I guess I’ve done the best I can.

I believe that the NXC firmware is based on the LEGO FW, and the scheduling in that FW is done statically. The I/O drivers run once per millisecond and the VM is guaranteed to not be running during that period. This simplifies the protection mechanisms.

The user level code that meshes well with this is to poll and if not arrived, sleep 1 millisecond. There would be slightly less overhead if the BT driver had a notification mechanism, but it is pretty capable as long as there is a delay. A slightly better guess is to sleep the appropriate time based on the amount being transferred. Does yield in NXC take a parameter, or is there a better way to sleep a controlled amount?

Greg McKaskle

There’s a millisecond wait command, which I assume also yields the processor.

I have not changed the firmware (probably should’ve made it clearer). I am running version 1.05 (I know it’s old, I have seen no reason to update).

I guess I’ll just poll it, and change the wait to 1 millisecond, now that I know more.

Thanks for the info.

I’m not sure when the LEGO FW was able to sleep efficiently, but I think it was 1.28 or so. Before that, the sleep may very well be a busy loop as well.

Greg McKaskle

I spent a couple hours debugging an issue where threads would randomly crash on it. I thought it could be a race condition, but only two variables are shared between threads, and reads/writes are atomic (boolean).

I then found the -safecall option to nbc. This fixed it.

From now on, my code will have to grab a mutex just to run. I hope Wait() is multithread-safe, but if it isn’t, I can write my own (I assume Acquire, Release, and Yield are threadsafe).

Thank you.

EDIT: It’s been running fine for a while now, so I thinkk Wait() is threadsafe.

EDIT2:
I am running into another weird bug. If I run 4 threads (I don’t know about numbers larger than four) and use a mutex (in only two of the threads), I get a delay in the bluetooth reception. The code doesn’t slow down, but the controls run with a delay.

I can’t edit it, so I’ll post that I’ve found the problem.

The fourth loop was pushing it just enough to make it take over 50 ms, so the messages were being buffered for some amount of time.