Tuesday, May 29, 2012

It Worked for Me – Circuits@Home USB Shield

Last week on Monday evening I placed an order with Circuits@Home for a USB Host Shield for Arduino Pro Mini.  On Friday the USPS delivered it to my mailbox.  By Monday, in spite of a busy holiday weekend, I had it up and handling traffic between my Android Tablet and a breadboard Arduino.

UHSM_prod

The hardware documentation was complete and the software, downloaded from GitHub, worked flawlessly.  Thanks to Oleg for making such a fine device available to us and for the great customer service.

Arduino to Android – Turning an LED On and Off using ADK and the Circuits@Home USB Shield

This is the same example conceptually as the previous post Arduino to Android – Turning an LED On and Off except that it uses the Android Open Accessory Development Kit (ADK) and a USB connection via a Circuits@Home USB Shield rather than bluetooth to communicate between the Android tablet and the Arduino.

The Android device connects using ADK over USB to the Ardunio which is running in a loop waiting for data from the USB Shield.  If the Android device sends a 1 then the Arduino turns the LED on. If a 0 is sent the LED is turned off.

Hardware Setup

For this example I used:

  1. A breadboard Arduino with a Sparkfun FTDI 3.3v board.
  2. An Acer Iconia Tab A100 running Ice Cream Sandwich 4.0.3.
  3. A Circuits@Home USB Host Shield for Arduino Pro Mini.
  4. A red LED. Connected to the Arduino on digital pin 8.
  5. A 470 ohm resistor connecting the LED to ground.

The picture below shows how the hardware is setup.

ADKSetup
The USB shield was wired to the Arduino as shown in the diagram below.

uhm11_manual
Starting from the top left of the board and working around the board clockwise.

USB Shield Arduino
INT (D9) Digital Pin 9
GND GND
RESET Reset
GND GND
3.3v 3.3v
SCK Digital Pin 13
MISO Digital Pin 12
MOSI Digital Pin 11
SS (D10) Digital Pin 10

Software Setup

This example assumes you have the eclipse Android development environment and the Arduino development environment.

If you are using the Circuits@Home USB Shield you will need to download the 2.0 libraries for the shield and put them in your Arduino libraries directory. The libraries and example files are on GitHub.

Ardunio Sketch
#include <avrpins.h>
#include <max3421e.h>
#include <usbhost.h>
#include <usb_ch9.h>
#include <Usb.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <address.h>

#include <adk.h>

#include <printhex.h>
#include <message.h>
#include <hexdump.h>
#include <parsetools.h>

USB Usb;
USBHub hub0(&Usb);
USBHub hub1(&Usb);
ADK adk(&Usb,"Digitalhack",
            "LEDOnOffADK",
            "DemoKit Arduino Board",
            "1.0",
            "http://www.android.com",
            "0000000012345678");
uint8_t  b, b1;

#define  LED       8

void setup();
void loop();

void setup() {
  Serial.begin(115200);
  Serial.println("\r\nADK demo start");
        
  digitalWrite(LED, LOW);
  pinMode(LED, OUTPUT);

  if (Usb.Init() == -1) {
    Serial.println("OSCOKIRQ failed to assert");
    while(1); //halt
  }
}

void loop() {
  uint8_t rcode;
  uint8_t msg[3] = { 0x00 };
  Usb.Task();
   
  if (adk.isReady() == false) {
    Serial.println("Waiting for adk.");
  } else {
    uint16_t len = sizeof(msg);
   
    rcode = adk.RcvData(&len, msg);
    if( rcode && rcode != hrNAK) {
      Serial.print("Data rcv rcode: ");
      Serial.println(rcode);
    } 

    if(len > 0) {
      Serial.println("Data Packet.");
      // assumes only one command per packet
      if (msg[0] == 0x2) {
        switch( msg[1] ) {
          case 0:
            digitalWrite(LED, LOW);
            break;
          case 1:
            digitalWrite(LED, HIGH);
            break;
         }  
       }
    }
    delay( 10 );
  }
}
LEDOnOFFADK.java
goes in ProjectRoot>\src\com\example\ledonoffadk\
package com.example.ledonoffadk;

import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import com.example.ledonoffadk.R;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;

public class LEDOnOffADK extends Activity {
  private static final String TAG = "LEDOnOffADK";
  
  private static final String ACTION_USB_PERMISSION = "com.example.LEDOnOffADK.USB_PERMISSION";
  
  private UsbManager mUsbManager;
  private PendingIntent mPermissionIntent;
  private boolean mPermissionRequestPending;
 
  UsbAccessory mAccessory;
  ParcelFileDescriptor mFileDescriptor;
  FileInputStream mInputStream;
  FileOutputStream mOutputStream;
 
  Button btnOn, btnOff;

  private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
      String action = intent.getAction();
      if (ACTION_USB_PERMISSION.equals(action)) {
        synchronized (this) {
          UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
          if (intent.getBooleanExtra(
              UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
            openAccessory(accessory);
          } else {
            Log.d(TAG, "permission denied for accessory "
                + accessory);
          }
          mPermissionRequestPending = false;
        }
      } else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
        UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
        if (accessory != null && accessory.equals(mAccessory)) {
          closeAccessory();
        }
      }
    }
  };

  
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.d(TAG, "In onCreate()");

    mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
    mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
    registerReceiver(mUsbReceiver, filter);
 
    if (getLastNonConfigurationInstance() != null) {
      mAccessory = (UsbAccessory) getLastNonConfigurationInstance();
      openAccessory(mAccessory);
    }
 
    setContentView(R.layout.main);

    btnOn = (Button) findViewById(R.id.btnOn);
    btnOff = (Button) findViewById(R.id.btnOff);

    btnOn.setOnClickListener(new OnClickListener() {
      public void onClick(View v) {
        byte[] buffer = new byte[2];
        buffer[0]= 0x2;        
        
        buffer[1]=(byte)1; // button says on, light is off
        if (mOutputStream != null) {
          try {
            mOutputStream.write(buffer);
          } catch (IOException e) {
            Log.e(TAG, "write failed", e);
          }
        }
        Toast msg = Toast.makeText(getBaseContext(),
            "You have clicked On", Toast.LENGTH_SHORT);
        msg.show();
      }
    });

    btnOff.setOnClickListener(new OnClickListener() {
      public void onClick(View v) {
        byte[] buffer = new byte[2];
        buffer[0]= 0x2;        
        
        buffer[1]=(byte)0; // button says on, light is off
        if (mOutputStream != null) {
          try {
            mOutputStream.write(buffer);
          } catch (IOException e) {
            Log.e(TAG, "write failed", e);
          }
        }
        Toast msg = Toast.makeText(getBaseContext(),
            "You have clicked Off", Toast.LENGTH_SHORT);
        msg.show();
      }
    });
  }
 
  @Override
  public Object onRetainNonConfigurationInstance() {
    if (mAccessory != null) {
      return mAccessory;
    } else {
      return super.onRetainNonConfigurationInstance();
    }
  }
 
  @Override
  public void onResume() {
    super.onResume();
 
    if (mInputStream != null && mOutputStream != null) {
      return;
    }
 
    UsbAccessory[] accessories = mUsbManager.getAccessoryList();
    UsbAccessory accessory = (accessories == null ? null : accessories[0]);
    if (accessory != null) {
      if (mUsbManager.hasPermission(accessory)) {
        openAccessory(accessory);
      } else {
        synchronized (mUsbReceiver) {
          if (!mPermissionRequestPending) {
            mUsbManager.requestPermission(accessory,mPermissionIntent);
            mPermissionRequestPending = true;
          }
        }
      }
    } else {
      Log.d(TAG, "mAccessory is null");
    }
  }

  @Override
  public void onPause() {
    super.onPause();
    closeAccessory();
  }
 
  @Override
  public void onDestroy() {
    unregisterReceiver(mUsbReceiver);
    super.onDestroy();
  }
 
  private void openAccessory(UsbAccessory accessory) {
    mFileDescriptor = mUsbManager.openAccessory(accessory);
    if (mFileDescriptor != null) {
      mAccessory = accessory;
      FileDescriptor fd = mFileDescriptor.getFileDescriptor();
      mInputStream = new FileInputStream(fd);
      mOutputStream = new FileOutputStream(fd);
      Log.d(TAG, "accessory opened");
    } else {
      Log.d(TAG, "accessory open fail");
    }
  }
 
  private void closeAccessory() {
    try {
      if (mFileDescriptor != null) {
        mFileDescriptor.close();
      }
    } catch (IOException e) {
    } finally {
      mFileDescriptor = null;
      mAccessory = null;
    }
  }
}
strings.xml
goes in <ProjectRoot>\res\values\
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">LED On Off (ADK)</string>

</resources>
main.xml
goes in <ProjectRoot>\res\layout\
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/btnOn"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="Turn LED On" />

    <Button
        android:id="@+id/btnOff"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="Turn LED Off" />

</LinearLayout>
accessory_filter.xml
goes in <ProjectRoot>\res\xml\
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <usb-accessory manufacturer="Digitalhack" model="LEDOnOffADK" version="1.0" /> 
</resources>
AndroidManifest.xml
goes in <ProjectRoot>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.ledonoffadk"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="15" />

<application android:icon="@drawable/ic_launcher" android:label="@string/app_name"> 
  <activity android:name=".LEDOnOffADK"
   android:label="@string/app_name">
   <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" /> 
   </intent-filter>
   <intent-filter>
    <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" /> 
   </intent-filter>
   <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
    android:resource="@xml/accessory_filter" />
  </activity> 
 </application>
</manifest>
Screen Capture from Acer A100

LEDOnOffADK

Notes:

  1. I cannot think how you would get this to work with the emulator so I didn't try.
  2. This example is built upon the work of others. I post it here not as an example of original work but rather as a complete working example for reference. If I didn't appropriately credit you for your work please let me know and I will add you.

Monday, May 14, 2012

Arduino to Android – Turning an LED On and Off

This example shows you how to program an Android device to communicate with an Arduino over bluetooth and turn on or turn off an LED.

The Android device connects via the bluetooth to the Arduino which is running in a loop waiting for data from the bluetooth inteface. The data is read from the bluetooth interface using the software serial library. If the Arduino reads a 1 it turns an LED on pin 13 on. If it finds a 0 then it turns the LED off. If it reads anything else it doesn't change the state of the LED.

If you are using the Sparkfun Bluetooth Mate when you successfully connect to it from your Android program the Red Stat LED will turn off and the Green Connect LED will turn on solid.

For this example I used the same setup as I did for my earlier Arduino to Android tutorial: Arduino to Android – Basic Bluetooth Connectivity with the addition of an LED connected to pin 13 on the Arduino.

Download Zip Archive of Android Source Files

Arduino Sketch
#include <SoftwareSerial.h>

SoftwareSerial mySerial(6, 5);
int dataFromBT;

void setup() {
  Serial.begin(57600);
  Serial.println("LEDOnOff Starting...");

  // The data rate for the SoftwareSerial port needs to 
  // match the data rate for your bluetooth board.
  mySerial.begin(115200);
  pinMode(13, OUTPUT);   
}

void loop() {
  if (mySerial.available())
    dataFromBT = mySerial.read();

  if (dataFromBT == '0') {
    // Turn off LED
    digitalWrite(13, LOW);
  } else if (dataFromBT == '1') {
    // Turn on LEFD
    digitalWrite(13, HIGH);
  }
}
LEDOnOFF.java
goes in <ProjectRoot>\src\com\example\ledonoff\
package com.example.ledonoff;

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

import com.example.ledonoff.R;

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.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class LEDOnOff extends Activity {
  private static final String TAG = "LEDOnOff";
  
  Button btnOn, btnOff;
  
  private static final int REQUEST_ENABLE_BT = 1;
  private BluetoothAdapter btAdapter = null;
  private BluetoothSocket btSocket = null;
  private OutputStream outStream = null;
  
  // Well known SPP UUID
  private static final UUID MY_UUID =
      UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

  // Insert your server's MAC address
  private static String address = "00:00:00:00:00:00";
  
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Log.d(TAG, "In onCreate()");

    setContentView(R.layout.main);

    btnOn = (Button) findViewById(R.id.btnOn);
    btnOff = (Button) findViewById(R.id.btnOff);
    
    btAdapter = BluetoothAdapter.getDefaultAdapter();
    checkBTState();

    btnOn.setOnClickListener(new OnClickListener() {
      public void onClick(View v) {
        sendData("1");
        Toast msg = Toast.makeText(getBaseContext(),
            "You have clicked On", Toast.LENGTH_SHORT);
        msg.show();
      }
    });

    btnOff.setOnClickListener(new OnClickListener() {
      public void onClick(View v) {
        sendData("0");
        Toast msg = Toast.makeText(getBaseContext(),
            "You have clicked Off", Toast.LENGTH_SHORT);
        msg.show();
      }
    });
  }
  
  @Override
  public void onResume() {
    super.onResume();

    Log.d(TAG, "...In onResume - Attempting client connect...");
  
    // Set up a pointer to the remote node using it's address.
    BluetoothDevice device = btAdapter.getRemoteDevice(address);
  
    // Two things are needed to make a connection:
    //   A MAC address, which we got above.
    //   A Service ID or UUID.  In this case we are using the
    //     UUID for SPP.
    try {
      btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
    } catch (IOException e) {
      errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
    }
  
    // Discovery is resource intensive.  Make sure it isn't going on
    // when you attempt to connect and pass your message.
    btAdapter.cancelDiscovery();
  
    // Establish the connection.  This will block until it connects.
    Log.d(TAG, "...Connecting to Remote...");
    try {
      btSocket.connect();
      Log.d(TAG, "...Connection established and data link opened...");
    } catch (IOException e) {
      try {
        btSocket.close();
      } catch (IOException e2) {
        errorExit("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
      }
    }
    
    // Create a data stream so we can talk to server.
    Log.d(TAG, "...Creating Socket...");

    try {
      outStream = btSocket.getOutputStream();
    } catch (IOException e) {
      errorExit("Fatal Error", "In onResume() and output stream creation failed:" + e.getMessage() + ".");
    }
  }

  @Override
  public void onPause() {
    super.onPause();

    Log.d(TAG, "...In onPause()...");

    if (outStream != null) {
      try {
        outStream.flush();
      } catch (IOException e) {
        errorExit("Fatal Error", "In onPause() and failed to flush output stream: " + e.getMessage() + ".");
      }
    }

    try     {
      btSocket.close();
    } catch (IOException e2) {
      errorExit("Fatal Error", "In onPause() and failed to close socket." + e2.getMessage() + ".");
    }
  }
  
  private void checkBTState() {
    // Check for Bluetooth support and then check to make sure it is turned on

    // Emulator doesn't support Bluetooth and will return null
    if(btAdapter==null) { 
      errorExit("Fatal Error", "Bluetooth Not supported. Aborting.");
    } else {
      if (btAdapter.isEnabled()) {
        Log.d(TAG, "...Bluetooth is enabled...");
      } else {
        //Prompt user to turn on Bluetooth
        Intent enableBtIntent = new Intent(btAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
      }
    }
  }

  private void errorExit(String title, String message){
    Toast msg = Toast.makeText(getBaseContext(),
        title + " - " + message, Toast.LENGTH_SHORT);
    msg.show();
    finish();
  }

  private void sendData(String message) {
    byte[] msgBuffer = message.getBytes();

    Log.d(TAG, "...Sending data: " + message + "...");

    try {
      outStream.write(msgBuffer);
    } catch (IOException e) {
      String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
      if (address.equals("00:00:00:00:00:00")) 
        msg = msg + ".\n\nUpdate your server address from 00:00:00:00:00:00 to the correct address on line 37 in the java code";
      msg = msg +  ".\n\nCheck that the SPP UUID: " + MY_UUID.toString() + " exists on server.\n\n";
      
      errorExit("Fatal Error", msg);       
    }
  }
}
strings.xml
goes in <ProjectRoot>\res\values\
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">LED On Off</string>

</resources>
main.xml
goes in <ProjectRoot>\res\layout\
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/btnOn"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="Turn LED On" />

    <Button
        android:id="@+id/btnOff"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="Turn LED Off" />

</LinearLayout>

AndroidManifest.xml
goes in <ProjectRoot>

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.ledonoff"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".LEDOnOff"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

</manifest>

Screen Capture from Acer A100

Notes:

  1. As the SDK Emulator doesn’t emulate bluetooth and probably wouldn't be able to make a connection even if it did this example will not run in the emulator.
  2. This example is built upon the work of others. I post it here not as an example of original work but rather as a complete working example for reference. If I didn't appropriately credit you for your work please let me know and I will add you.

Tuesday, May 8, 2012

Quick Note - Android - Activity Lifecycle Notes

When you run an app it goes through the following states: onCreate, onStart and onResume.

When you press home the app goes through: onPause and onStop.

When you go back to the app it goes through: onStart and onResume.

When you press back the app goes through: onPause, onStop and onDestroy

Sunday, May 6, 2012

Arduino to Android – Basic Bluetooth Connectivity Tutorial

This tutorial will show you how to configure an Ardunio to communicate over bluetooth with an Android device.

It assumes you have a basic knowledge of the Arduino, the Arduino IDE and installing Android applications from Google Play.

For this tutorial you will need the following items:

  1. An Arduino board.
  2. An Android device with bluetooth.
  3. A bluetooth serial board capable of connecting to the Arduino. 
  4. An Android bluetooth terminal program

You will also need the Arduino IDE.  The Android SDK and a breadboard are not required but are helpful.

What I used:

  1. A breadboard Arduino with a Modern Devices USB BUB.
  2. An Acer Iconia Tab A100 running Ice Cream Sandwich 4.0.3.
  3. A Sparkfun Bluetooth Mate Silver.
  4. BlueTerm by pymasde.es available on Google Play.

Arduino Configuration

Connect GND, VCC, RX and TX from the bluetooth device to the appropriate Arduino pins.  For my setup I connected GND to GND, VCC to +5V, RX to D5 and TX to D6.

Arduino Sketch

The Arduino sketch makes use of the SoftwareSerial library to communicate via two digital pins to the bluetooth device. You will need to make sure you set the SoftwareSerial baud rate to match the baud rate of your bluetooth device.

Android Setup

You will a program on Android that can connect to the bluetooth and host an SPP connection. I used BlueTerm from Google Play but you should be able to use another bluetooth terminal.

Run your bluetooth terminal. If you are using BlueTerm follow the steps below:

Select the three vertical dots to get the menu.

This next step is optional.  To make typing on your Android device easier you may want to turn on local echo.  Press preferences

and then select Local Echo. 

Return to the menu screen by pressing previous and select Connect Device.

Select your bluetooth device.  Mine is named mymate. If you are using the Sparkfun Bluetooth Mate when you successfully connect your Android device to it the blinking red LED marked "Stat" (red arrow in the above picture of the breadboard Arduino) will turn off and the green LED marked "Connect" (green arrow in the above picture) will turn on.

Compile and run the Arduino sketch and you should see output in BlueTerm and the Arduino serial monitor.

Serial Monitor

If you type characters on the Android device they should show up in the Arduino Serial Monitor.

Notes:

  1. As the SDK Emulator doesn’t emulate bluetooth and probably wouldn't be able to make a connection even if it did this example will not run in the emulator.
  2. This example is built upon the work of others. I post it here not as an example of original work but rather as a complete working example for reference. If I didn't appropriately credit you for your work please let me know and I will add you.

Saturday, May 5, 2012

Android Example - Bluetooth Discover and List Devices and Services

This example does a bluetooth device discovery followed by a service discovery for every device it finds. The devices and services are listed as they are found.

There is one mystery that has me perplexed. Two identical sets of services are returned for each device. In the Android documentation it states that fetchUuidsWithSdp() will:
If there is an error in getting the SDP records or if the process takes a long time, ACTION_UUID intent is sent with the UUIDs that is currently present in the cache.
It is conceivable that the first set of responses is from cache and the second is from the remote device.

This example also demonstrates the use of a BroadcastReceiver, Intent Filters and a scrolling TextArea.

I have included the files that have content that is key to setting up the application.

You should be able to create a new Android project in eclipse and then copy the code included below into the appropriate file. Because fetchUUidsWithSDP() is called directly this example requires ICS or higher.

Below the code attachments you will find a screen capture of what it looks like running on my Acer A100.

If you have any suggestions or questions please post them as comments.

Download Zip Archive of Android Source Files

DiscoverDevicesAndServices.java
goes in <ProjectRoot>\src\com\example\discoverdevicesandservices\
strings.xml
goes in <ProjectRoot>\res\values\
main.xml
goes in <ProjectRoot>\res\layout\
AndroidManifest.xml
goes in <ProjectRoot>
Screen Capture from Acer A100

Notes:

  1. Due to fetchUuidsWithSDP() this requires API Release 15
  2. As the SDK Emulator doesn’t emulate bluetooth this example will not run in the emulator.
  3. This example is built upon the work of others. I post it here not as an example of original work but rather as a complete working example for reference. If I didn't appropriately credit you for your work please let me know and I will add you.

Android Example - Bluetooth Simple SPP Client and Server

This example has both a client and a server. The client runs on Android and in my case I ran the server on Windows 7 x64. I tested both java server and a perl server.

A useful freeware tool for listing the services / UUIDs on a device is Medieval Software's Bluetooth Network Scanner.

I have included the files that have content that is key to setting up the application.

You should be able to create a new Android project in eclipse and then copy the code included below into the appropriate file.

Below the code attachments you will find a screen capture of what it looks like running on my Acer A100.

If you have any suggestions or questions please post them as comments.


Android SPP Client

The Android application is based on this post: Serial over Bluetooth simple test client. from anddev.org.

ConnectTest.java
goes in <ProjectRoot>\src\com\example\connecttest\
strings.xml goes in <ProjectRoot>\res\values\ main.xml
goes in <ProjectRoot>\res\layout\
AndroidManifest.xml
goes in <ProjectRoot>
Screen Capture from Acer A100


Java SPP Server

The java server was based on this the SimpleSPPSever example from JSR-82 Sample : SPP Server and Client. To get to run on Windows I used the bluecove-2.1.1-SNAPSHOT.jar library.

SimpleSPPServer.java
goes in <ProjectRoot>\src\
Screen Capture from PC


Perl Server

The perl server was built using the Net::Bluetooth module.

SimpleSPPServer.pl

Notes:

  1. As the SDK Emulator doesn’t emulate bluetooth this example will not run in the emulator.
  2. This example is built upon the work of others. I post it here not as an example of original work but rather as a complete working example for reference. If I didn't appropriately credit you for your work please let me know and I will add you.

Wednesday, May 2, 2012

Andriod Example - Bluetooth Show Paired Devices

Here is a very simple example that I thought might be helpful to someone. I have included the four files that have content that is key to setting up the application.

The program checks to see if the device has bluetooth. If the device does and it isn’t turned on the program will prompt the user to turn it one. Once bluetooth is running it lists the paired devices.

You should be able to create a new Android project in eclipse and then copy the code included below into the appropriate file.

As the SDK Emulator doesn’t emulate bluetooth this example will not run in the emulator.

This example is built upon the information in the Bluetooth Dev Guide on the Android Developers site and the Android-Java Bluetooth on Samsung Galaxy post on stackoverflow.com.

Below the code attachments you will find a screen capture of what it looks like running on my Acer A100.

If you have any suggestions or questions please post them as comments.

ShowPaired.java
goes in <ProjectRoot>\src\com\example\showpaired\

strings.xml
goes in <ProjectRoot>\res\values\

main.xml
goes in <ProjectRoot>\res\layout\

AndroidManifest.xml
goes in <ProjectRoot>

Screen Capture from Acer A100



Notes:

  1. The code highlighting is done using SyntaxHighlighter which is maintained by Alex Gorbatchev and can be found at http://alexgorbatchev.com/SyntaxHighlighter/.
  2. This example is built upon the work of others. I post it here not as an example of original work but rather as a complete working example for reference. If I didn't appropriately credit you for your work please let me know and I will add you.

Android Programming

As described in the previous post I have wanted to integrate touch screen technology into one of my projects.  A couple of weeks ago after reading some introductory information on the Android SDK I decided to install it and give it a try.

I am lucky to live in an area where our county libraries have a subscription to Safari Books Online.  After doing some general reading up based on google search hits I jumped on Safari and did a search for books on Android.

The search resulted in a number of hits and after reviewing them I settled on Learning Android by Marco Gargenta.  This lead me to the open source training company Markana which has an excellent TechTV repository.  One of the video series they have is their Android Bootcamp Training Course which was presented by Marko Garenta based on the Learning Android book.

I used the books and the online videos to work my way through chapters 1 – 8 which provided me with enough knowledge to start working on a couple of my own examples.

To move forward I have made a lot of use of other people who have gone before me.  A lot of what I have learned has been based on examples from various web sites and forums.  In an attempt to give something back I plan to post some examples that I got working in an attempt to pass on what others have shown me.

My development environment consists of:

  • Windows 7 Professional x64
  • Eclipse Indigo Release 2
  • Revision 19 of the SDK
  • Android 4.0.3 (API 15)
  • Acer Iconia Tab A100 running ICS 4.0.3

While I have a good bit of experience with IT technology and programming Java is not one of my strong points.  If you see something that I have done that is wrong or could be improved please let me know.

If you have questions that I may be able to help with please post them in the comments and I will get back to you as soon as possible.