понедељак, 27. фебруар 2012.

Arduino and Android parking assistance 2 (ANDROID communication part )


Hi guys,

hope you have enjoyed reading our last post about „Matrix led display controlled by Arduino and Android - the coding part“. Now we want to build on the previous post about Arduino and Android parking assistance. Just now we’ll talk about Android Parking assistance app. As we could see in  previous post how look like Android app interface,  in this post we’ll describe how were implemented bluetooth protocol.

We all know Android is very popular now, especially ADK (Android Open Accessory Development Kit), which allows external 0pen source hardware to connect with Android system by USB and interact with an Android-powered device in a special “accessory” mode.
To make the communication between Android and Arduino easy, we would like show you a new way that android interact with Arduino and other similar boards. Bluetooth for example.

Step one: Make a APP to Android which could communicate with other devices by bluetooth.
Step two: Android APP connect to Arduino by Bluetooth Mate Silver.

This APP allows Android connect to each other by bluetooth, so you need at least two Android devices for this app.

Bluetooth

            The Android platform includes support for the Bluetooth network stack, which allows a device to wirelessly exchange data with other Bluetooth devices. The application framework provides access to the Bluetooth functionality through the Android Bluetooth APIs. These APIs let applications connect wirelessly to other Bluetooth devices, enabling point-to-point and multipoint wireless features.

The Basics

All of the Bluetooth APIs are available in the Android bluetooth package. Here is a summary of the classes you will need to create as below.

ü  BluetoothAdapter: Represents the local Bluetooth adapter (Bluetooth radio)
ü  BluetoothDevice: Represents a remote Bluetooth device, query information such as its name, address, class, and bonding state.
ü  BluetoothSocket: Represents the interface for a Bluetooth socket (similar to a TCP Socket).
ü  BluetoothServerSocket: Represents an open server socket that listens for incoming requests (similar to a TCP ServerSocket).
ü  BluetoothClass: Describes the general characteristics and capabilities of a Bluetooth device.

Bluetooth Permissions

                In order to use Bluetooth features in your application, you need to declare at least one of two Bluetooth permissions: BLUETOOTH and BLUETOOTH_ADMIN.
Declare the Bluetooth permissionin your application’s AndroidManifest.xml as below.

AndroidManifest.xml
<manifest ... >
  <uses-permission android:name="android.permission.BLUETOOTH" />
  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
  ...
</manifest>
Let us see some code, really start from here. In order to connect by bluetooth, there should be four steps as below:
  • Setting Up Bluetooth
  •  Finding Device
  •  Connecting Device
  •   Managing Device


Setting Up Bluetooth

We made the App include eight java files. For now, we only need to use:

·         Main.java,
·         DiscoveryActivity.java
·         ClientSocketActivity.java

Before your application can communicate with Bluetooth, you should verify Bluetooth is supported on the device and make sure that it is enabled. If Bluetooth is not supported, you should gracefully disable any Bluetooth features. If Bluetooth is supported, but disabled, you are able to request the user enable Bluetooth without leaving your application. So, at Main.java in Tab Settings we get five buttons, as below:

  Select “Enable Bluetooth” button make the device’s own Bluetooth adapter (the Bluetooth radio) working. There is one Bluetooth adapter for the entire system, and your application can interact with it when it is open.


public BluetoothAdapter _bluetooth = BluetoothAdapter.getDefaultAdapter(); 
...
public void EnableBluetooth(View v)
{
                Toast.makeText(this, "Bluetooth enable", Toast.LENGTH_LONG).show();
                _bluetooth.enable();  
               
                Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                startActivityForResult(enabler, REQUEST_DISCOVERABLE);
                               
}

/*
   There are two ways to enable bluetooth
1)
   Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
   startActivityForResult(enabler, REQUEST_DISCOVERABLE);
2)
   _bluetooth.enable();
*/




Create a new Intent as  
“Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)”, a dialog box will appear and request user permission to enable Bluetooth. Select “Yes” and the system will enable Bluetooth and focus will return to your application once the process completes.

            You need to ensure that Bluetooth is enabled and allowed other devices could discover it. Add the below code, and a dialog box will appear also, you should click “Yes”.
A part of code for each button activity in Main.class as bellow:

Main.java
public void openBluetooth(View v)
    {
       Toast.makeText(this, "Bluetooth enable ...", Toast.LENGTH_LONG).show();
       _bluetooth.enable();      
       Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
              startActivityForResult(enabler, REQUEST_DISCOVERABLE);
             
    }

       public void closeBluetooth(View v)
    {        
             ........

       _bluetooth.disable();
       Toast.makeText(this, "Bluetooth disable ...", Toast.LENGTH_LONG).show();
      
              ........
    }
   
    public void searchDevices(View v)
    {
       Intent search = new Intent();
       search.setClass(c, DiscoveryActivity.class);
       startActivity(search);
    }
   
    public void openClientSocketButton(View v)
    {
       Intent enabler = new Intent(c,ClientSocketActivity.class);
       startActivity(enabler);
    }




Finding Device

            With Discovery Activity.java file, we will find around device. The process is asynchronous and the method will immediately return with a boolean indicating whether discovery has started successfully. The discovery process usually involves an inquiry scan of about 12 seconds, followed by a page scan of each found device to retrieve its Bluetooth name. Your application must register a BroadcastReceiver for the ACTION_FOUND. Intent in order to receive information about each device discovered.

/* Register Receiver*/
IntentFilter discoveryFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(_discoveryReceiver, discoveryFilter);
IntentFilter foundFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(_foundReceiver, foundFilter);

/**
 * Receiver
 * When the discovery finished be called.
 */
private BroadcastReceiver _foundReceiver = new BroadcastReceiver()
{
       public void onReceive(Context context, Intent intent) {
       /* get the search results */
       BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
       /* push in ArrayList */
       _devices.add(device);
       /* show the devices list */
       showDevices();
       }
};

private BroadcastReceiver _discoveryReceiver = new BroadcastReceiver() {
              @Override
       public void onReceive(Context context, Intent intent) 
       {
       /* unRegister Receiver */
       Log.d("EF-BTBee", ">>unregisterReceiver");
             
       unregisterReceiver(_foundReceiver);
       unregisterReceiver(this);
       _discoveryFinished = true;
       }
};
      


After discovery will return remote device’s MAC address, device name and class. Using this information, the device performing discovery can then choose to initiate a connection with the discovered device. The following figure is click the “Search Device” button.


Connecting Device and Managing Device

            In order to create a connection between your application and two devices, you must implement the both server-side and client-side mechanisms, because one device must open a server socket and the other one must initiate the connection (use the server device’s MAC address to initiate a connection). So you must used a same UUID.

As Client:
UUID for Android App
socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));




The full code of class ClientSocketActivity.java
package com.android;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;

public class ClientSocketActivity  extends Activity
{
  private static final String TAG = ClientSocketActivity.class.getSimpleName();
  private static final int REQUEST_DISCOVERY = 0x1;;
   private Handler _handler = new Handler();
   private BluetoothAdapter _bluetooth = BluetoothAdapter.getDefaultAdapter();
   private BluetoothSocket socket = null;
      
       protected void onCreate(Bundle savedInstanceState)
       {
              super.onCreate(savedInstanceState);
              getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
              WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
              setContentView(R.layout.client_socket);
              if (!_bluetooth.isEnabled())
             {
                     finish();
                return;
              }

             Intent intent = new Intent(this, DiscoveryActivity.class);   
             /* Prompted to select a server to connect */
             Toast.makeText(this, "select device to connect", Toast.LENGTH_SHORT).show();
              /* Select device for list */
              startActivityForResult(intent, REQUEST_DISCOVERY);
       }
      
      
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
/*The integer request code originally supplied to startActivityForResult(), allowing you to identify who this result came from */
             
             if (requestCode != REQUEST_DISCOVERY)
              {
                     return;
              }
/*resultCode  The integer result code returned by the child activity through
               * its setResult() */
              if (resultCode != RESULT_OK) {
                     return;
              }
             
             final BluetoothDevice device = data.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
              connect(device);          
       }
      
      
       protected void connect(BluetoothDevice device)
       {
              //BluetoothSocket socket = null;
              try {
    //Create a Socket connection: need the server's UUID number of registered
              socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
                    
                     Singleton.remote_soket=socket;
                     Intent i=new Intent();
                     i.setClass(this.getApplicationContext(), Main.class);
                     startActivity(i);
                     finish();
                     return;
                    
              } catch (IOException e) {
                     Log.e("EF-BTBee", "", e);
              }
       }
}




When user selects device which he wants to connect, it looks like on picture above:


So, if anyone have some problem, with code, leave a comment and we will try to answer and solve the problem. As we mentioned earlier, we hope to post some more videos about how system is working and also write about some new projects (some stuff about using Arduino in Smart houses, so very interesting topics)...anyway, see you soon

M&M

5 коментара:

  1. Can you give me some example code to receive some character string from Bluetooth mate silver connected Arduino to Android application?

    ОдговориИзбриши
  2. Hi, of course ... here is this part of code.

    InputStream inputStream;
    OutputStream outputStream;

    //Send
    outputStream=Singleton.remote_soket.getOutputStream();
    String send="c";
    byte[] bytesend = new byte[1024];
    bytesend=send.getBytes();
    outputStream.write(bytesend);

    // Received some character
    inputStream = Singleton.remote_soket.getInputStream();
    int read = -1;
    final byte[] bytes = new byte[2048];
    read = inputStream.read(bytes);
    String s = new String(bytes);
    tv.setText(s);

    ОдговориИзбриши
  3. Hello Hishan Melanga, ask any further questions if you have some... can you leave a short reply about what you are doing with your Bluetooth module, maybe some video or short description...maybe if it interesting, you can write an article and send us to post it on our blog?

    ОдговориИзбриши
  4. Hi blogeri,

    I was working on a project that would allow communication between arduino and android. My app seems to be crashing and I would like to compare code. I am mostly interested in how to connect the devices via bluetooth. Could you please provide to ryanctek@yahoo.com or direct me to the source code. That would be greatly appreciated!

    Cheers

    ОдговориИзбриши
  5. can you send me a source code of android example?

    ОдговориИзбриши