battle programmers alliance
Would you like to react to this message? Create an account in a few clicks or log in to continue.

battle programmers allianceLog in

the LivinGrimoire Artificial General Intelligence software design pattern forum

description[java] android studio control droiduino bluetooth arduino with bluetooth Empty[java] android studio control droiduino bluetooth arduino with bluetooth

more_horiz
android studio control droiduino bluetooth arduino with bluetooth

arduino crush course :

arduino is a microcontroller used to controll robots.

an arduino shield is a part you connect to an arduino board to increase its available functions.

most popular arduino board variations :

Arduino Uno : popular board for begginers
Arduino Mega: if you need more input/output ports
Arduino nano :small scale arduino boards

to code an arduino board you need the arduino IDE installed on your computer
then send the code via USB cable to the arduino board.

arduino IDE DL link :

https://www.arduino.cc/en/software/

when connecting the board make sure the IDE recognizes it :
tools->choose your board
next select the usb port
tools->port
(the board needs to be connected only when you are ready to send the compiled code)
there is a V btn to compile and an arrow btn to send the code to the arduino board

the IDE has example code.
file->examples->basics->blink

every arduino code cosists of 2 functions :
1 setup : runs once
2 loop : runs non stop

description[java] android studio control droiduino bluetooth arduino with bluetooth EmptyRe: [java] android studio control droiduino bluetooth arduino with bluetooth

more_horiz
the code has been beefed up to enable automatic enabling of bluetooth programmaticaly
connect to a bluetooth headset, and animate the recyclerview.

in the manifest file :
add bluetooth permissions under package

<!--Permissions for Bluetooth access-->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

right click java classes folder at left explorer window and add a new empty activity.

activity_select_device.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SelectDeviceActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/deviceList"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>


SelectDeviceActivity:

Code:

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.os.Bundle;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class SelectDeviceActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_select_device);

        // Instantiate RecyclerView
        RecyclerView recyclerView = findViewById(R.id.deviceList);

        // Initialize Bluetooth adapter
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        //enable bluetooth programmaticaly :

        if (!bluetoothAdapter.isEnabled()) {
            bluetoothAdapter.enable();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // Fetch the list from Android device's cache
        Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
        List<Object> deviceList = new ArrayList<>();
        for (BluetoothDevice device : pairedDevices){
            String deviceName = device.getName();
            String deviceHardwareAddress = device.getAddress();
            DeviceInfoModel deviceInfoModel = new DeviceInfoModel(deviceName,deviceHardwareAddress);
            deviceList.add(deviceInfoModel);
        }

        // Setting Up RecyclerView
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        // Connecting to Data Source and Content Layout
        // Data source is the list of Bluetooth devices that are paired with Android Device
        ListAdapter listAdapter = new ListAdapter(this,deviceList);
        recyclerView.setAdapter(listAdapter);


    }
}


n the res, layout directory add a layout for the items in the recycler view :
item_layout.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/textItem"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:textSize="18sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/divider"
        android:layout_width="409dp"
        android:layout_height="1dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:background="?android:attr/listDivider"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textItem" />
</androidx.constraintlayout.widget.ConstraintLayout>

description[java] android studio control droiduino bluetooth arduino with bluetooth EmptyRe: [java] android studio control droiduino bluetooth arduino with bluetooth

more_horiz
add java class DeviceInfoModel, this will hold device bluetooth addresses and names :

Code:

public class DeviceInfoModel {

    private String deviceName, deviceHardwareAddress;

    public DeviceInfoModel(){}

    public DeviceInfoModel(String deviceName, String deviceHardwareAddress){
        this.deviceName = deviceName;
        this.deviceHardwareAddress = deviceHardwareAddress;
    }

    public String getDeviceName(){return deviceName;}

    public String getDeviceHardwareAddress(){return deviceHardwareAddress;}

}


add (java class) ListAdaptor

Code:

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class ListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Context context;
    private List<Object> deviceList;

    public static class ViewHolder extends RecyclerView.ViewHolder {
        TextView textName;

        public ViewHolder(View view){
            super(view);
            textName = view.findViewById(R.id.textItem);
        }
    }

    public ListAdapter(Context context, List<Object> deviceList){
        this.context = context;
        this.deviceList = deviceList;
    }

    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout,parent,false);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    public void onBindViewHolder(RecyclerView.ViewHolder holder,int position){
        // Get Device Name and Device Address
        DeviceInfoModel deviceInfoModel = (DeviceInfoModel) deviceList.get(position);
        String deviceName = deviceInfoModel.getDeviceName();
        final String deviceAddress = deviceInfoModel.getDeviceHardwareAddress();

        // Assign Device name to the list
        ViewHolder itemHolder = (ViewHolder) holder;
        itemHolder.textName.setText(deviceName);

        // Return to Main Screen when a device is selected
        // And pass device Address information to create connection
        itemHolder.textName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(context, MainActivity.class);
                intent.putExtra("deviceAddress",deviceAddress);
                context.startActivity(intent);
            }
        });

    }

    public int getItemCount(){
        int dataCount = deviceList.size();
        return dataCount;
    }

}


description[java] android studio control droiduino bluetooth arduino with bluetooth EmptyRe: [java] android studio control droiduino bluetooth arduino with bluetooth

more_horiz
set mainactivity layout xml file code:

Code:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="32dp"
        android:layout_marginTop="64dp"
        android:layout_marginEnd="32dp"
        android:orientation="vertical"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/textBluetoothStatus"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Bluetooth is Disconnected"
            android:textAlignment="center"
            android:textSize="24sp" />

        <LinearLayout
            android:id="@+id/linearLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/buttonConnect"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Connect" />

            <Button
                android:id="@+id/buttonDisconnect"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Disconnect" />
        </LinearLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="32dp"
        android:layout_marginTop="32dp"
        android:layout_marginEnd="32dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/textLedStatus"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="LED is OFF"
            android:textAlignment="center"
            android:textSize="24sp" />

        <Button
            android:id="@+id/buttonOn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Turn ON" />

        <Button
            android:id="@+id/buttonOff"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Turn OFF" />

        <Button
            android:id="@+id/buttonBlink"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Blinking" />
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>


MainActivity.java :

Code:

package com.yotamarker.bluetoothjava1;

import androidx.appcompat.app.AppCompatActivity;

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.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.UUID;

import static android.content.ContentValues.TAG;

public class MainActivity extends AppCompatActivity {

    private String deviceAddress = null;
    public static Handler handler;
    public static BluetoothSocket mmSocket;
    public static ConnectedThread connectedThread;
    public static CreateConnectThread createConnectThread;

    // The following variables used in bluetooth handler to identify message status
    private final static int CONNECTION_STATUS = 1;
    private final static int MESSAGE_READ = 2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Instantiate UI
        final TextView bluetoothStatus = findViewById(R.id.textBluetoothStatus);
        Button buttonConnect = findViewById(R.id.buttonConnect);
        Button buttonDisconnect = findViewById(R.id.buttonDisconnect);
        final TextView ledStatus = findViewById(R.id.textLedStatus);
        Button buttonOn = findViewById(R.id.buttonOn);
        Button buttonOff = findViewById(R.id.buttonOff);
        Button buttonBlink = findViewById(R.id.buttonBlink);

        // Code for the "Connect" button
        buttonConnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // This is the code to move to another screen
                Intent intent = new Intent(MainActivity.this, SelectDeviceActivity.class);
                startActivity(intent);
            }
        });

        // Get Device Address from SelectDeviceActivity.java to create connection
        deviceAddress = getIntent().getStringExtra("deviceAddress");
        if (deviceAddress != null){
            bluetoothStatus.setText("Connecting...");
            /*
            This is the most important piece of code.
            When "deviceAddress" is found, the code will call the create connection thread
            to create bluetooth connection to the selected device using the device Address
            */
            BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            //connect to device hack (such as bluetooth headset)
            BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(deviceAddress);
            bluetoothAdapter.enable();
            bluetoothDevice.createBond();
            //end of hack snippet
            createConnectThread = new CreateConnectThread(bluetoothAdapter,deviceAddress);
            createConnectThread.start();
        }



        /*
        Second most important piece of Code.
        This handler is used to update the UI whenever a Thread produces a new output
        and passes through the values to Main Thread
        */
        handler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg){
                switch (msg.what){
                    // If the updates come from the Thread to Create Connection
                    case CONNECTION_STATUS:
                        switch(msg.arg1){
                            case 1:
                                bluetoothStatus.setText("Bluetooth Connected");
                                break;
                            case -1:
                                bluetoothStatus.setText("Connection Failed");
                                break;
                        }
                        break;

                    // If the updates come from the Thread for Data Exchange
                    case MESSAGE_READ:
                        String statusText = msg.obj.toString().replace("/n","");
                        ledStatus.setText(statusText);
                        break;
                }
            }
        };

        // Code for the disconnect button
        buttonDisconnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (createConnectThread != null){
                    createConnectThread.cancel();
                    bluetoothStatus.setText("Bluetooth is Disconnected");
                }
            }
        });

        // Code to turn ON LED
        buttonOn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String androidCmd = "w";
                connectedThread.write(androidCmd);
            }
        });

        // Code to turn OFF LED
        buttonOff.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String androidCmd = "s";
                connectedThread.write(androidCmd);
            }
        });

        // Code to make the LED blinking
        buttonBlink.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String androidCmd = "d";
                connectedThread.write(androidCmd);
            }
        });
    }

    /* ============================ Thread to Create Connection ================================= */
    public static class CreateConnectThread extends Thread {

        public CreateConnectThread(BluetoothAdapter bluetoothAdapter, String address) {
            // Opening connection socket with the Arduino board
            BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(address);
            BluetoothSocket tmp = null;
            UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
            try {
                // Get a BluetoothSocket to connect with the given BluetoothDevice.
                // MY_UUID is the app's UUID string, also used in the server code.
                tmp = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(uuid);
            } catch (IOException e) {
                Log.e(TAG, "Socket's create() method failed", e);
            }
            mmSocket = tmp;
        }

        public void run() {
            // Cancel discovery because it otherwise slows down the connection.
            BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            bluetoothAdapter.cancelDiscovery();
            try {
                // Connect to the Arduino board through the socket. This call blocks
                // until it succeeds or throws an exception.
                mmSocket.connect();
                handler.obtainMessage(CONNECTION_STATUS, 1, -1).sendToTarget();
            } catch (IOException connectException) {
                // Unable to connect; close the socket and return.
                try {
                    mmSocket.close();
                    handler.obtainMessage(CONNECTION_STATUS, -1, -1).sendToTarget();
                } catch (IOException closeException) { }
                return;
            }

            // The connection attempt succeeded. Perform work associated with
            // the connection in a separate thread.
            // Calling for the Thread for Data Exchange (see below)
            connectedThread = new ConnectedThread(mmSocket);
            connectedThread.run();
        }

        // Closes the client socket and causes the thread to finish.
        // Disconnect from Arduino board
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
    }

    /* =============================== Thread for Data Exchange ================================= */
    public static class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        // Getting Input and Output Stream when connected to Arduino Board
        public ConnectedThread(BluetoothSocket socket) {
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) { }
            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        // Read message from Arduino device and send it to handler in the Main Thread
        public void run() {
            byte[] buffer = new byte[1024];  // buffer store for the stream
            int bytes = 0; // bytes returned from read()
            // Keep listening to the InputStream until an exception occurs
            while (true) {
                try {
                    // Read from the InputStream
                    buffer[bytes] = (byte) mmInStream.read();
                    String arduinoMsg = null;

                    // Parsing the incoming data stream
                    if (buffer[bytes] == '\n'){
                        arduinoMsg = new String(buffer,0,bytes);
                        Log.e("Arduino Message",arduinoMsg);
                        handler.obtainMessage(MESSAGE_READ,arduinoMsg).sendToTarget();
                        bytes = 0;
                    } else {
                        bytes++;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    break;
                }
            }
        }

        // Send command to Arduino Board
        // This method must be called from Main Thread
        public void write(String input) {
            byte[] bytes = input.getBytes(); //converts entered String into bytes
            try {
                mmOutStream.write(bytes);
            } catch (IOException e) { }
        }
    }
}

description[java] android studio control droiduino bluetooth arduino with bluetooth EmptyRe: [java] android studio control droiduino bluetooth arduino with bluetooth

more_horiz
###################################################################################
optional :

add animetions to the recycler view in the SelectDeviceActivity :


recycler animation beef up :

res, create anim folder, add :
1 item_animation_fall_down.xml :

XML:

Code:

<set xmlns:android="http://schemas.android.com/apk/res/android"

    android:duration="2000">



    <translate

        android:fromYDelta="-20%"

        android:toYDelta="0"

        android:interpolator="@android:anim/decelerate_interpolator"

        />



    <alpha

        android:fromAlpha="0"

        android:toAlpha="1"

        android:interpolator="@android:anim/decelerate_interpolator"

        />



    <scale

        android:fromXScale="105%"

        android:fromYScale="105%"

        android:toXScale="100%"

        android:toYScale="100%"

        android:pivotX="50%"

        android:pivotY="50%"

        android:interpolator="@android:anim/decelerate_interpolator"

        />



</set>


android:duration="2000" is how long the animation runs

and layout_animation_fall_down.xml :

XML:

<?xml version="1.0" encoding="utf-8"?>

<layoutAnimation

xmlns:android="http://schemas.android.com/apk/res/android"

android:animation="@anim/item_animation_fall_down"

android:delay="15%"

android:animationOrder="normal"

/>

bind the animation to the xml recycler widget like this view xml attribute :

android:layoutAnimation="@anim/layout_animation_fall_down"
^ put this in the recycler View in the selectdeviceactivity

description[java] android studio control droiduino bluetooth arduino with bluetooth EmptyRe: [java] android studio control droiduino bluetooth arduino with bluetooth

more_horiz
arduino code for this project

Code:

  /* Char to Integer conversion according to ASCII Table
  * this is used to convert command from Android
  * "w" = 119 --> turn on LED
  * "s" = 115 --> turn off LED
  * "d" = 100 --> make the LED blinking
  *
  */

int ledPin = 13; // Built-in LED
int androidCmd; // Command message from Android

void setup() {
  // LED Setup
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW); // LED is OFF by default
 
  // Bluetooth Setup
  Serial.begin(9600); // Default communication rate of the Bluetooth Module

}

void loop() {
  // Read incoming command from Android
  if (Serial.available() > 0){
    androidCmd = Serial.read();
    Serial.println(androidCmd); // For debug purpose
  }

  // Translate Android command into Action
  if (androidCmd == 119){ // Equivalent to the character "w"
    Serial.println("LED is ON/n"); // Send status message to Android
    digitalWrite(ledPin, HIGH); // Turn On LED
  } else {
    if (androidCmd == 115){ // Equivalent to the character "s"
      Serial.println("LED is OFF/n"); // Send status message to Android
      digitalWrite(ledPin, LOW); // Turn Off LED
    } else {
      if (androidCmd == 100){ // Equivalent to the character "d"
        Serial.println("LED is Blinking/n"); // Send status message to Android
        blinkingLed(); // LED is blinking
      }
    }
  }
}

// Function to Blink LED
// Called from the loop function
void blinkingLed(){
  digitalWrite(ledPin,HIGH);
  delay(500);
  digitalWrite(ledPin,LOW);
  delay(500);
}
privacy_tip Permissions in this forum:
You cannot reply to topics in this forum
power_settings_newLogin to reply