arduino蓝牙控制程序_创建自定义的android应用程序以使用蓝牙控制arduino板

arduino蓝牙控制程序

This tutorial is about creating your custom Android app to connect with an Arduino board using Bluetooth. Consequently, some basic prior knowledge of Android programming is required to follow this tutorial.

本教程是关于创建自定义Android应用程序以使用蓝牙与Arduino开发板连接的。 因此,遵循本教程需要具备一些Android编程的先验知识。

But don’t worry, if you don’t have basic knowledge on Android programming but still want to create your own Bluetooth app, then you can take the Basic Android Programming for Arduino Makers that is available in Udemy. You will learn how to create a Bluetooth app that can talk with your Arduino board from scratch and without prior knowledge in Android programming required.

但请放心,如果您不具备Android编程的基本知识,但仍想创建自己的蓝牙应用程序,那么可以采用Udemy中提供的Arduino Makers基本Android编程。 您将学习如何创建一个蓝牙应用程序,该应用程序可以从头开始与Arduino板通信,而无需事先具备Android编程知识。

The codes presented in this tutorial is the minimum codes that enable an Android phone and Arduino board to send and receive messages (that can be translated into commands) with each other through Bluetooth.

本教程中介绍的代码是使Android手机和Arduino开发板能够通过蓝牙相互发送和接收消息(可以转换为命令)的最小代码。

开发环境 (Development environment)

To manage some expectations in case the app doesn’t work like it’s supposed to be, this is the environment I use to develop this app:

为了在应用程序无法正常运行时管理一些期望,这是我用来开发该应用程序的环境:

  1. Samsung Galaxy S8, with Android version 9.

    三星Galaxy S8,带有Android版本9。
  2. Android Studio version 3.6.3 with compatible Gradle version.

    Android Studio版本3.6.3与兼容的Gradle版本。
  3. Minimum SDK Version: 19 (You need to select this when creating a new project using Android Studio).

    最低SDK版本:19(使用Android Studio创建新项目时,需要选择此版本)。
  4. Mac OS 10.15.4 (Windows machines also works perfectly)

    Mac OS 10.15.4(Windows机器也可以正常运行)

这个应用程式的运作方式 (How this app works)

This app will create a Bluetooth connection with a nearby Arduino board that has been connected with the HC05 Bluetooth module. It is created to be compatible with Arduino board from this tutorial. However, it is easy to modify the codes so that it can be used together with Arduino boards with different configurations.

此应用程序将与附近已与HC05蓝牙模块连接的Arduino板创建蓝牙连接。 通过创建本教程可以使其与Arduino开发板兼容。 但是,修改代码很容易,因此可以与具有不同配置的Arduino板一起使用。

To test Bluetooth connection functionality, you can press the button on this App to control a built-in LED on the Arduino board. Once a predefined command message is received from Android, Arduino will transmit a return message to Android as a status message.

要测试蓝牙连接功能,您可以按此应用上的按钮以控制Arduino板上的内置LED。 从Android接收到预定义的命令消息后,Arduino将向状态消息发送一条返回消息到Android。

在Android上创建蓝牙连接 (Creating Bluetooth Connection on Android)

Before we dive into the coding part, I would like to describe the step by step flow to create a Bluetooth connection on Android. This is a summary of the more detailed documentation from Google.

在深入研究编码部分之前,我将逐步介绍在Android上创建蓝牙连接的流程。 这是Google更详细的文档的摘要。

  1. Initialize the default Bluetooth adapter (device) on your Android phone.

    初始化Android手机上的默认蓝牙适配器(设备)。
  2. Get the MAC Address from the remote device that you are connecting to. In this case, the MAC Address of HC05 Bluetooth module connected to Arduino board.

    从您要连接的远程设备获取MAC地址。 在这种情况下,HC05蓝牙模块的MAC地址连接到Arduino板。
  3. Create a separate thread in your code to initiate a connection using the MAC Address that we previously obtained. This thread will manage what happens if a connection is successfully established or failed to be established. It also handles if we want to close the Bluetooth connection.

    在代码中创建一个单独的线程,以使用我们先前获得的MAC地址启动连接。 如果成功建立连接或建立连接失败,该线程将管理发生的情况。 它还可以处理是否要关闭蓝牙连接。
  4. Once a connection is successfully established, the thread will do callback for the codes that manage data exchange (transmit and receive between 2 devices). For this, we need to create another thread.

    成功建立连接后,线程将对管理数据交换的代码进行回调(在2个设备之间进行发送和接收)。 为此,我们需要创建另一个线程。
  5. This thread will read incoming data transmission and parse it if necessary (or you can parse it elsewhere on the code) and transmit the message or command that is generated by the Android app.

    该线程将读取传入的数据传输并在必要时对其进行解析(或者您可以在代码的其他位置进行解析),并传输由Android应用生成的消息或命令。

Now, the flow above needs to be translated into codes.

现在,以上流程需要转换为代码。

创建活动和Java类 (Creating Activities and Java Class)

Create a new project with the empty activity template and select the appropriate name for your app. For this app we will create 2 activities and 2 Java classes :

使用空的活动模板创建一个新项目,然后为您的应用选择适当的名称。 对于这个应用程序,我们将创建2个活动和2个Java类:

  1. MainActivity. This is automatically created when you create a new project. This is where most of the interactions take place.

    主要活动。 当您创建新项目时,将自动创建该文件。 这是大多数交互发生的地方。
  2. SelectDeviceActivity. The UI where you select the Bluetooth device that you want to connect.

    选择设备活动。 在其中选择要连接的蓝牙设备的UI。
  3. DeviceListAdapter. A class to display a list of paired Bluetooth devices for you to connect. The list will be displayed in SelectDeviceActivity.

    DeviceListAdapter。 显示配对的蓝牙设备列表以供您连接的类。 该列表将显示在SelectDeviceActivity中。
  4. DeviceInfoModel. A class that acts as a placeholder for the remote device information.

    DeviceInfoModel。 充当远程设备信息的占位符的类。

AndroidManifest.xml (AndroidManifest.xml)

Once you created all the activities and classes above, your AndroidManifest.xml file will look something like this :

一旦创建了以上所有活动和类,您的AndroidManifest.xml文件将如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.droiduino.bluetoothconn">


    <!--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" />


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".SelectDeviceActivity"></activity>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />


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


</manifest>

Please note that you should add the Bluetooth permission so that you can access your phone’s Bluetooth device.

请注意,您应该添加蓝牙权限,以便可以访问手机的蓝牙设备。

MainActivity布局 (MainActivity Layout)

MainActivity is the main UI where you can interact with the interfaces that will connect you to a remote Bluetooth device and control it.

MainActivity是主用户界面,您可以在其中与将您连接到远程蓝牙设备并对其进行控制的界面进行交互。

Image for post
Main Screen Layout
主画面布局

The XML code for the layout above is like this:

上面布局的XML代码如下所示:

<?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:id="@+id/constrainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/background_light"
    tools:context=".MainActivity">


    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        android:theme="?attr/actionBarTheme"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:subtitleTextColor="@android:color/background_light"
        app:title="Bluetooth Connection"
        app:titleTextColor="@android:color/background_light" />


    <ImageView
        android:id="@+id/imageView"
        android:layout_width="200dp"
        android:layout_height="300dp"
        android:layout_marginTop="24dp"
        android:background="@color/colorOff"
        android:contentDescription="Visual LED"
        android:scaleType="centerCrop"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"
        app:srcCompat="@drawable/ic_bulb_light"
        tools:ignore="VectorDrawableCompat" />


    <Button
        android:id="@+id/buttonConnect"
        style="@style/Widget.AppCompat.Button.Borderless"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Connect"
        android:textColor="@android:color/background_light"
        app:layout_constraintBottom_toBottomOf="@+id/toolbar"
        app:layout_constraintEnd_toEndOf="@+id/toolbar"
        app:layout_constraintTop_toTopOf="@+id/toolbar" />


    <Button
        android:id="@+id/buttonToggle"
        style="@style/Widget.AppCompat.Button.Colored"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="400dp"
        android:text="Turn On"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        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/textViewInfo"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:textAlignment="center"
        android:textStyle="italic"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/buttonToggle" />




</androidx.constraintlayout.widget.ConstraintLayout>

SelectDeviceActivity布局(SelectDeviceActivity Layout)

This activity will display a list of remote Bluetooth devices that are already paired with your phone. It is shown when the “Connect” button is clicked on the MainActivity. The layout XML code for this activity is as follows:

此活动将显示已与手机配对的远程蓝牙设备的列表。 单击MainActivity上的“连接”按钮时,将显示该图标。 此活动的布局XML代码如下:

<?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/recyclerViewDevice"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity代码(MainActivity Code)

Now we continue with the code. Code in MainActivity is the one creating a Bluetooth connection to a remote device. You can just copy and paste the code below to your project. Some comments have been added to the code you can understand it better.

现在,我们继续代码。 MainActivity中的代码是用于创建到远程设备的蓝牙连接的代码。 您可以将以下代码复制并粘贴到您的项目中。 一些注释已添加到代码中,您可以更好地理解它。

package com.droiduino.bluetoothconn;


import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;


import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.DialogInterface;
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.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;




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


import static android.content.ContentValues.TAG;


public class MainActivity extends AppCompatActivity {


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


    private final static int CONNECTING_STATUS = 1; // used in bluetooth handler to identify message status
    private final static int MESSAGE_READ = 2; // used in bluetooth handler to identify message update


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


        // UI Initialization
        final Button buttonConnect = findViewById(R.id.buttonConnect);
        final Toolbar toolbar = findViewById(R.id.toolbar);
        final ProgressBar progressBar = findViewById(R.id.progressBar);
        progressBar.setVisibility(View.GONE);
        final TextView textViewInfo = findViewById(R.id.textViewInfo);
        final Button buttonToggle = findViewById(R.id.buttonToggle);
        buttonToggle.setEnabled(false);
        final ImageView imageView = findViewById(R.id.imageView);
        imageView.setBackgroundColor(getResources().getColor(R.color.colorOff));


        // If a bluetooth device has been selected from SelectDeviceActivity
        deviceName = getIntent().getStringExtra("deviceName");
        if (deviceName != null){
            // Get the device address to make BT Connection
            deviceAddress = getIntent().getStringExtra("deviceAddress");
            // Show progree and connection status
            toolbar.setSubtitle("Connecting to " + deviceName + "...");
            progressBar.setVisibility(View.VISIBLE);
            buttonConnect.setEnabled(false);


            /*
            This is the most important piece of code. When "deviceName" is found
            the code will call a new thread to create a bluetooth connection to the
            selected device (see the thread code below)
             */
            BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            createConnectThread = new CreateConnectThread(bluetoothAdapter,deviceAddress);
            createConnectThread.start();
        }


        /*
        Second most important piece of Code. GUI Handler
         */
        handler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg){
                switch (msg.what){
                    case CONNECTING_STATUS:
                        switch(msg.arg1){
                            case 1:
                                toolbar.setSubtitle("Connected to " + deviceName);
                                progressBar.setVisibility(View.GONE);
                                buttonConnect.setEnabled(true);
                                buttonToggle.setEnabled(true);
                                break;
                            case -1:
                                toolbar.setSubtitle("Device fails to connect");
                                progressBar.setVisibility(View.GONE);
                                buttonConnect.setEnabled(true);
                                break;
                        }
                        break;


                    case MESSAGE_READ:
                        String arduinoMsg = msg.obj.toString(); // Read message from Arduino
                        switch (arduinoMsg.toLowerCase()){
                            case "led is turned on":
                                imageView.setBackgroundColor(getResources().getColor(R.color.colorOn));
                                textViewInfo.setText("Arduino Message : " + arduinoMsg);
                                break;
                            case "led is turned off":
                                imageView.setBackgroundColor(getResources().getColor(R.color.colorOff));
                                textViewInfo.setText("Arduino Message : " + arduinoMsg);
                                break;
                        }
                        break;
                }
            }
        };


        // Select Bluetooth Device
        buttonConnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Move to adapter list
                Intent intent = new Intent(MainActivity.this, SelectDeviceActivity.class);
                startActivity(intent);
            }
        });


        // Button to ON/OFF LED on Arduino Board
        buttonToggle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String cmdText = null;
                String btnState = buttonToggle.getText().toString().toLowerCase();
                switch (btnState){
                    case "turn on":
                        buttonToggle.setText("Turn Off");
                        // Command to turn on LED on Arduino. Must match with the command in Arduino code
                        cmdText = "<turn on>";
                        break;
                    case "turn off":
                        buttonToggle.setText("Turn On");
                        // Command to turn off LED on Arduino. Must match with the command in Arduino code
                        cmdText = "<turn off>";
                        break;
                }
                // Send command to Arduino board
                connectedThread.write(cmdText);
            }
        });
    }


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


        public CreateConnectThread(BluetoothAdapter bluetoothAdapter, String address) {
            /*
            Use a temporary object that is later assigned to mmSocket
            because mmSocket is final.
             */
            BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(address);
            BluetoothSocket tmp = null;
            UUID uuid = bluetoothDevice.getUuids()[0].getUuid();


            try {
                /*
                Get a BluetoothSocket to connect with the given BluetoothDevice.
                Due to Android device varieties,the method below may not work fo different devices.
                You should try using other methods i.e. :
                tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
                 */
                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 remote device through the socket. This call blocks
                // until it succeeds or throws an exception.
                mmSocket.connect();
                Log.e("Status", "Device connected");
                handler.obtainMessage(CONNECTING_STATUS, 1, -1).sendToTarget();
            } catch (IOException connectException) {
                // Unable to connect; close the socket and return.
                try {
                    mmSocket.close();
                    Log.e("Status", "Cannot connect to device");
                    handler.obtainMessage(CONNECTING_STATUS, -1, -1).sendToTarget();
                } catch (IOException closeException) {
                    Log.e(TAG, "Could not close the client socket", closeException);
                }
                return;
            }


            // The connection attempt succeeded. Perform work associated with
            // the connection in a separate thread.
            connectedThread = new ConnectedThread(mmSocket);
            connectedThread.run();
        }


        // Closes the client socket and causes the thread to finish.
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
                Log.e(TAG, "Could not close the client socket", e);
            }
        }
    }


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


        public ConnectedThread(BluetoothSocket socket) {
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;


            // Get the input and output streams, using temp objects because
            // member streams are final
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) { }


            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }


        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 from Arduino until termination character is reached.
                    Then send the whole String message to GUI Handler.
                     */
                    buffer[bytes] = (byte) mmInStream.read();
                    String readMessage;
                    if (buffer[bytes] == '\n'){
                        readMessage = new String(buffer,0,bytes);
                        Log.e("Arduino Message",readMessage);
                        handler.obtainMessage(MESSAGE_READ,readMessage).sendToTarget();
                        bytes = 0;
                    } else {
                        bytes++;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    break;
                }
            }
        }


        /* Call this from the main activity to send data to the remote device */
        public void write(String input) {
            byte[] bytes = input.getBytes(); //converts entered String into bytes
            try {
                mmOutStream.write(bytes);
            } catch (IOException e) {
                Log.e("Send Error","Unable to send message",e);
            }
        }


        /* Call this from the main activity to shutdown the connection */
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
    }


    /* ============================ Terminate Connection at BackPress ====================== */
    @Override
    public void onBackPressed() {
        // Terminate Bluetooth Connection and close app
        if (createConnectThread != null){
            createConnectThread.cancel();
        }
        Intent a = new Intent(Intent.ACTION_MAIN);
        a.addCategory(Intent.CATEGORY_HOME);
        a.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(a);
    }
}

I make some minor style changes to the color resources.

我对颜色资源进行了一些小的样式更改。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#6200EE</color>
    <color name="colorPrimaryDark">#3700B3</color>
    <color name="colorAccent">#03DAC5</color>
    <color name="colorOff">#000000</color>
    <color name="colorOn">#FF8800</color>
</resources>

SelectDeviceActivity,DeviceListAdapter和DeviceInfoModel(SelectDeviceActivity, DeviceListAdapter and DeviceInfoModel)

This activity works with DeviceListAdapter class and DeviceInfoModel class to display the list of paired devices.

此活动与DeviceListAdapter类和DeviceInfoModel类一起使用以显示已配对设备的列表。

SelectDeviceActivity.java

SelectDeviceActivity.java

package com.droiduino.bluetoothconn;


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


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


import com.google.android.material.snackbar.Snackbar;


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);


        // Bluetooth Setup
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();


        // Get List of Paired Bluetooth Device
        Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
        List<Object> deviceList = new ArrayList<>();
        if (pairedDevices.size() > 0) {
            // There are paired devices. Get the name and address of each paired device.
            for (BluetoothDevice device : pairedDevices) {
                String deviceName = device.getName();
                String deviceHardwareAddress = device.getAddress(); // MAC address
                DeviceInfoModel deviceInfoModel = new DeviceInfoModel(deviceName,deviceHardwareAddress);
                deviceList.add(deviceInfoModel);
            }
            // Display paired device using recyclerView
            RecyclerView recyclerView = findViewById(R.id.recyclerViewDevice);
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
            DeviceListAdapter deviceListAdapter = new DeviceListAdapter(this,deviceList);
            recyclerView.setAdapter(deviceListAdapter);
            recyclerView.setItemAnimator(new DefaultItemAnimator());
        } else {
            View view = findViewById(R.id.recyclerViewDevice);
            Snackbar snackbar = Snackbar.make(view, "Activate Bluetooth or pair a Bluetooth device", Snackbar.LENGTH_INDEFINITE);
            snackbar.setAction("OK", new View.OnClickListener() {
                @Override
                public void onClick(View view) { }
            });
            snackbar.show();
        }


    }
}

DeviceListAdapter.java

DeviceListAdapter.java

package com.droiduino.bluetoothconn;


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


import androidx.recyclerview.widget.RecyclerView;


import java.util.List;


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


    private Context context;
    private List<Object> deviceList;


    public static class ViewHolder extends RecyclerView.ViewHolder {
        TextView textName, textAddress;
        LinearLayout linearLayout;


        public ViewHolder(View v) {
            super(v);
            textName = v.findViewById(R.id.textViewDeviceName);
            textAddress = v.findViewById(R.id.textViewDeviceAddress);
            linearLayout = v.findViewById(R.id.linearLayoutDeviceInfo);
        }
    }


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


    }


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


    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
        ViewHolder itemHolder = (ViewHolder) holder;
        final DeviceInfoModel deviceInfoModel = (DeviceInfoModel) deviceList.get(position);
        itemHolder.textName.setText(deviceInfoModel.getDeviceName());
        itemHolder.textAddress.setText(deviceInfoModel.getDeviceHardwareAddress());


        // When a device is selected
        itemHolder.linearLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(context,MainActivity.class);
                // Send device details to the MainActivity
                intent.putExtra("deviceName", deviceInfoModel.getDeviceName());
                intent.putExtra("deviceAddress",deviceInfoModel.getDeviceHardwareAddress());
                // Call MainActivity
                context.startActivity(intent);


            }
        });
    }


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

DeviceInfoModel.java

DeviceInfoModel.java

package com.droiduino.bluetoothconn;


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;}


}

The whole Android project is also available on Github.

整个Android项目也可以在Github上获得

Once you build the whole project, you need to install the app to your actual device to be able to use the Bluetooth function.

构建完整个项目后,您需要将应用程序安装到实际设备上,才能使用蓝牙功能。

Note: Due to periodic update to the app, the Github version might slightly different from the code in this post. But the core function remains the same.

注意:由于该应用程序的定期更新,Github版本可能与本文中的代码略有不同。 但是核心功能保持不变。

修改Arduino代码 (Modifying the Arduino Code)

We need to make some small modifications to the Arduino code from this tutorial. You can create a new Arduino sketch and copy-paste the code below.

我们需要从本教程中对Arduino代码进行一些小的修改。 您可以创建一个新的Arduino草图并复制粘贴以下代码。

const int ledPin = 13; // Built in LED in Arduino board
String msg,cmd;


void setup() {
  // Initialization
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  Serial.begin(9600); // Communication rate of the Bluetooth Module
  msg = "";
}


void loop() {
  
  // To read message received from other Bluetooth Device
  if (Serial.available() > 0){ // Check if there is data coming
    msg = Serial.readString(); // Read the message as String
    Serial.println("Android Command: " + msg);
  }


  // Control LED in Arduino board
  if (msg == "<turn on>"){
    digitalWrite(ledPin, HIGH); // Turn on LED
    Serial.println("LED is turned on\n"); // Then send status message to Android
    msg = ""; // reset command
  } else {
    if (msg == "<turn off>"){
      digitalWrite(ledPin, LOW); // Turn off LED
      Serial.println("LED is turned off\n"); // Then send status message to Android
      msg = ""; // reset command
    }
  }
}

Don’t forget to compile and upload the code to your Arduino board. You can also go to Github to get this code.

不要忘了编译并将代码上传到Arduino开发板。 您也可以转到Github获取此代码。

将Android连接到Arduino… (Connecting Android to Arduino…)

Follow the steps below to connect your phone to the Arduino board

请按照以下步骤将手机连接到Arduino开发板

  1. Connect HC05 module to the Arduino board as described in the previous post then connect it to a power supply. The LED on HC05 module should be blinking fast.

    一篇文章所述,将HC05模块连接至Arduino板,然后将其连接至电源。 HC05模块上的LED指示灯应快速闪烁。

  2. Activate Bluetooth on your phone and pair HC05 with your phone. The device name you’re looking for is “HC-05”. You don’t need your app yet for pairing with HC05.

    在手机上激活蓝牙,然后将HC05与手机配对。 您要查找的设备名称是“ HC-05”。 与HC05配对时,您还不需要您的应用程序。
  3. Now open your app and press the “Connect” button. A list of paired devices will be shown on screen. If you change the device name when you’re pairing with HC05, you actually only change the alias name. Your app only shows the device name, so select “HC-05”.

    现在打开您的应用程序,然后按“连接”按钮。 配对设备的列表将显示在屏幕上。 如果与HC05配对时更改设备名称,则实际上仅更改别名。 您的应用仅显示设备名称,因此选择“ HC-05”。
  4. Once HC05 is connected, there will be status on the toolbar and the LED button will be enabled. You know when HC05 is connected when the LED on HC05 blinks slowly.

    连接HC05后,工具栏上将显示状态,并且LED按钮将启用。 当HC05上的LED缓慢闪烁时,您知道何时连接HC05。

…并测试数据交换 (…And Test the Data Exchange)

Now, you can press the LED button and watch the built-in LED on Arduino turned on and off. Visually, you can also see the light bulb image on your phone change color to indicate LED status. The color changes when your phone receives the status message from Arduino, so you might notice some delay between the change on LED on Arduino with the light bulb image on your phone.

现在,您可以按下LED按钮,并观察Arduino上的内置LED打开和关闭。 视觉上,您还可以看到手机上的灯泡图像变色以指示LED状态。 当手机从Arduino收到状态消息时,颜色会发生变化,因此您可能会注意到Arduino上的LED指示灯更改与手机上的灯泡图像之间存在一些延迟。

下一步是什么 (What’s next)

You have now understood one of the methods to connect your Android phone to an Arduino board. Exciting new possibilities are now available for you. For example, you can:

您现在已经了解了将Android手机连接到Arduino开发板的方法之一。 激动人心的新可能性现已为您提供。 例如,您可以:

  1. Improve the app so that it shows alert when Bluetooth function on your phone is not yet activated.

    改进应用程序,使其在手机上的蓝牙功能尚未激活时显示警报。
  2. Add more codes on Arduino so now your app can control 2 LEDs

    在Arduino上添加更多代码,现在您的应用可以控制2个LED
  3. Connect a simple sensor on Arduino e.g. proximity sensor and read the values on your phone.

    在Arduino上连接一个简单的传感器,例如接近传感器,并读取手机上的值。
  4. And many more. If you can imagine it, you can create it.

    还有很多。 如果可以想象,可以创建它。

If you find this tutorial is too difficult to follow or if you don’t have prior knowledge in Android programming, then you can always take the course Basic Android Programming For Arduino Makers in Udemy which will guide you to create your own Bluetooth app from scratch.

如果您发现本教程太难理解或不了解Android编程,那么您可以随时选择Udemy上的Arduino Makers基础Android编程课程,该课程将指导您从头开始创建自己的蓝牙应用。

翻译自: https://medium.com/swlh/create-custom-android-app-to-control-arduino-board-using-bluetooth-ff878e998aa8

arduino蓝牙控制程序

已标记关键词 清除标记
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页