12 Replies Latest reply on Apr 20, 2016 7:48 PM by yuanll

    Bluetooth communication between custom Android app and Edison in Python

    Frederick Blais

      When I first got my Edison, I installed  Ubilinux and tried to get Bluetooth working with Android. I managed to get it to work but it was not really stable. Since then, Intel worked on Edison Bluetooth profiles and SPP was correctly tested and implemented in software release 2.0 (we are at 2.1 right now). So everybody with version 2.0 and higher of Yocto firmware should be able to get this to work.

       

      In the Bluetooth User Guide ( http://download.intel.com/support/edison/sb/edisonbluetooth_331704007.pdf ) Intel demonstrate how to communicate with an Android phone using a Bluetooth terminal application (like Bluetooth SPP Pro). It is interesting, but what if you would like to create a custom Android app that can communicate with your Edison? This is what I woud like to demonstrate today.


      The first thing to do is to pair and connect with your phone. The steps are outlined here : https://software.intel.com/en-us/articles/intel-edison-board-getting-started-with-bluetooth

      There is something really important you should do in Bluetoothctl : you should trust the device. When the device is trusted, you can accept new SPP connection without having to always accept them by typing yes in the terminal with the keyboard agent. To do this, execute "trust <Device ID>"


      After this, you are ready to code. Intel wrote the SPP-Loopback.py script and it works really well to establish a connection between the phone and the Edison. However, there is a lot of ugly code that I would like to hide in the file, so I created an hooks.py file that is imported by SPP loopback. Here is what the hooks file looks like :


      import subprocess
      import mraa
      
      
      LED = mraa.Gpio(13)
      LED.dir(mraa.DIR_OUT)
      
      
      version = subprocess.check_output(["configure_edison","--version"])
      count = 0
      
      
      def init(s):
          print("Connected!")
          s.send(version)
      
      
      def loop(s, data):
          global count
          print data
          count+=1
          s.send(str(count))
          if data == "ON":
              LED.write(1)
          elif data == "OFF":
              LED.write(0)
          else:
              pass
      
      
      def close(s):
          global count
          count = 0
          print("Bye!")
      


      On the Edison Python side, what I do is watch for a new connection and send the Edison version. Each time I receive data, I increase the count value, and turn an LED on or off depending on the data received (on-board LED on the Arduino breakout board). When the connection is closed, I reset the count.


      The Python file is pretty simple and it can be modified without having to change SPP.py (These 2 files are included in the post in Code.zip)


      For the Android part, it is a little bit more involved (at least for me because I'm a beginner with Android Developement).

      The Application was done with Android Studio (project included BluetoothEdison.zip).

       

      There is four buttons in the app (CONNECT, ON, OFF, CLOSE)

      CONNECT : when it is pressed, it looks for a paired deviced called "edison" and create a socket connection on it from the standard SPP uuid. When it is done, it writes the Edison version number in a text field.

      public void connect(View view){
              pairedDevices = Adapter.getBondedDevices();
      
      
              for(BluetoothDevice bt : pairedDevices) {
                  if(bt.getName().equals("edison"))
                      Device = bt;
              }
              Log.d(TAG, "Address: " + Device.getAddress());
              Log.d(TAG, "Name: "+Device.getName());
      
      
              try {
                  BluetoothSocket Socket = Device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"));
      
      
                  if (!Socket.isConnected()){
                      Socket.connect();
                      Log.d(TAG, "Connected");
                  }
      
      
                  outStream = Socket.getOutputStream();
                  inStream = Socket.getInputStream();
      
      
                  String v = read(); //Get version from Edison
                  Version.setText("Version: "+v);
                  Count.setText("Count: 0");
      
      
              } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
          }
      


      ON : send the string "ON" to the Edison to turn on an LED

          public void on(View view) throws IOException {
              String msg = "ON";
              if (outStream == null) {
                  Log.d(TAG, "You have to connect");
                  return;
              }
      
      
              try {
                  outStream.write(msg.getBytes());
              } catch (IOException e) {
                  e.printStackTrace();
              }
              Log.d(TAG, "LED ON!");
      
      
              String c = read(); //Get count from Edison
              Count.setText("Count: " + c);
          }
      


      OFF: send the string "OFF" to the Edison to turn off an LED

          public void off(View view) throws IOException {
              String msg = "OFF";
              if (outStream == null) {
                  Log.d(TAG, "You have to connect");
                  return;
              }
      
      
              try {
                  outStream.write(msg.getBytes());
              } catch (IOException e) {
                  e.printStackTrace();
              }
              Log.d(TAG, "LED OFF!");
              String c = read(); //Get count from Edison
              Count.setText("Count: " + c);
          }
      


      CLOSE: Disconnect the socket, input and ouput stream.

          public void close(View view) {
              if (inStream != null) {
                  try {inStream.close();} catch (Exception e) {}
                  inStream = null;
              }
      
      
              if (outStream != null) {
                  try {outStream.close();} catch (Exception e) {}
                  outStream = null;
              }
      
      
              if (Socket != null) {
                  try {Socket.close();} catch (Exception e) {}
                  Socket = null;
              }
          }
      


      each time ON or OFF is pressed, the phone receive an incrementing count value that is written in a text field.


      In the project, don't forget the bluetooth permission in the manifest file

      <uses-permissionandroid:name="android.permission.BLUETOOTH"/>

      Also, don't forget to add the onclick event to the buttons like this :

      android:onClick="close"


      Here is what it looks like :

      Screenshot_2015-06-30-09-14-38.png


      All the code to do this is included in the post.

       

      If you have trouble to make this works, I'm here to help.

       

        • 1. Re: Bluetooth communication between custom Android app and Edison in Python
          Santogolde

          Hi Frederick Blais,

          I tried your Android app on my Samsung Ace 4 with my edison on an Arduino Board, but I have the following problems :

           

          - when I press "Connect" :

          Screenshot_2015-07-20-13-54-51.png

          So I change the BluetoothActivity program so it would only print "connected" when connected.

           

          When I press "ON" or "OFF" :

          2.png

           

           

          When I press again "ON" or "OFF":

          3.png

          And if I press again "ON" or "OFF" the program freeze.

           

          But the LED is never turn on or off.

          Would you have any idea why it doesn't work?

           

          Thank you for your help.

          • 2. Re: Bluetooth communication between custom Android app and Edison in Python
            Frederick Blais

            Santogolde

             

            At least, something works because the Edison sent a string back to your Android phone.

             

            it looks like you are not running my version of SPP loopback. Are your running the SPP.py included in my code.zip file?

            • 3. Re: Bluetooth communication between custom Android app and Edison in Python
              Santogolde

              It's finally working!

              You were right, the SPP.py wasn't running on the Edison.

              Thank you for your help.

              • 4. Re: Bluetooth communication between custom Android app and Edison in Python
                barbin04

                How's it going Frederick Blais and Santogolde,

                I am having some severe issues on getting the edison to connect to the android. I connect the edison to the android phone with bluetoothctl, no problem. however running the app to receive data from the arduino is not working.

                The following snippet is my uuid information for the edison. which uuid should i be using in the python code and also in the java code to get it to connected?

                edison uuid.PNG

                This is the edison python code, what exactly should i be inputting in each of the options ? maybe this is the issue?

                com4-putty.PNG

                In the java code I inputted the PnP Information uuid and I am having the following error. which would be the correct uuid to use?

                Also this is the error timeout that is occuring when i press the connect button on the app:

                11-16 11:47:04.968    8519-8534/com.example.fred.bluetoothedison I/OpenGLRenderer﹕ Initialized EGL, version 1.4

                11-16 11:47:12.976    8519-8519/com.example.fred.bluetoothedison D/BluetoothActivity﹕ trying to look for devices

                11-16 11:47:12.977    8519-8519/com.example.fred.bluetoothedison D/BluetoothActivity﹕ Address: 98:4F:EE:03:45:84

                11-16 11:47:12.978    8519-8519/com.example.fred.bluetoothedison D/BluetoothActivity﹕ Name: edison

                11-16 11:47:12.978    8519-8519/com.example.fred.bluetoothedison D/BluetoothActivity﹕ connecting the uuid: 00001200-0000-1000-8000-00805f9b34fb

                11-16 11:47:12.981    8519-8519/com.example.fred.bluetoothedison W/BluetoothAdapter﹕ getBluetoothService() called with no BluetoothManagerCallback

                11-16 11:47:15.766    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ java.io.IOException: read failed, socket might closed or timeout, read ret: -1

                11-16 11:47:15.768    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:684)

                11-16 11:47:15.768    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ at android.bluetooth.BluetoothSocket.readInt(BluetoothSocket.java:696)

                11-16 11:47:15.768    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:373)

                11-16 11:47:15.768    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ at com.example.fred.bluetoothedison.BluetoothActivity.connect(BluetoothActivity.java:102)

                11-16 11:47:15.768    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ at java.lang.reflect.Method.invoke(Native Method)

                11-16 11:47:15.768    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ at android.view.View$DeclaredOnClickListener.onClick(View.java:4447)

                11-16 11:47:15.769    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ at android.view.View.performClick(View.java:5198)

                11-16 11:47:15.769    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ at android.view.View$PerformClick.run(View.java:21147)

                11-16 11:47:15.769    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ at android.os.Handler.handleCallback(Handler.java:739)

                11-16 11:47:15.769    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:95)

                11-16 11:47:15.769    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ at android.os.Looper.loop(Looper.java:148)

                11-16 11:47:15.769    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5417)

                11-16 11:47:15.769    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ at java.lang.reflect.Method.invoke(Native Method)

                11-16 11:47:15.769    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)

                11-16 11:47:15.769    8519-8519/com.example.fred.bluetoothedison W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

                 

                Please help!

                • 5. Re: Bluetooth communication between custom Android app and Edison in Python
                  Songer

                  Hi there,


                  Great post, but I am wondering if there is any way to modify SPP-loopback as a module rather than the main program?



                  • 6. Re: Bluetooth communication between custom Android app and Edison in Python
                    Frederick Blais

                    Hello Songer,

                     

                    I tried but with no success.

                    • 7. Re: Bluetooth communication between custom Android app and Edison in Python
                      yuanll

                      hi

                         how can i get your app? I download your BluetoothEdison.zip ,I extract it ,but I haven't see a app for android.Or the BluetoothEdison.zip is just a tool to product apps?If is ,how can I launch it?

                      • 8. Re: Bluetooth communication between custom Android app and Edison in Python
                        yuanll

                        hi,Frederick

                              Since i hadn't any erperience at Andriod Development,could you post the Andriod apk ? So I can download it and  install it on my Andriod phone,thanks very much.

                        • 9. Re: Bluetooth communication between custom Android app and Edison in Python
                          Frederick Blais

                          Hi,

                           

                          you will have to download the Android Studio and compile it for your particular version of Android. There is really no need in using this app if you don't plan to modify it.

                           

                          Fred

                          • 10. Re: Bluetooth communication between custom Android app and Edison in Python
                            yuanll

                            hi,Frederick

                                   Thanks very much for  your reply,I will try it.

                            • 11. Re: Bluetooth communication between custom Android app and Edison in Python
                              yuanll

                              hi,Frederick

                                    Another question,all the programme aboveis based on the Python.Is there another language such as c/c++ to do this above.And the test-profile( where to find http://git.kernel.org/cgit/bluetooth/bluez.git/tree/test) in  edison bluetooth pdf  is also a Python  script. Can I find the example programme such as the SPP-Loopback.py somewhere?

                              • 12. Re: Bluetooth communication between custom Android app and Edison in Python
                                yuanll

                                Can I find the example programme such as the SPP-Loopback.py somewhere but use C /C++ language