Friday 29 July 2016

Sending 'commands' from a micro:bit over Bluetooth

I got asked how you might use Bluetooth to send 'commands' from a micro:bit to another Bluetooth enabled device.

First read my blog on what kind of Bluetooth device can 'talk' to what kind of other device.

micro:bit has the concept of "events" which are things we can use as though they are numeric commands. An event has an ID and a value. Each are 16 bits in length so an event is a total of 32 bits long.

The micro:bit has something called the Event Service and this allows events to flow in either direction between the micro:bit and something else like a smartphone.

The Microsoft PXT tool lets you create your own event values and trigger them from anything you like in your code.

So these are our basic ingredients.

Let's walk through an example.

First, check out this application I created in PXT


You can fork the code itself here: https://makecode.microbit.org/_PUaidt6ub1Rm

You can see I create an event ID of 9010 and two associated event values of 1 and 2. I also keep track of whether or not we have a Bluetooth connection in a variable called 'connected'

Then, if the user presses button A we create an event with ID 9010 and event value 01. If the user presses button B we create an event with ID 9010 and event value 02.

That's all we need to do on the micro:bit side of things.

On the other device we have to send the micro:bit the event ID and values we're interested in being notified about if they occur.

Here's what the micro:bit Bluetooth Event Service looks like. It will help when we look at how to test this code from a smartphone next.


The blobs are called "characteristics" and they're like data items or variables that have particular purposes. Client Requirements contains a list of one or more event IDs and event values that the client (i.e. the other device) has said it's interested in. MicroBit Event contains the event ID and value of the most recent event that has happened on the micro:bit.

There's a great smartphone app for Android and iOS that lets you explore and test Bluetooth communication called nRF Connect. I'll walk through how I tested my PXT code using screenshots to illustrate:


Note: I've paired my micro:bit and phone. This is essential as at the time of writing both PXT and the microbit.co.uk tools produce code which requires your micro:bit to be paired if you're going to use Bluetooth. Here's how to pair with an iOS device and here's how to pair with Android.

There's nRF Connect on my Android phone. I launch it and it automatically scans for advertising Bluetooth devices and finds my micro:bit.


I click CONNECT to have the phone connect to the micro:bit.This gives me the next screen which shows the Bluetooth services on the micro:bit. Most were custom designed for the micro:bit so nRF Connect does not know their names.


The UUIDs are unique identifiers. The highlighted one is the event service. You can see the UUID shown here is the same as the one in the Event Service graphic above. Selecting the service causes it to expand so we can see its characteristics:


The two we're interested in are highlighted in green. 9775 is the MicroBit Event characteristic. 23C4 is the Client Requirements characteristic. The next job is to write to the Client Requirements characteristic using nRF Connect. This will transmit the value we enter to the micro:bit, effectively saying "Hey, if one of these events happens, please tell me". You start a Write operation by selecting the upwards pointing arrow icon next to the characteristic and this causes a dialogue to appear:


The second field is a drop down data type selector. I have it set to BYTE ARRAY. The value is in hex and needs some explanation. The first two bytes are the event ID of 9010. The second is the event value but 0000 means "any event values with the specified event ID". 9010 is not 0x3223 in hex though, it's 0x2332! micro:bit, in common with many other devices likes its data to arrive or be sent over comms links in 'little endian format'. So the least significant bytes come first as we read left to right and this is why we're sending 0x3223.

Now that the micro:bit knows what we're interested in, we also have to switch on "notifications" relating to the MicroBit Event characteristic. This just tells Bluetooth on the micro:bit to send the phone a message if its value changes. And it will change if one of the events we just said we were interested in happens.


Notifications are enabled by selecting the icon with multiple downward pointing arrows next to the MicroBit Event characteristic as shown.

All that's left now is to test! Pressing first button A and then button B causes the value of the MicroBit Event characteristic to change as the data is received over Bluetooth from the micro:bit. Your own code on a phone or other Central mode Bluetooth device could respond to these events anyway you choose.


That's the result of pressing Button A. Event ID 0x3234 (9010) and Event Value 0x0100 which of course is ID 9010 and value 01 in little endian format.

And button B produces....


the same result but this time the value is 02.

Simples!

Code it. Connect it. Bitty Software.

2 comments:

  1. Great blog post, thanks! I'm hoping to use the microbit over bluetooth to send accelerometer / button press data, like you have in this tutorial, but I want to receive the data directly to my raspberry pi over bluetooth, using python. Any tips on how to get started? I think I could manage the python stuff with pybluez but not sure what I need to do to get the microbit to send out its state over bluetooth.

    ReplyDelete
    Replies
    1. Hi Andy Pi

      sending accelerometer data, button state changes etc over Bluetooth is easy peasy.... as long as you don't create your micro:bit code using any of the code editors at microbit.co.uk. You're limited to using the event service and not much more with those editors and even then are very restricted as to what you can do.

      To expose the state of buttons, accelerometer, magnetometer and more, you need to include the corresponding Bluetooth services in your micro:bit code. The easiest way to do this is to use the Microsoft PXT tool at https://www.pxt.io and just drag and drop service blocks from the Bluetooth tray (Go into More/Add Package and choose Bluetooth to make this visible). Alternatively, use C/C++ using mbed (see http://bluetooth-mdw.blogspot.co.uk/p/bbc-microbit.html#mbed_ble) or Yotta for offline work.

      The entire Bluetooth profile and the micro:bit API to it is explained here: https://lancaster-university.github.io/microbit-docs/ble/profile/

      A sample micro:bit application which I contributed, and which shows how to add all the Bluetooth services (more or less) is in the microbit-samples repo here:

      https://github.com/lancaster-university/microbit-samples/tree/master/source/examples/bluetooth-services

      If you're working with Pi and not averse to using node.js rather than Python, you might want to check out this module:

      https://github.com/sandeepmistry/node-bbc-microbit

      Finally, Bitty Software have a growing list of resources you might want to check out:

      http://www.bittysoftware.com

      Hope this helps

      Martin

      Delete

Note: only a member of this blog may post a comment.