Thursday, March 29, 2012

How to use BlueMesh Tutorial

This post is a basic tutorial on how to use BlueMesh in your own android project.  Source code for this tutorial was taken from WebViewHost and WebViewTest.

To begin, you can consider the BlueMeshService object both a device for input and output.  This object provides functionality for both reading data from all devices on the BlueMesh network and writing data to all devices on the BlueMesh network.

As a prerequisite to using BlueMesh, a device should enable Bluetooth and pair with other devices.  It is not necessary to be paired with all devices that are going to be on the network, but there should be a path from every device to every other device via Bluetooth pairs.

The first thing that needs to be done when using BlueMesh is create a BlueMeshService object.
try{ bms = new BlueMeshService(); } catch(NullPointerException e){ Log.e(TAG, "Bluetooth not enabeled"); return; }

It is important to note that the BlueMeshService() constructor throws a NullPointerException if Bluetooth is not enabled.  If this happens it means that the constructor failed and you should not proceed, rather you should either end the program, or attempt to enable Bluetooth and try again.

If the constructor completes successfully, it is then time to call launch().  launch begins the Bluetooth communications (listening for other devices running the same app to connect to) and allows you to use the IO functions.
bms.launch();

Now that BlueMesh is running it is time to use the IO functions.  Remember that the UI thread must complete in order to render any graphical display, so it is recommended that BlueMesh IO is preformed in a separate thread.

The following code block shows how to set up a button to send data over BlueMesh.  The write(byte[]) function takes one argument, a byte array, and sends it to all devices on the network.  In this example slides is an ArrayList of Strings.
//button listener send final Button buttonSend = (Button) findViewById(R.id.btnSend); buttonSend.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if( bluetoothWorking ){ bms.write(slides.get(currentSlide).getBytes()); } } });

In order to read data, use the byte[] pull() function.  This function will return a byte array containing a received message on success and null if there is no message to receive.  This call is non-blocking and will return immediately, please note that it is not recommended that this function be called instantly over and over again in a read loop without a small sleep between attempts.

The following code block shows how to create a read thread the polls the BlueMeshService object for incoming messages.  In this example, the read thread passes messages to the UI thread via Handler mHandler.
private final Handler mHandler = new Handler(){ @Override public void handleMessage( Message msg ){ byte[] byteMessage = (byte[]) msg.obj; String stringMessage = byteMessage.toString(); //Here you can do UI with the message } }; private class ReadThread extends Thread { public void run(){ Looper.myLooper(); Looper.prepare(); while (true){ if( this.isInterrupted()){ Log.d(TAG, "readThread interrupted"); return; } byte bytes[] = null; bytes = bms.pull(); if( bytes == null){ //Sleep if nothing is received to avoid //pounding bms try { sleep(100); } catch (InterruptedException e) { Log.e(TAG, "sleep() failed", e); } } else{ mHandler.obtainMessage (0, bytes.length, -1, bytes) .sendToTarget(); //Here you could process the message //and send a response } } } }

Now that your program can read and write over BlueMesh the only thing that remains is shutting down communications.  This requires a simple call to disconnect() which can be run as the program shuts down.
@Override public void onDestroy(){ super.onDestroy(); readThread.interrupt(); bms.disconnect(); }

Hopefully you enjoyed this simple tutorial on BlueMesh and will be able to develop your own apps.  If you have any questions please email me at schnej7@rpi.edu.

5 comments:

  1. Hello.

    You have written about call blocking while bluemesh is used. Is it android limitation, your program limitation or h/w platform limitation?

    Can I hope that it will be solved in the future?

    ReplyDelete
  2. Hey shura0,

    I'm not exactly sure which calls you are talking about, BlueMesh has a constructor and 4 functions. You can read about the API here https://github.com/schnej7/Blue-Mesh/wiki/API. All of those 5 functions are non-blocking (they all return immediately). I hope this answers your question, please feel free to ask more about how BlueMesh works too.

    Jerry

    ReplyDelete
  3. Hi, Jerome.

    Maybe here is some misunderstanding.
    Your presentation:
    https://github.com/schnej7/Blue-Mesh/blob/951fcc550a4e195eedc775c17a7a7724729469b5/Presentations/RCOSBlueMesh2.pptx
    slides 7 and 9. "bluetooth blocking call" and "lots of blocking calls."
    What do you mean? I understand it as "when this program is running there is impossible to make or receive phone calls" Am I right?

    ReplyDelete
  4. shura0,

    There is definitely a misunderstanding. When I refer to "calls" I am talking about "function calls" not "phone calls". There is nothing in my project or in Bluetooth that will block phone calls.

    What i was referring to is when you use some of the Android Bluetooth function calls, your program has to wait until the function completes. This was a challenge for developing BlueMesh, however we have addressed all of those problems.

    I hope this answers your question,
    Jerry

    ReplyDelete
  5. Thank you, now everything is clear

    ReplyDelete