蓝牙控制小车教程:STC89C52RC + HC-06蓝牙模块

目录

前期准备:

开发环境:

设备:单片机(以STC89C52RC为例),HC-06 , 串口下载器

IDE:AndroidStudio , keil4

工具:串口调试助手  , stc-isp

设备测试:

安卓端开发:

UI界面:

编辑

应用测试:

小车开发:

串口通讯:


 

前期准备:

        开发环境:

                设备:单片机(以STC89C52RC为例),HC-06 , 串口下载器

                IDE:AndroidStudio , keil4

                工具:串口调试助手  , stc-isp

                        关于AndroidStudio(AS)安装的教程网上很多 不多说

                        keil4/keil5 大家也能找到很多教程 跳过

                        工具:单开发工具.zip - 蓝奏云

          设备测试:

                        将HC-06模块与下载器模块相连接,连接电脑(杜邦线丢了先不上图)

                        RXD 与 TXD相连接, GND与GND 连接, UCC 与 5v 连接

                        安装CH340驱动 CH341SER.zip - 蓝奏云

                                1.按win+r 输入 devmgmt.msc 打开设备管理器

                               2.开启 串口 子目录 查看CH340是否正常(无感叹号)b7f129b678974f0cb80252027a9b288c.png

                                3. 如果出错 删掉重复的端口 (COM3这样的) ,重新拔插,安装驱动

                                4.打开串口调试助手2.2 端口选择CH340的端口 文本形势发送 AT 若正常则返回OK

                                5.通过 AT指令修改值 : 特别是名称 和 波特率

                        上述无异常则设备正常

安卓端开发:

        创建个空项目,然后做个自己喜欢的    

        UI界面:

                   最右上角有个Design Split Code 点Code 输入代码

   2677b67ef55e455488864f93c2b76153.png

 

 

 

 

 

 

 

 

代码

<?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">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="fitXY"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="1.0"
        app:srcCompat="@mipmap/background" />

    <SeekBar
        android:id="@+id/bar_left"
        android:layout_width="250dp"
        android:layout_height="60dp"
        android:background="@mipmap/bar_background"
        android:max="40"
        android:progress="20"
        android:progressDrawable="@android:drawable/divider_horizontal_dim_dark"
        android:rotation="270"
        android:thumb="@mipmap/bar_dot"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.504" />

    <SeekBar
        android:id="@+id/bar_right"
        android:layout_width="250dp"
        android:layout_height="60dp"
        android:background="@mipmap/bar_background"
        android:max="40"
        android:progress="20"
        android:progressDrawable="@android:drawable/divider_horizontal_dim_dark"
        android:rotation="270"
        android:thumb="@mipmap/bar_dot"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.498" />

    <TableRow
        android:id="@+id/tableRow"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="100dp"
        android:layout_marginBottom="50dp"
        android:background="#aa777777"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/bar_right"
        app:layout_constraintStart_toEndOf="@+id/bar_left"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:background="#aa777777"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:outlineProvider="none"
        android:overScrollMode="ifContentScrolls"
        android:scrollbars="horizontal"
        app:layout_constraintBottom_toTopOf="@+id/tableRow"
        app:layout_constraintEnd_toStartOf="@+id/bar_right"
        app:layout_constraintStart_toEndOf="@+id/bar_left"
        app:layout_constraintTop_toTopOf="@+id/imageView"
        app:layout_constraintVertical_bias="0.65999997">

        <Switch
            android:id="@+id/switch_hctr"
            android:layout_width="85dp"
            android:layout_height="wrap_content"
            android:layout_weight="20"
            android:text="手控"
            android:textColor="#EEEEEE"
            tools:ignore="TouchTargetSizeCheck,VisualLintButtonSize" />

        <Switch
            android:id="@+id/switch_srt"
            android:layout_width="90dp"
            android:layout_height="wrap_content"
            android:layout_weight="20"
            android:text="循迹"
            android:textColor="#EEEEEE"
            tools:ignore="TouchTargetSizeCheck,VisualLintButtonSize" />

        <Switch
            android:id="@+id/switch_stp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="20"
            android:checked="true"
            android:text="停止"
            android:textColor="#EEEEEE"
            tools:ignore="TouchTargetSizeCheck,VisualLintButtonSize" />

        <Switch
            android:id="@+id/switch_etd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="20"
            android:text="没想好"
            android:textColor="#EEEEEE"
            tools:ignore="TouchTargetSizeCheck,VisualLintButtonSize" />
    </LinearLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/bluetooth_cont"
        android:layout_width="450dp"
        android:layout_height="0dp"
        android:layout_marginStart="-400dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ListView
            android:id="@+id/bluetooth_list"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginEnd="50dp"
            android:background="#9500BCD4"
            android:paddingStart="10dp"
            android:paddingTop="10dp"
            android:paddingEnd="10dp"
            android:paddingBottom="10dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="1.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

        </ListView>

        <ImageButton
            android:id="@+id/bluetooth_btn"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:scaleType="fitXY"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@mipmap/bluetooth"
            tools:ignore="SpeakableTextPresentCheck" />

        <ImageButton
            android:id="@+id/bluetooth_connect"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:scaleType="fitXY"
            app:layout_constraintBottom_toBottomOf="@+id/bluetooth_list"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/bluetooth_list"
            app:layout_constraintTop_toBottomOf="@+id/bluetooth_btn"
            app:layout_constraintVertical_bias="0.3"
            app:srcCompat="@mipmap/connect"
            tools:ignore="SpeakableTextPresentCheck" />

    </androidx.constraintlayout.widget.ConstraintLayout>


</androidx.constraintlayout.widget.ConstraintLayout>

                可以直接抄

 

                MainActivity 代码(绑定点事件罢了 直接抄!!!!!(我是自己写的啊))

package com.alray.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import java.lang.reflect.Method;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    private final int REQ_PERMISSION_CODE = 1;
    // 蓝牙权限列表
    public ArrayList<String> requestList = new ArrayList<>();
    private IntentFilter foundFilter;
    private Context mContext;
    private Bluetooth bluetoothController;

    ArrayList<BluetoothDevice> connectedDevices = new ArrayList<BluetoothDevice>();

    private Toast mToast;
    private Activity ac;

    // 蓝牙状态改变广播
    private BroadcastReceiver receiver = new BroadcastReceiver(){

        @Override
        public void onReceive(Context context, Intent intent) {
            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
            switch (state){
                case BluetoothAdapter.STATE_OFF:
                    showToast("STATE_OFF");
                    break;
                case BluetoothAdapter.STATE_ON:
                    showToast("STATE_ON");
                    break;
                case BluetoothAdapter.STATE_TURNING_OFF:
                    showToast("STATE_TURNING_OFF");
                    break;
                case BluetoothAdapter.STATE_TURNING_ON:
                    showToast("STATE_TURNING_ON");
                    break;
                default:
                    unregisterReceiver(this);
                    break;
            }
        }
    };
    //蓝牙搜索广播
    private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver()
    {
        @SuppressLint("MissingPermission")
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                String s;
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                getPermision();
                if (device.getBondState() == 12) {
                    s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
                    bluetoothController.Connect(device);
                    connectedDevices.add(device);
                }
                else if (device.getBondState() == 10){
                    s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" +"\n";
                } else{
                    s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未知" + "\n";
                }
                if (!deviceName.contains(s)) {
                    deviceName.add(s);//将搜索到的蓝牙名称和地址添加到列表。
                    arrayList.add(device.getAddress());//将搜索到的蓝牙地址添加到列表。
                    adapter1.notifyDataSetChanged();//更新
                }
            }  else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                unregisterReceiver(this);
            } else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
            }
        }
    };

    ArrayAdapter adapter1;
    //定义一个列表,存蓝牙设备的地址。
    public ArrayList<String> arrayList = new ArrayList<>();
    //定义一个列表,存蓝牙设备地址,用于显示。
    public ArrayList<String> deviceName = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getSupportActionBar().hide();
        bluetoothController = new Bluetooth();
        bluetoothController.setAc(this);

        // 蓝牙状态改变信息
        IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        // 注册广播
        registerReceiver(receiver, filter);

        //搜索蓝牙的广播
        foundFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        foundFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        foundFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        foundFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);

        ac = this;
        ord();
    }

    private void unpairDevice(BluetoothDevice device){
        try {
            Method m = device.getClass()
                    .getMethod("removeBond", (Class[]) null);
            m.invoke(device, (Object[]) null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void ord() {
        SeekBar bar_left = (SeekBar) findViewById(R.id.bar_left);
        SeekBar bar_right = (SeekBar) findViewById(R.id.bar_right);
        bar_left.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                bluetoothController.sendMessageHandle(String.format("L%02d\r\n",seekBar.getProgress()));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                seekBar.setProgress(20);
            }
        });
        bar_right.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                bluetoothController.sendMessageHandle(String.format("R%02d\r\n",seekBar.getProgress()));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                seekBar.setProgress(20);
            }
        });

        Switch switch_hctr = (Switch) findViewById(R.id.switch_hctr);
        Switch switch_srt = (Switch) findViewById(R.id.switch_srt);
        Switch switch_stp = (Switch) findViewById(R.id.switch_stp);
        switch_stp.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    switch_hctr.setChecked(false);
                    switch_srt.setChecked(false);
                    bluetoothController.sendMessageHandle("OP\r\n");
                } else {
                    if (switch_hctr.isChecked() || switch_srt.isChecked())
                        return;
                    switch_stp.setChecked(true);
                }
            }
        });
        switch_srt.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    switch_hctr.setChecked(false);
                    switch_stp.setChecked(false);
                    bluetoothController.sendMessageHandle("OS\r\n");
                } else {
                    if (switch_hctr.isChecked() || switch_stp.isChecked())
                        return;
                    switch_srt.setChecked(true);
                }
            }
        });
        switch_hctr.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    switch_stp.setChecked(false);
                    switch_srt.setChecked(false);
                    bluetoothController.sendMessageHandle("OH\r\n");
                } else {
                    if (switch_stp.isChecked() || switch_srt.isChecked())
                        return;
                    switch_hctr.setChecked(true);
                }
            }
        });

        ImageButton bluetooth_connect = (ImageButton)findViewById(R.id.bluetooth_connect);
        ImageButton bluetooth_btn = (ImageButton) findViewById(R.id.bluetooth_btn);
        ConstraintLayout bluetooth_cont = (ConstraintLayout) findViewById(R.id.bluetooth_cont);
        ListView bluetooth_List = (ListView) findViewById(R.id.bluetooth_list);
        int marginStart = ((ConstraintLayout.LayoutParams) (bluetooth_cont.getLayoutParams())).getMarginStart();
        bluetooth_btn.setOnClickListener(new View.OnClickListener() {
            @SuppressLint("MissingPermission")
            @Override
            public void onClick(View v) {

                ConstraintLayout.LayoutParams lp = (ConstraintLayout.LayoutParams) (bluetooth_cont.getLayoutParams());
                if (lp.getMarginStart() == 0) {
                    lp.setMarginStart(marginStart);
                    bluetoothController.cancelSearch();
                }
                else {
                    lp.setMarginStart(0);
                    getPermision();
                    bluetoothController.turnOnBlueTooth(ac,1);
                    // 初始化各列表
                    arrayList.clear();
                    deviceName.clear();
                    adapter1.notifyDataSetChanged();
                    getPermision();
                    for (BluetoothDevice device: connectedDevices) {

                        String s;
                        s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
                        if (deviceName.contains(s))
                            deviceName.remove(s);
                        s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已连接" + "\n";
                        deviceName.add(s);//将搜索到的蓝牙名称和地址添加到列表。
                        arrayList.add(device.getAddress());//将搜索到的蓝牙地址添加到列表。
                        adapter1.notifyDataSetChanged();//更新
                    }
                    registerReceiver(bluetoothReceiver, foundFilter);
                    // 开始搜索
                    bluetoothController.findDevice();
                }
                bluetooth_cont.setLayoutParams(lp);
            }
        });
        bluetooth_connect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                for (BluetoothDevice device:connectedDevices) {
                    bluetoothController.Connect(device);
                }
            }
        });
        adapter1 = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, deviceName);
        bluetooth_List.setAdapter(adapter1);
        bluetooth_List.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @SuppressLint("MissingPermission")
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                CharSequence content = ((TextView) view).getText();
                String con = content.toString();
                String[] conArray = con.split("\n");
                String rightStr = conArray[1].substring(5, conArray[1].length());
                BluetoothDevice device = bluetoothController.find_device(rightStr);
                getPermision();
                if (device.getBondState() == 10) {
                    String s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" + "\n";
                    deviceName.remove(s);
                    if(device.createBond()) {
                        s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
                        connectedDevices.add(device);
                    }
                    deviceName.add(s);
                    adapter1.notifyDataSetChanged();
                } else {
                    String s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
                    if (deviceName.contains(s2)) {
                        unpairDevice(device);
                        connectedDevices.remove(device);
                        deviceName.remove(s2);
                        s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" + "\n";
                        deviceName.add(s2);
                        adapter1.notifyDataSetChanged();
                    }
                    s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已连接" + "\n";
                    if (deviceName.contains(s2)) {
                        unpairDevice(device);
                        connectedDevices.remove(device);
                        deviceName.remove(s2);
                        s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" + "\n";
                        deviceName.add(s2);
                        adapter1.notifyDataSetChanged();
                    }
                }
            }
        });
    }
    /**
     * 动态申请权限
     */
    public void getPermision(){
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
            requestList.add(Manifest.permission.BLUETOOTH_SCAN);
            requestList.add(Manifest.permission.BLUETOOTH_ADVERTISE);
            requestList.add(Manifest.permission.BLUETOOTH_CONNECT);
            requestList.add(Manifest.permission.ACCESS_FINE_LOCATION);
            requestList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
            requestList.add(Manifest.permission.BLUETOOTH);
        }
        if(requestList.size() != 0){
            ActivityCompat.requestPermissions(this, requestList.toArray(new String[0]), REQ_PERMISSION_CODE);
        }
    }
    public void showToast(String text){
        // 若Toast控件未初始化
        if( mToast == null){
            // 则初始化
            mToast = Toast.makeText(this, text, Toast.LENGTH_SHORT);
        }
        // 否则
        else{
            // 修改显示文本
            mToast.setText(text);
        }
        // 显示
        mToast.show();
    }
}

                其中的Bluetooth类为自定义类,自己新建个文件放进去

package com.alray.myapplication;


import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.ArrayMap;
import android.util.Log;
import android.widget.Toast;

import androidx.core.app.ActivityCompat;

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

@SuppressLint("MissingPermission")
public class Bluetooth {

    private static final int REQ_PERMISSION_CODE = 1;
    private BluetoothAdapter mAdapter;

    private BluetoothSocket bluetoothSocket;

    // 延时创建Toast类,
    private Toast mToast;
    private BTclient bTclient = new BTclient();
    private Activity ac;
    private Context context;

    public ArrayList<String> requestList = new ArrayList<>();

    public readThread readthread = new readThread();
    public Byte[] rdbuffer;

    // 活动间消息传递
    public  BTclient mClient = new BTclient();

    private class BTclient extends Thread{
        private void connectDevice(BluetoothDevice device){

            try {
                bluetoothSocket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
                bluetoothSocket.connect();
                readthread.start();
                showToast("蓝牙连接成功");
            }
            catch (IOException e)
            {
                showToast("蓝牙连接失败");
            }

        }
        private void disconnectDevice(BluetoothDevice device) {
            try {
                readthread.interrupt();
                bluetoothSocket.close();
                showToast("蓝牙断开");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    void Connect(BluetoothDevice device)
    {
        bTclient.connectDevice(device);
    }
    void setAc(Activity a)
    {
        ac = a;
    }
    void setCont(Context t){
        context = t;
    }

    public void sendMessageHandle(String msg)
    {
        if (bluetoothSocket == null)
        {
            return;
        }
        try {
            OutputStream os = bluetoothSocket.getOutputStream();
            os.write(msg.getBytes()); //发送出去的值为:msg
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //读取数据
    private class readThread extends Thread {
        private static final String TAG = "";

        public void run() {
            super.run();
            byte[] buffer = new byte[1024];
            int bytes;
            InputStream mmInStream = null;

            try {
                mmInStream = bluetoothSocket.getInputStream();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            while (true) {
                try {
                    // Read from the InputStream
                    if ((bytes = mmInStream.read(buffer)) > 0) {
                        byte[] buf_data = new byte[bytes];
                        for (int i = 0; i < bytes; i++) {
                            buf_data[i] = buffer[i];
                        }
                        String s = new String(buf_data);//接收的值inputstream 为 s
                    }
                } catch (IOException e) {
                    try {
                        mmInStream.close();
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                    break;
                }
            }
        }
    }

    public Bluetooth() {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
    }

    public boolean isSupportBlueTooth() {
        // 若支持蓝牙,则本地适配器不为null
        if (mAdapter != null) {
            return true;
        }
        // 否则不支持
        else {
            return false;
        }
    }

    public boolean getBlueToothStatus() {
        // 断言,为了避免mAdapter为null导致return出错
        assert (mAdapter != null);
        // 蓝牙状态
        return mAdapter.isEnabled();
    }

    public boolean turnOnBlueTooth(Activity activity, int requestCode) {
        if (!mAdapter.isEnabled()) {
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

            activity.startActivityForResult(intent, requestCode);
            return true;
        }
        return false;
    }

    public void turnOffBlueTooth() {
        if (mAdapter.isEnabled()) {
            mAdapter.disable();
        }
    }

    public void enableVisibly(Context context) {
        Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
        context.startActivity(discoverableIntent);
    }

    public boolean findDevice() {
        assert (mAdapter != null);
        if (mAdapter.isDiscovering()) {
            mAdapter.cancelDiscovery();
            return false;
        } else {
            return mAdapter.startDiscovery();
        }
    }

    public BluetoothDevice find_device(String addr){
        return mAdapter.getRemoteDevice(addr);
    }

    public ArrayList<BluetoothDevice> getBondedDeviceList() {
        return new ArrayList<BluetoothDevice>(mAdapter.getBondedDevices());
    }

    public void cancelSearch() {
        mAdapter.cancelDiscovery();
    }

    public void showToast(String text){
        if( mToast == null){
            mToast = Toast.makeText(ac, text, Toast.LENGTH_SHORT);
        }
        else{
            mToast.setText(text);
        }
        mToast.show();
    }

}

                发送信息代码为 bluetoothController.sendMessageHandle

                小技巧:按下ctrl+f 快速搜索(基本上适用于各种应用)

        应用测试:

                测试前记得给位置权限,不然会连不上

                安卓真机测试(不要用模拟器,没蓝牙),先开usb调试

                如果你是安卓衍生系统,简单说不是苹果不是鸿蒙,那么,恭喜你,找根线连上去,选择文件传输,特别好用,如果你是鸿蒙(同样适用于安卓),先连接,选择文件传输:

                        1.找到adb(安装sdk的目录/platform-tools)

                        2.在终端中打开f12bf3f3698e469783275163a090f7e6.png

                        3.在终端中输入.\adb tcpip 8888

                        4.如果说no device啥的,重新拔插,然后迅雷不及掩耳之势在输入一遍(小知识:按上键!)

                        5.直到出来很像成功了的提示

                        6.查看你手机的IP,输入 .\adb connect (ip地址):8888 比如 192.168.1.104:8888;

                        7.开跑

 

小车开发:

                串口通讯:

                                  单片机通过Timer2 来进行串口通讯的波特率发生器

                                  于是在初始化代码中:

		 
	PCON &= 0x7F;	   //波特率不倍速
    SCON = 0x50;       //串口方式1, 8-n-1, 允许接收.  
	TMOD&=0x0F;        //计时器1 重置
	TMOD|=0X20;        //计时器1 模式2
    TL1= 0xFa;         //计时器1 1ms 设置
	TH1 = 0xFa;		   //
    ET1= 0;	           //计时器1中断关闭
	TR1 = 1;		   //计时器1开启         
    ES  = 1;           //串口中断.
	EA = 1;			   //开总中断	

                                        串口通讯代码:

							
void UART_Interrupt(void) interrupt 4
{
	if(RI)			//如果接收到
	{										
		RI = 0;		//手动清零接收中断标志位
		*pMsg = SBUF;	//接收字符		
		TI = 0;	  		
		if(*pMsg == 0x0A)
		{
			pMsg = msg;		  	 
			switch(msg[0])
			{
				case 'O':
					flag = msg[1];	 		
				break;
				case 'L':
					lv = (msg[1] - '0')*10 + msg[2] - '0';	 
				break;
				case 'R':							  
					rv = (msg[1] - '0')*10 + msg[2] - '0'; 	
				break;
			}
		}
		else
		{
			pMsg++;
		}
	}
	if(TI)
		TI = 0;
}	  

                                        我们同时还需要一个计时器来进行PWM调速

                                        选用计时器0


	TH0= 0XFc;		  //1ms定时
    TL0= 0X18;	 	  //
	ET0 = 1;          //计时器0中断允许
	TR0 = 1;          //计时器0开始
    //EA = 1;      

                                        代码:

void timer0()interrupt 1   using 2
{
	TH0= 0XFc;		  //1ms定时
    TL0= 0X18;
	 time++;
	 pwm_val_left++;
	 pwm_val_right++;				   
	 pwm_out_left_moto();
	 pwm_out_right_moto();
 }	

 

记住 所有的函数 名字不重要 重要的是interupt n 也就是中断等级

/******************************************************************/
/*                    右电机调速                                  */  
   void pwm_out_right_moto(void)
{ 
  if(Right_moto_stop)
   { 
    if(pwm_val_right<=push_val_right)
	      {
	       Right_moto_pwm=1; 
//		   Right_moto_pwm1=1; 
		   }
	else 
	      {
		   Right_moto_pwm=0;
//		   Right_moto_pwm1=0; 
		  }
	if(pwm_val_right>=20)
	       pwm_val_right=0;
   }
   else    
          {
           Right_moto_pwm=0;
//           Right_moto_pwm1=0; 
	      }
}
/*                    左电机调速                                        */
/*调节push_val_left的值改变电机转速,占空比            */
		void pwm_out_left_moto(void)
{  
   if(Left_moto_stop)
   {
    if(pwm_val_left<=push_val_left)
	       {
		     Left_moto_pwm=1; 
//		     Left_moto_pwm1=1; 
		   }
	else 
	       {
	         Left_moto_pwm=0;
//		     Left_moto_pwm1=0; 
		   }
	if(pwm_val_left>=20)
	       pwm_val_left=0;
   }
   else    
          {
           Left_moto_pwm=0;
//           Left_moto_pwm1=0; 
		  }
}

                                最后的,为了使用PWM调速 拔掉电机驱动模块上的ENA 和 ENB 的键帽

 

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值