This is the second post in a series on mobile development for Arduino. The Internet of Things is a niche segment in software development that is quickly becoming an emerging trend in the industry. In this post, we are going to continue to build upon the knowledge outlined in part 1 to “cut the cord” per se on our existing mobile device-driven speaker. In order to accomplish this, instead of physically connecting our mobile device and Arduino with a USB OTG cable, we are going to connect our mobile device to the Arduino with a Bluetooth device.

1. Declare The Necessary Permissions in the Manifest

In order for an Android application to transmit data via Bluetooth, two critical permissions must be added to the manifest. The first is “Bluetooth Admin.” This permission will allow the application to discover and pair Bluetooth devices. The second permission that is needed is “Bluetooth.” This permission enables applications to connect with paired Bluetooth devices.

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

 

2. Create Fragment To Discover Paired Bluetooth Devices

This fragment called the ArduinoBluetooth will display paired bluetooth devices in a listView and pass the address of the selected bluetooth device to our pre-existing fragment that will later be amended to connect to the bluetooth device. All you need is a listView and these variables. BluetoothAdapter is an Android class that allows you to perform fundamental Bluetooth tasks, such as initiate device discovery, query a list of bonded (paired) devices, etc. The BluetoothDevice class represents the remote bluetooth Device that we will connect to. Be sure to set this as the Fragment that is created when MainActivity is instantiated.

private ListView devicesListview;
private BluetoothAdapter bluetoothAdapter;
private Set<BluetoothDevice> pairedDevices;
public static String BLUETOOTH_ADDRESS = "bluetooth_address";

 

3. Create A Method that Will Discover Paired Devices And Populate Listview

The fetchPairedDevices() methods does exactly as its name implies. It fetches all the bluetooth devices that the mobile device is paired with. We will then capture the name and address of each BluetoothDevice as it returns to populate the listView. Next, create an OnItemClickListener that passes the address of the selected fragment to the next fragment.

 private void fetchPairedDevices() {
       pairedDevices = bluetoothAdapter.getBondedDevices();
       ArrayList list = new ArrayList();

       if (pairedDevices.size() > 0) {
           for(BluetoothDevice bt : pairedDevices) {
               list.add(bt.getName() + "n" + bt.getAddress());
           }
       } else {
           snackbar = Snackbar.make(coordinatorLayout, "No bluetooth device paired", Snackbar.LENGTH_LONG);
           snackbar.show();
       }

       final ArrayAdapter adapter = new ArrayAdapter(getActivity() ,android.R.layout.simple_list_item_1, list);
       devicesListview.setAdapter(adapter);
       devicesListview.setOnItemClickListener(itemClickListener);
   }

   private AdapterView.OnItemClickListener itemClickListener = new AdapterView.OnItemClickListener() {

       public void onItemClick (AdapterView<?> av, View v, int arg2, long arg3) {
           String info = ((TextView) v).getText().toString();
           String address = info.substring(info.length() - 17);

           ArduinoFragment fragment = ArduinoFragment.bluetoothInstance(address);
           getFragmentManager().beginTransaction()
                   .replace(R.id.container, fragment)
                   .addToBackStack(null)
                   .commit();
       }
   };

 

4. Amend Pre-Existing Fragment To Accommodate Bluetooth Functionality

In the Arduino Fragment that was created in the previous post, add necessary variables and create a new constructor that will allow the Bluetooth device address to be passed in. The BluetoothSocket class is what establishes and handles the serial communication between the mobile device and Bluetooth device. The hard-coded UUID shown below is what is needed when connecting a Bluetooth to a serial board. Otherwise, it would be necessary to generate a unique UUID if connecting to an Android peer.

 String bluetoothAddress;
 Boolean isBlueToothInstance;
 BluetoothAdapter bluetoothAdapter = null;
 BluetoothSocket btSocket = null;
 private boolean isBtConnected;
 static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

 public static ArduinoFragment newInstance() {
     return new ArduinoFragment();
 }

 public static ArduinoFragment bluetoothInstance(String bluetoothAddress) {
     ArduinoFragment fragment = new ArduinoFragment();
     fragment.bluetoothAddress = bluetoothAddress;
     fragment.isBlueToothInstance = true;
     return fragment;
 }

 

5. Create Class That Connects To BlueTooth Device

This class takes the Bluetooth address that is passed into the fragment and attempts to establish serial connection via the Bluetooth socket.

private class ConnectBlueTooth extends AsyncTask<Void, Void, Void> {
       private boolean connectSuccess = true;

       @Override
       protected Void doInBackground(Void... devices) {
           try
           {
               if (btSocket == null || !isBtConnected) {
                   bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
                   BluetoothDevice btDevice = bluetoothAdapter.getRemoteDevice(bluetoothAddress);
                   btSocket = btDevice.createInsecureRfcommSocketToServiceRecord(myUUID);
                   BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
                   btSocket.connect();
               }
           }
           catch (IOException e) {
               ConnectSuccess = false;
           }
           return null;
       }

       @Override
       protected void onPostExecute(Void result) {
           super.onPostExecute(result);
           if (!ConnectSuccess)  {
               Toast.makeText(getContext(), "Connection Failed. Is it a SPP Bluetooth? Try again.", Toast.LENGTH_LONG).show();
           } else {
               Toast.makeText(getContext(), "Connected.", Toast.LENGTH_LONG).show();
               isBtConnected = true;
           }
       }
   }

 

6. Amend Methods To Handle Bluetooth Functionality

First, we need to instantiate and execute the ConnectBlueTooth class in the OnViewCreated method if running Bluetooth instance of the fragment. Second, the playNote() method needs to be amended for the same reasons.

@Override
   public void onViewCreated(View view, Bundle savedInstanceState) {
       super.onViewCreated(view, savedInstanceState);

       ArrayAdapter<String> musicalNotesAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, musicalNotes);
       notesListView.setOnItemClickListener(this);
       notesListView.setAdapter(musicalNotesAdapter);

       if (isBlueToothInstance) {
           new ConnectBlueTooth().execute();
       } else {
           permissionIntent = PendingIntent.getBroadcast(getActivity(), 0, new Intent(ACTION_USB_PERMISSION), 0);
           getActivity().registerReceiver(usbPermissionReceiver, new IntentFilter(ACTION_USB_PERMISSION));
           getActivity().registerReceiver(usbConnectionStatusReceiver, new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED));
           getActivity().registerReceiver(usbConnectionStatusReceiver, new IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED));

           connectUsb();
       }
   }

  public void playNote(int note_value) {
       byte[] bytesOut = new byte[]{ ((Integer) note_value).byteValue()};

       if (isBlueToothInstance) {
           if (btSocket!=null){
               try {
                   btSocket.getOutputStream().write(bytesOut);
               } catch (IOException e) {
                   Toast.makeText(getContext(), "Error.", Toast.LENGTH_LONG).show();
               }
           }
       } else{
           if (arduinoDevice != null) {
               usbArduinoConnection.bulkTransfer(endpointOut, bytesOut, bytesOut.length, 0);
           }
       }
   }

 

7. Now, on the Arduino side, read the bytes and send them to the Piezo

This code is similar to the code for connecting to Arduino via USB OTG. However, there are subtle differences. Since the Serial connection tends to be fickle, we’ve added an LED to render visual feedback of the Bluetooth serial connection. It must also be noted that the SoftwareSerial library enables the Arduino to leverage its other ports to be used for serial connections. This is useful if one wanted to connect multiple Bluetooth devices to a single Arduino.

int speakerPin = 9;
int tones[] = { 440, 494, 523, 587, 659, 698, 784};

void setup() {
  pinMode(speakerPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
    if (Serial.available()) {
        int incomingByte = Serial.read();

        if (incomingByte > -1) {
          playNote(incomingByte);
        }
    }
}

void playNote(int note) {
  tone(speakerPin, tones[note], 200);
}

 

8. Connect Physical Arduino Components in Manner Shown Below

mobile development for Arduino

First, connect the VCC pin of the Bluetooth module to power. Second, connect the GRD pin of the Bluetooth module to the ground of the breadboard. Third, connect the Rx pin of the Bluetooth module to the Tx pin (1 pin) of the Arduino, which is marked with an upward pointing arrow. Lastly, connect the Tx pin of the Bluetooth module to the Rx pin of the Arduino (0 pin), which is marked with a downward pointing arrow.

mobile development for Arduino

Place the LED in pin 13 and GRD of the Arduino,

Now, upload your sketch. However, be mindful. Sometimes the Arduino will give an error when attempting to upload a sketch when the Bluetooth module is connected. It may be necessary to disconnect that component before uploading the sketch. Once the sketch is uploaded, pair your mobile device to the Bluetooth. If you don’t know the pairing pin it is usually 0000 or 1234 by default. Next, start the application and select the device from the list. When the application connects to the Bluetooth device, you are ready to begin playing notes via Bluetooth communication.

The GitHub repository for this ongoing project is available. In Mobile Development for Arduino Part 3, we’ll learn how to communicate with the Arduino via REST services over an HTTP connection.

Leave a Reply

Your email address will not be published. Required fields are marked *