Donnerstag, 29. März 2012

Control a LEGO NXT brick from a smartphone using AppInventor

Dear lovers of embedded electronics!

Today, as I was on duty for tech support, I had lots of time to try something new. Being equipped with a Samsung Galaxy S i9001 smartphone, I told myself that it must be possible to connect the thing to a LEGO Mindstorms NXT programmable brick via a Bluetooth Serial Port Profile (SPP) connection. As I'm not really deep into Android programming yet, I wanted to use MIT's AppInventor (download local component for Windows here) to create a control application for the phone. I intended to let my app read the orientation sensor's values and use them to set the output power for some motors accordingly.
First, I paired the NXT with my phone using the Bluetooth system settings panel. This step is neccessary, as pairing new devices is impossible from inside an app. The NXT got two motors connected to ports B and C.
Second, I created my app's screen in the AppInventor. To control the NXT, I had to add a BluetoothClient and an NxtDrive. The NxtDrive uses the BluetoothClient to communicate with the NXT, so the NxtDrive must be told which instance of BluetoothClient to use within the screen designer! Then there's the OrientationSensor the measure how your phone is tilted at the moment.
I also added three labels to display the orientation values and a list picker. The list picker is used to connect to a specfic Bluetooth device via SPP. As I said, the device must be paired outside the app. The SPP connection itself is created from within the app.
So here's a screenshot of my very simple screen layout:
NXT control screen layout
NxtDrive property rollout: Note that the value of "BluetoothClient" is set to "BluetoothClient1"
Now it's time to switch to the Blocks Editor. Let's configure the list picker first. When I press it, it should show me a list of all paired devices, from which I can pick my NXT to connect to. Here's the program:
Somehow it's neccessary to save the result of the call to BluetoothClient1.Connect in a variable, so that's what I did here, but I don't use the result anywhere.
Finally, the orientation values have to be read continuously and the motor power has to be set accordingly. I just use the "roll" readings and adjust for signedness, as I don't know whether MoveForwardIndefinitely can take any negative values for its power setting. So, if the "roll" value is negative, I tell the NXT motors to rotate backward, otherwise, they'll have to move forward (whatever that means...). I also update the labels to show the orientation values.
Here's what it looks like:
Last, but not least, here's a video showing you how to operate the app: