• 代码我忘了在哪找的,只记得是把别人网上的代码稍微整理了一下,之后再加上自己的一些东西就成功了,对,反正就是成功了。很感谢我的一个哥们帮我组建了单片机和蓝牙...一,Android 手机蓝牙Android 手机蓝牙 ...

         代码我忘了在哪找的,只记得是把别人网上的代码稍微整理了一下,之后再加上自己的一些东西就成功了,对,反正就是成功了。很感谢我的一个哥们帮我组建了单片机和蓝牙设备硬件方面的东西,服务器那边也是他写的,灰常感谢...

    在上次的博客中写的手机设备向蓝牙设备中发送消息,代码很乱不是很容易整理,这次我会把源码的地址放到文末,大家可以测试一下。

    一,Android 手机蓝牙 与 Android 手机蓝牙

        从网上抠下来的那个代码,在一个APP中写了接受和发送,也就是说,两部手机用一个APP就可以通信,     

                                                             

    很清楚的看到,两个手机一个APP,在未连接之下点击目标蓝牙会先配对,配对成功之后就可相互发送消息了。

    二,Android 手机蓝牙向HC05设备发送数据

    在这里之前有一个问题导致APP无法使用,最后看到有博客这样写,我是这样理解的,你的目标设备可以分几类,每一类又有几个专门的UUID,使得匹配,差不多就是这个意思。最后也成功了,也是用这个APK ,那接受的部分就交给我哥们了,啊哈哈哈.

    下载地址:https://download.csdn.net/download/h2677lucy/10295861

    layout_buletooth_seacher.xml

    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical">
    
        <LinearLayout
            android:id="@+id/l1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:orientation="vertical">
    
            <ListView
                android:id="@+id/lvDevices"
                android:layout_width="match_parent"
                android:layout_height="250dp" />
    
            <TextView
                android:id="@+id/text_1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal"
                android:text="[CURRENT ORDER]"
                android:textSize="18sp" />
    
            <TextView
                android:id="@+id/receive_text"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:background="#EEEEEE"
                android:gravity="center"
                android:textSize="20dp" />
        </LinearLayout>
    
        <LinearLayout
            android:layout_below="@id/l1"
            android:id="@+id/l2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_weight="3">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
    
                <Button
                    android:id="@+id/red"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:layout_weight="1"
                    android:text="红灯"
                    android:textSize="10dp" />
    
                <Button
                    android:id="@+id/green"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:textSize="10dp"
                    android:layout_weight="1"
                    android:text="绿灯"/>
                <Button
                    android:id="@+id/blue"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:textSize="10dp"
                    android:layout_weight="1"
                    android:text="蓝灯" />
                <Button
                    android:id="@+id/breath"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:textSize="10dp"
                    android:layout_weight="1"
                    android:text="呼吸灯" />
                <Button
                    android:id="@+id/close_all_led"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:textSize="10dp"
                    android:layout_weight="1"
                    android:text="关灯" />
            </LinearLayout>
    
            <LinearLayout
                android:layout_width="match_parent"
    
                android:padding="5dp"
                android:layout_height="50dp">
    
                <TextView
                    android:id="@+id/textView"
                    android:layout_width="50dp"
                    android:layout_height="match_parent"
                    android:gravity="center"
                    android:background="#31555555"
                    android:text="亮度" />
    
                <SeekBar
                    android:id="@+id/seekBar"
                    style="@style/AlertDialog.AppCompat.Light"
                    android:layout_width="match_parent"
                    android:layout_height="50dp"
                    android:layout_gravity="center_vertical"
                    android:max="800"
                    android:background="#31555555"
                    android:progress="50" />
            </LinearLayout>
    
            <Button
                android:id="@+id/button"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:onClick="onClick_Search"
                android:text="搜索" />
        </LinearLayout>
        <LinearLayout
            android:layout_below="@id/l2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            >
            <TextView
                android:id="@+id/text_2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal"
                android:text="[RECEIVE ORDER]"
                android:textSize="18sp" />
            <TextView
                android:id="@+id/msg"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:background="#EEEEEE"
                android:gravity="center"
                android:textSize="20dp" />
        </LinearLayout>
    
    </RelativeLayout>

    BuletoothClientActivity

    package com.managesoft.nullchen.buletoothdemo;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Set;
    import java.util.UUID;
    
    import android.graphics.Color;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.app.Activity;
    import android.bluetooth.BluetoothAdapter;
    import android.bluetooth.BluetoothDevice;
    import android.bluetooth.BluetoothServerSocket;
    import android.bluetooth.BluetoothSocket;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.util.Log;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.AdapterView.OnItemClickListener;
    import android.widget.ArrayAdapter;
    import android.widget.Button;
    import android.widget.ListView;
    import android.widget.SeekBar;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class BuletoothClientActivity extends Activity implements OnItemClickListener{
        // 获取到蓝牙适配器
        private BluetoothAdapter mBluetoothAdapter;
        // 用来保存搜索到的设备信息
        private List<String> bluetoothDevices = new ArrayList<String>();
        // ListView组件
        private ListView lvDevices;
        // ListView的字符串数组适配器
        private ArrayAdapter<String> arrayAdapter;
        // UUID,蓝牙建立链接需要的
        private final UUID MY_UUID = UUID
                .fromString("00001101-0000-1000-8000-00805F9B34FB");
        // 为其链接创建一个名称
        private final String NAME = "Bluetooth_Socket";
        // 选中发送数据的蓝牙设备,全局变量,否则连接在方法执行完就结束了
        private BluetoothDevice selectDevice;
        // 获取到选中设备的客户端串口,全局变量,否则连接在方法执行完就结束了
        private BluetoothSocket clientSocket;
        // 获取到向设备写的输出流,全局变量,否则连接在方法执行完就结束了
        private OutputStream os;
        // 服务端利用线程不断接受客户端信息
        private AcceptThread thread;
        //定义按钮
        //定义按钮
        private Button close_all_led;
        private Button red1 = null;
        private Button green1 = null;
        private Button blue1 = null;
        private Button breath = null;
        private TextView receive1;
        private SeekBar seekBar;
        private String LED_STATE = "A 红灯亮";
        private TextView re_msg;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.layout_buletooth_seacher);
            red1 = (Button)findViewById(R.id.red);
            green1 = (Button)findViewById(R.id.green);
            blue1 = (Button)findViewById(R.id.blue);
            receive1 = (TextView)findViewById(R.id.receive_text);
            close_all_led = (Button)findViewById(R.id.close_all_led);
            breath = (Button)findViewById(R.id.breath);
            seekBar = (SeekBar)findViewById(R.id.seekBar);
            re_msg = (TextView)findViewById(R.id.msg);
    
            red1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    LED_STATE = "R";
                    receive1.setText(LED_STATE);
                }
            });
            green1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    LED_STATE = "G";
                    receive1.setText(LED_STATE);
                }
            });
            blue1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    LED_STATE = "B";
                    receive1.setText(LED_STATE);
                }
            });
            close_all_led.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    LED_STATE = "E";
                    receive1.setText(LED_STATE);
                }
            });
            breath.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    LED_STATE = "H";
                    receive1.setText(LED_STATE);
                }
            });
            seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                    if (b){
                        LED_STATE ="{0:"+i+"}";
                        receive1.setText(LED_STATE);
                    }
                }
    
                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {
    
                }
    
                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {
    
                }
            });
            // 获取到蓝牙默认的适配器
            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            // 获取到ListView组件
            lvDevices = (ListView) findViewById(R.id.lvDevices);
            // 为listview设置字符换数组适配器
            arrayAdapter = new ArrayAdapter<String>(this,
                    android.R.layout.simple_list_item_1, android.R.id.text1,
                    bluetoothDevices);
            // 为listView绑定适配器
            lvDevices.setAdapter(arrayAdapter);
            // 为listView设置item点击事件侦听
            lvDevices.setOnItemClickListener(this);
    
            // 用Set集合保持已绑定的设备   将绑定的设备添加到Set集合。
            Set<BluetoothDevice> devices = mBluetoothAdapter.getBondedDevices();
            if (devices.size() > 0) {
                for (BluetoothDevice bluetoothDevice : devices) {
                    // 保存到arrayList集合中
                    bluetoothDevices.add(bluetoothDevice.getName() + ":"
                            + bluetoothDevice.getAddress() + "\n");
                }
            }
    
            // 因为蓝牙搜索到设备和完成搜索都是通过广播来告诉其他应用的
            // 这里注册找到设备和完成搜索广播
            IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
            registerReceiver(receiver, filter);
            filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
            registerReceiver(receiver, filter);
    
            // 实例接收客户端传过来的数据线程
            thread = new AcceptThread();
            // 线程开始
            thread.start();
        }
    
        //搜索蓝牙设备
        public void onClick_Search(View view) {
            setTitle("正在扫描...");
            // 点击搜索周边设备,如果正在搜索,则暂停搜索
            if (mBluetoothAdapter.isDiscovering()) {
                mBluetoothAdapter.cancelDiscovery();
            }
            mBluetoothAdapter.startDiscovery();
        }
        // 注册广播接收者
        private BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context arg0, Intent intent) {
                // 获取到广播的action
                String action = intent.getAction();
                // 判断广播是搜索到设备还是搜索完成
                if (action.equals(BluetoothDevice.ACTION_FOUND)) {
                    // 找到设备后获取其设备
                    BluetoothDevice device = intent
                            .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    // 判断这个设备是否是之前已经绑定过了,如果是则不需要添加,在程序初始化的时候已经添加了
                    if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                        // 设备没有绑定过,则将其保持到arrayList集合中
                        bluetoothDevices.add(device.getName() + ":"
                                + device.getAddress() + "\n");
                        // 更新字符串数组适配器,将内容显示在listView中
                        arrayAdapter.notifyDataSetChanged();
                    }
                } else if (action
                        .equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
                    setTitle("搜索完成");
                }
            }
        };
    
        // 点击listView中的设备,传送数据
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                                long id) {
            // 获取到这个设备的信息
            String s = arrayAdapter.getItem(position);
            // 对其进行分割,获取到这个设备的地址
            String address = s.substring(s.indexOf(":") + 1).trim();
            Log.d("TAG",address);
            // 判断当前是否还是正在搜索周边设备,如果是则暂停搜索
            if (mBluetoothAdapter.isDiscovering()) {
                mBluetoothAdapter.cancelDiscovery();
            }
            // 如果选择设备为空则代表还没有选择设备
            if (selectDevice == null) {
                //通过地址获取到该设备
                selectDevice = mBluetoothAdapter.getRemoteDevice(address);
            }
            // 这里需要try catch一下,以防异常抛出
            try {
                // 判断客户端接口是否为空
                if (clientSocket == null) {
                    // 获取到客户端接口
                    clientSocket = selectDevice
                            .createRfcommSocketToServiceRecord(MY_UUID);
                    // 向服务端发送连接
                    clientSocket.connect();
                    // 获取到输出流,向外写数据
                    os = clientSocket.getOutputStream();
    
                }
                // 判断是否拿到输出流
                if (os != null) {
                    // 需要发送的信息
                    //String text = "我传过去了";
                    // 以utf-8的格式发送出去
                    os.write(LED_STATE.getBytes("UTF-8"));
                }
                // 吐司一下,告诉用户发送成功
                Toast.makeText(this, "发送信息成功,请查收", 0).show();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                // 如果发生异常则告诉用户发送失败
                Toast.makeText(this, "发送信息失败", 0).show();
            }
    
        }
    
        // 创建handler,因为我们接收是采用线程来接收的,在线程中无法操作UI,所以需要handler
        Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                super.handleMessage(msg);
                // 通过msg传递过来的信息,吐司一下收到的信息
               // Toast.makeText(BuletoothClientActivity.this, (String) msg.obj, Toast.LENGTH_SHORT).show();
                re_msg.setText((String)msg.obj);
            }
        };
    
        // 服务端接收信息线程
        private class AcceptThread extends Thread {
            private BluetoothServerSocket serverSocket;// 服务端接口
            private BluetoothSocket socket;// 获取到客户端的接口
            private InputStream is;// 获取到输入流
            private OutputStream os;// 获取到输出流
    
            public AcceptThread() {
                try {
                    // 通过UUID监听请求,然后获取到对应的服务端接口
                    serverSocket = mBluetoothAdapter
                            .listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
            public void run() {
                try {
                    // 接收其客户端的接口
                    socket = serverSocket.accept();
                    // 获取到输入流
                    is = socket.getInputStream();
                    // 获取到输出流
                    os = socket.getOutputStream();
    
                    // 无线循环来接收数据
                    while (true) {
                        // 创建一个128字节的缓冲
                        byte[] buffer = new byte[128];
                        // 每次读取128字节,并保存其读取的角标
                        int count = is.read(buffer);
                        // 创建Message类,向handler发送数据
                        Message msg = new Message();
                        // 发送一个String的数据,让他向上转型为obj类型
                        msg.obj = new String(buffer, 0, count, "utf-8");
                        // 发送数据
                        handler.sendMessage(msg);
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
    
            }
        }
    }
    
    最后感谢我的好哥们和那个网友。
    展开全文
  • 单片机传来多字节数据,想让前一个字节显示在一个textview,后一个字节显示在另一个texiview里该怎么弄呢
  • Android studio 2.2 安卓端与传统蓝牙HC05/06的通信APP,刚写,亲测可用。
  • 经典蓝牙hc05的代码示例,经过了多次优化,使用EventBus总线方式传递数据!
  • 【周记-Android移动端开发】手机蓝牙与下位机HC-05蓝牙模块通信系统 很久没有写博客了,计划一直都有,但总是被这样或者那样的事情给耽搁了,在此写下文字监督自己:不论长短,每周至少一篇!本文根据自己的实践...

    很久没有写博客了,计划一直都有,但总是被这样或者那样的事情给耽搁了,在此写下文字监督自己:不论长短,每周至少一篇!本文根据自己的实践总结而来,参考前人博客之余,也自己总结和开发了一些功能,在这里给自己备份也分享给大家。不同之处在于:自动打开并搜索蓝牙、修改蓝牙名字、完整接收蓝牙传输数据、修改蓝牙密码、解除蓝牙绑定。


    一、系统框架简介

    系统由上、下位机两部分构成,旨在实现移动端app通过蓝牙通信,将app发送过来的数据存储在下位机的存储单元,与此同时,app也可以通过指令查询下位机的参数设置。系统框架图如下:

    这里写图片描述

    二、软件界面设计

    话不多说,先上软件界面:

    这里写图片描述

    界面主要涉及到按键的监听和Activity的跳转:
    ①按键监听有四种方法,详情可以参考博客
    ②Activity的跳转包括:直接跳startActivity转和带返回跳startActivityForResult转,详情可以参考博客

    二、蓝牙开发

    蓝牙功能 函数名称
    (1)开启&关闭蓝牙 enable()/disable()
    (2)修改蓝牙名字 changeName()
    (3)搜索&显示蓝牙设备 DeviceListActivity
    (4)配对&连接蓝牙 connectToServerSocket(address)
    (5)数据收发 write/ConnectedThread
    (6)修改蓝牙密码 changeMima()
    (7)取消蓝牙配对 removeBond

    本系统中实现的功能如表所示,这里不打算赘述已经开发成熟的功能,可以参考这篇博客,讲得比较清晰,这里只针对自己在开发中添加的功能做一下记录,开发之前需要提醒的有两点:
    ①不要忘记蓝牙权限的设置:

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

    ②让主程序弹出搜索对话框时,不要忘了intent设置;

    <activity android:name=".DeviceListActivity" 
    android:theme="@android:style/Theme.Dialog" 
    android:label="选取连接设备" 
    android:configChanges="orientation|keyboardHidden"/>

    (1)自动打开并搜索蓝牙

    一般的做法都是监听按键(打开蓝牙按键和搜索设备按键),先打开蓝牙,接着搜索蓝牙。但是,这样做无疑使操作更加复杂,在实际生产和用户使用时并不方便,我要做的效果是程序启动的时候自动打开蓝牙并开始搜索设备,于是乎,出问题了,蓝牙虽然打开了,但是不接着搜索设备了,汗。。。解决办法是,打开蓝牙后延时1秒后开始搜索,这样就行了

    //得到BluetoothAdapter对象
    BluetoothAdapter mBtAdapter = BluetoothAdapter.getDefaultAdapter();
    mBtAdapter.enable();//打开蓝牙
    Timer timer=new Timer();
    TimerTask task=new TimerTask(){//定时1k=new TimerTask(){//定时1秒后搜索设备
        @Override
         public void run() {
            Intent serverIntent = new Intent(MainActivity.this, DeviceListActivity.class); //跳转程序设置
            startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);  //设置返回宏定义
        }          
    };
    timer.schedule(task,1000);

    (3)修改蓝牙名字

    这一功能有两种实现方式,一种是通过蓝牙传输将名字传输给下位机,用单片机操作蓝牙AT指令直接修改蓝牙名字,这样,以后任何手机搜索该蓝牙设备时,显示的名字都是你所修改的名字;另一种方式是在软件层面实现蓝牙名字的修改,其实是搜索出蓝牙设备的ID,然后将其对应到你想修改的名字,并将这一映射存在本地,那么,以后这部手机下次搜索到该设备时,就会显示你所修改的名字,而不影响其他手机对该设备的显示。这种方法各有特色,就看你的需求了。这里就讲讲第二种方式的实现:

    步骤一:搜索蓝牙设备,获取并修改名字

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);
        switch(requestCode) {
        case REQUEST_CONNECT_DEVICE:     //连接结果,由DeviceListActivity设置返回
            if (resultCode == Activity.RESULT_OK) { //选择蓝牙
                String address = data.getExtras().getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
                device = mBluetoothAdapter.getRemoteDevice(address);// 得到蓝牙设备句柄
                connectToServerSocket(address);
                setting_thread=true;
                ConnectedThread thread=new ConnectedThread();
                thread.start();
            }
            break;
            default:break;
        }
    }

    在从DeviceListActivity返回的数据中,其实已经包含蓝牙设备的句柄,我们可以通过device.getName()获取当前连接的蓝牙模块的名字,然后将设备的名字或者其唯一标识符(例如,98:D3:34:90:8A:BC)与新修改的名字做映射保存在本地。
    步骤二:存储设置到本地,下次搜索蓝牙时做映射显示
    使用SharedPreferences存储数据,SharedPreferences是Android平台上一个轻量级的存储类,主要是保存一些常用的配置比如窗口状态,一般在Activity中 重载窗口状态onSaveInstanceState保存一般使用SharedPreferences完成,它提供了Android平台常规的Long长 整形、Int整形、String字符串型的保存。

    //获取SharedPreferences对象
    Context ctx = MainActivity.this;       
    SharedPreferences sp = ctx.getSharedPreferences("SP", MODE_PRIVATE);
    //存入数据
    Editor editor = sp.edit();
    editor.putString("STRING_KEY", "string");
    editor.commit();

    (4)完整接收蓝牙传输数据

    在开发蓝牙数据接收时,发现一个问题:数据有时候会接收不完整。由于项目中的每一位数据返回都十分重要,所以必须保证数据的完整性,要解决这一问题需要清楚的了解如何从InputStream中读取数据,从输入流中读取数据最常用的方法基本上就是如下 3 个 read() 方法:

    ① read () 方法,这个方法从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1 。
    ② read (byte[] b,int off,int len) 方法,将输入流中最多 len 个数据字节读入 byte 数组。尝试读取 len 个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。
    ③ read (byte[] b) 方法, 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。

    对于三种方法的选择,需要看具体项目的需求,如果你能够通过某种方法知道数据的长度,那么建议用第一种方法,每次读取一个字节,保证数据的完整性;如果数据长度不知道,那么就用②或者③,一般③用的比较多,这一方法效率高但是读取数据的长度不确定—-不超过数组b的长度,所以就需要多次读取直到把数据全部读完。

    (5)修改蓝牙密码

    本项目中用的是HC-05蓝牙模块,该模块有接收蓝牙指令模式(即通信模式),和AT指令集模式,一般默认状态为蓝牙通信模式,要想修改蓝牙连接密码,需要将蓝牙模块切换到AT指令集模式,具体过程见下面的流程图:
    这里写图片描述

    (6)解除蓝牙绑定(配对)

    在真实场景中,要想在程序修改完密码后,之前连接的蓝牙设备都无法与该蓝牙模块建立连接,需要解除该模块与手机的绑定,即取消配对。要想解除所有的配对,当然是需要下位机控制蓝牙模块进入AT指令集模式,解除所有绑定,而与此同时,当前修改密码的手机也需要在软件层面解除绑定(配对),这样交互性更强。

    用过Android系统设置(Setting)的人都知道蓝牙搜索之后可以建立配对和解除配对,但是这两项功能的函数没有在SDK中给出,本项目利用Java的反射机制去调用removeBond解除绑定,从而取消本机与该蓝牙模块的配对。具体实现程序如下:当程序接收到下位机传来的修改密码成功的指令后,程序会弹出一个强提示,当用户点击确认按钮之后,程序解除绑定并退出程序。

    if(modify_flag){//修改密码成功
          AlertDialog.Builder builder = new Builder(MainActivity.this);
          builder.setTitle("密码修改成功");
          builder.setMessage("点击确定按钮重新启动!");
          builder.setCancelable(false);
          builder.setPositiveButton("确认", new OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int which) {
               try {//接触绑定
                   Method m = device.getClass().getMethod("removeBond", (Class[]) null);
                   m.invoke(device, (Object[]) null);
               } catch (Exception e) {
                    Log.e("erro", e.getMessage());
               }
               setting_thread=false;
               dialog.dismiss();
               mBluetoothAdapter.disable();//关闭蓝牙
               finish();
               System.exit(0);//销毁程序
               }
          });
          builder.setCancelable(false);
          builder.create().show();
    }else {
         Toast.makeText(MainActivity.this, "set failed!", Toast.LENGTH_SHORT).show();
    }
    展开全文
  • 蓝牙模块,HC系列较全的资料 附一个Android的应用程序,这是原厂家提供的,自己开发的话可以参考Android蓝牙类.如果是单片机开发的话就是用串口通信,数据量不大的近距离传输可以选择.
  • 可用于stm32的蓝牙数据传输,内部只有单工,没有手机端到android端口
  • APP作为信息的发送者与接受者,可以实现手机与手机的通信,手机向HC05发送数据(HC06就不知道了)。解压用AS打开生成APK就可以使用。
  •  HC-05蓝牙模块为主从一体的蓝牙模块,并可与手机实现实时的通信。将单片机的串口通信通过HC-05进行扩展从而实现无线通信,更可使用手机来控制单片机完成工作。 要完成单片机与Android手机的无...

      51单片机是市面上比较普及的单片机种类,同时也深受广大电子爱好者的青睐。在51单片机的众多功能中串口通信占据了重要的地位,通过串口通信,我们可以实现51单片机与其他设备的互联,增加了学习的趣味性。

      HC-05蓝牙模块为主从一体的蓝牙模块,并可与手机实现实时的通信。将单片机的串口通信通过HC-05进行扩展从而实现无线通信,更可使用手机来控制单片机完成工作。

     要完成单片机与Android手机的无线通信,首先我们要在写好单片机的控制程序,因为HC-05只是对串口通信功能进行延伸, 并不能独立完成通信。

     编写串口通信的程序中首先我们要对串口的配置进行初始化

    void UartConfigurationInit()
    {
        TMOD=0x20;  //设置定时器1工作方式为方式2   
        TH1=0xfd;  	  //波特率9600
        TL1=0xfd;  
        TR1=1;      //启动定时器1     
        SM0=0;SM1=1;      //串口方式1         
        REN=1;      //允许接收   
        PCON=0x00;  //关倍频   
        ES=1;       //开串口中断   
        EA=1;       //开总中断
    }

    配置好串口后,在编写发送函数前我们需要对串口发送数据的原理有个了解:

    转码过程:

    发送十进制数:查询ASCII码表后发送相应的字符 ,如SBUF=65;则会收到字符‘A’;

    发送字符:原样输出

    发送字符串:强行对SBUF传递字符串会造成输出乱码,得不到想要的结果。想要发送字符串则需要运用指针,每次发送时发送指针指向的那个字符,因为发送频率很快,最后输出时组合起来还是一条字符串。

    实现整数转为字符串发送:

       0x30对应的字符‘0’,当我们要发送一个整数时,需要将该整数按最高位到最低位得到顺序依次发送,发送时需要在原始数据上加上0x30或者48,则会输出相应的数字字符。


    字符发送函数:

    void PostChar(uchar character)  
    {     
    	    SBUF=character;   //发送单个字符
    	    while(!TI);TI=0; //发送完成标志 
    }

    字符串的发送需要依靠字符发送函数来实现:

      这里加了一个延时函数delay(),因为在实际与手机通信中我发现发送速度过快会产生严重的数据丢失,因此加上一个延时可以较好的保证数据的准确度,具体延时数据根据大家实际需要调整。

    void  PostString(uchar *p)  
    {  
    	    while(*p)  	   //若指针指向的地址为空,则跳出循环
    	    {  
    	        PostChar(*p); //指针第一次默认指向首地址
    			delay(20);  //延时,作用为提高发送准确度
    	        p++;  
    	    }	  
    }

    十进制数据发送:

     因为十进制数据不能直接发送,所以要先加上0x30或者48后再转为字符型。

    void IntConversionChar(uint number)
    {
           uint model;	//模
           uint numberByte; //十进制数据不同位上的值
    
         for(model=1000;model>=1;model=model/10) //model的取值根据实际需要选择,选择过大会浪费资源
    
          {
                numberByte = number/model;	//相除取整
    			//当取到整数数据的最高位时,将其加上0x30或者48并转为字符型后发送
                if(numberByte >=1 ) PostChar((uchar)(numberByte%10+0x30));
          		//if(numberByte >=1 ) PostChar((unsigned char)(numberByte%10+48));
    	  }	
    }

    以上就是51单片机使用HC-05蓝牙模块与Android手机通信的程序的要点和原理。

    完整程序:

    https://download.csdn.net/download/qq_41570228/10398277



    展开全文
  • STC89C52通过HC-06蓝牙模块与Android手机通信   如需转载请标明出处:http://blog.csdn.net/itas109  QQ技术交流群:129518033  2017-11-04补充 注意问题: 1.确保上位机波特率为9600 2.确保下位机的波特...

    STC89C52通过HC-06蓝牙模块与Android手机通信

     

    如需转载请标明出处:http://blog.csdn.net/itas109 

    QQ技术交流群:129518033

     2017-11-04补充

    注意问题:

    1.确保上位机波特率为9600

    2.确保下位机的波特率为9600,下位机的晶振应该为11.0592MHz

    3.本教程中接收指令的是字符1、2、3,不是16进制的0x01、0x02、0x03

    4.可能跟上拉电阻有关系,但是不少人反应不需要上拉电阻,时间长了我也不知道了

     

    环境
             1、任意单片机开发板即可(当时用的芯片STC90C516RD+),约定为下位机
              2、无线蓝牙串口透传模块 HC-06从机
              3windows xp操作系统
              4、Android智能手机(蓝牙串口通信助手软件),约定为上位机

    二、连接的部分电路图(有集成板子的直接插上就可以了,但是要注意若单片机的TXD无上拉能力需要加上拉电阻)

          上拉电阻的阻值有人问我,我当时用的是1KΩ。

     

    三、下位机测试程序

    (各位大神如果分数比较多可以赞助我一下,就1个积分)

    程序地址(整个工程):http://download.csdn.net/detail/itas109/5430553

          

       /***********************************************************
    
    STC90C51RD+与HC-06蓝牙连线:
    
             蓝牙  STC90C51RD+
    
             RXD    TXD
    
             TXD    RXD
    
    其他连线:
    
             P2.0、P2.1、P2.3分别接一个指示灯
    
     
    
    !!!!
    
    !!!!注意:若单片机TXD(P3.1)无上拉能力,必须在P3.1端接上拉电阻。本次测试需要接上拉电阻
    
    !!!!
    
     
    
    手机采用蓝牙串口通信助手
    
    最后已改用Android自编蓝牙通信软件
    
                                                   By itas109
    
                                                   http://blog.csdn.net/itas109
    
    ***********************************************************/
    
    #include <reg52.h>
    
    #include <intrins.h>
    
    unsigned char tmp;
    
    unsigned int c=0;
    
     
    
    sbit led1=P2^0;                      //指示灯0
    
    sbit led2=P2^1;                           //指示灯1
    
    sbit led3=P2^3;                           //指示灯3
    
     
    
    void init();   //串口初始化
    
    void send(unsigned char a);     //单字节发送函数
    
    void ctrl(); //接收处理函数
    
     
    
    void main()
    
    {
    
                       init();
    
              while(1)
    
              {         
    
                      if(RI==1)                     //是否有数据到来
    
                      {
    
                       RI = 0;
    
                      tmp = SBUF;                   //暂存接收到的数据
    
                                           ctrl();
    
                                           }      
    
              }
    
    }
    
     
    
     void init()        //串口初始化
    
     {
    
                       ES=0;                                                                       //关中断
    
                         SCON = 0x50;                        // REN=1允许串行接受状态,串口工作模式1,
    
                                                                                                             //10位UART(1位起始位,8位数据位,1位停止位,无奇偶校验),波特率可变
    
     
    
                         TMOD = 0x20;                        //定时器1工作于方式2,8位自动重载模式,用于产生波特率
    
              TH1=TL1=0xFD;                       //波特率9600 (本次测试采用晶振为11.0592)
    
              
    
              PCON &= 0x7f;                       //波特率不倍增
    
              TR1 = 1;                                                                  //定时器1开始工作,产生波特率
    
                                                                                                             //发送标志位置0
    
                         TI=0;                                                                        //接收标志位置0
    
                         RI=0;
    
                         
    
                         //EA=0;
    
                   ES=1;
    
     
    
     
    
              led1=0;                                    //初始化设置3个指示灯全亮
    
                         led2=0;
    
                         led3=0;
    
     }
    
       
    
    void send(unsigned char a)      //单字节数据发送
    
    {                                                                //注意:若单片机TXD(P3.1)无上拉能力,必须在P3.1端接上拉电阻。本次测试需要接上拉电阻
    
             TI=0;         
    
             SBUF=a;
    
             while(TI==0);
    
             TI=0;
    
     
    
             if(c%2)                                           //发送指示灯标志,每接收一次,此灯亮灭交替
    
              led3=1;
    
             else
    
              led3=0;
    
             c++;
    
    } 
    
     
    
    void ctrl()                      //接收处理函数
    
    {
    
                                         switch(tmp)
    
                                           {
    
                                                case '1':
    
                                                            led1=1;                           //收到字符1,指示灯0灭
    
                                                            send(tmp);
    
                                                            break;                                           
    
                                                   case '2':                                         //收到字符2,指示灯1灭
    
                                                             led2=1;
    
                                                             send(tmp);
    
                                                             break;
    
                                                   case '3':                                   //收到字符3,指示灯0、1亮
    
                                                             led1=0;
    
                                                             led2=0;
    
                                                             send(tmp);
    
                                                             break;
    
                                                   case '4':                                         //收到字符4,指示灯0、1灭
    
                                                              led1=1;
    
                                                              led2=1;
    
                                                              send(tmp);
    
                                                              break;
    
                                                   case '5':                                         //收到字符5,指示灯3亮
    
                                                            led3=0;
    
                                                            send(tmp);
    
                                                            break;
    
                                                   default:                   //其他,灯全灭
    
                                                              led1=1;
    
                                                              led2=1;
    
                                                              led3=1;
    
                                                              send(tmp);
    
                                           }
    
    }
    
    


    四、上位机软件可以用蓝牙串口通信助手软件

     

     

    觉得文章对你有帮助,请扫描二维码捐赠给博主,谢谢!

     

     

    如需转载请标明出处:http://blog.csdn.net/itas109 

    QQ技术交流群:129518033

     

     

    展开全文
  • 进入 At 模式进行蓝牙基本参数设置想要使用 Arduino 的蓝牙模块,首先要对蓝牙模块进行基本参数设置。基本参数设置主要包含:蓝牙名称、模式以及匹配密码等。设置蓝牙模块可以使用 USB-TTL 连接电脑使用串口调试软

    通过本文,可以了解到以下内容:

    • 进入 AT 模式进行蓝牙基本参数设置
    • Arduino 蓝牙控制 LED 电路设计以及代码编写
    • 利用 Andorid 蓝牙串口调试软件测试功能

    进入 At 模式进行蓝牙基本参数设置

    想要使用 Arduino 的蓝牙模块,首先要对蓝牙模块进行基本参数设置。基本参数设置主要包含:蓝牙名称、模式以及匹配密码等。设置蓝牙模块可以使用 USB-TTL 连接电脑使用串口调试软件进入 AT 模式进行设置,也可以使用 Arduino 连接蓝牙模块进行设置,本文主要介绍后一种方法。

    注意事项

    在连接蓝牙的时候,要注意线的连接是否正确,检查清楚再进行通电,除此之外,还要主要不要让针脚短路,我在首次使用蓝牙模块的时候,因为没注意接线,导致一个蓝牙模块损坏了,只能发信息不能收信息,所以为了避免不必要的损失,这里要注意。

    Arduino HC05 AT模式接线

    进入 AT 模式设置蓝牙的接线如下:
    Arduino 5V - VCC
    Arduino GND - GND
    Arduino Pin10 - TXD
    Arduino Pin11 - RXD
    在通电前检查接线是否正确连接
    hc05_at_mode.jpg

    Arduino 进入 AT 模式代码

    接下来,我们需要为使用 Arduino 设置蓝牙模块 AT 模式编写程序,这个程序是让我们可以通过 Arduino IDE 提供的串口监视器来设置蓝牙模块。详细的 Arduino 代码如下:

    #include <SoftwareSerial.h> 
    
    // Pin10为RX,接HC05的TXD
    // Pin11为TX,接HC05的RXD
    SoftwareSerial BT(10, 11); 
    char val;
    
    void setup() {
      Serial.begin(38400); 
      Serial.println("BT is ready!");
      // HC-05默认,38400
      BT.begin(38400);
    }
    
    void loop() {
      if (Serial.available()) {
        val = Serial.read();
        BT.print(val);
      }
    
      if (BT.available()) {
        val = BT.read();
        Serial.print(val);
      }
    }

    利用 Arduino IDE 串口监视器进行调试

    首先,将 Arduino 断电,然后按着蓝牙模块上的黑色按钮,再让 Arduino 通电,如果蓝牙模块指示灯按2秒的频率闪烁,表明蓝牙模块已经正确进入 AT 模式。
    打开 Arduino IDE 的串口监视器,选择正确的端口,将输出格式设置为 Both: NL & CR ,波特率设置为 38400 ,可以看到串口监视器中显示 BT is ready! 的信息。
    然后,输入 AT ,如果一切正常,串口显示器会显示 OK
    接下来,我们即可对蓝牙模块进行设置,常用 AT 命令如下:

    AT+ORGL    # 恢复出厂模式
    AT+NAME=<Name>    # 设置蓝牙名称
    AT+ROLE=0    # 设置蓝牙为从模式
    AT+CMODE=1    # 设置蓝牙为任意设备连接模式
    AT+PSWD=<Pwd>    # 设置蓝牙匹配密码

    正常情况下,命令发送后,会返回 OK ,如果没有返回任何信息,请检查接线是否正确,蓝牙模块是否已经进入 AT 模式,如果上述两点都没有问题,可能是蓝牙模块的问题,可以找蓝牙模块供应商咨询。
    设置完毕后,断开电源,再次通电,这是,蓝牙模块指示灯会快速闪烁,这表明蓝牙已经进入正常工作模式。

    利用 Andorid 手机连接 Arduino 并控制 LED灯开关

    我们完成了对蓝牙模块的设置后,我们将做一个可以通过手机蓝牙连接,控制 Arduino 开关 LED 灯的小实验。

    Arduino 电路设计

    这里的电路设计比较简单,主要是两部分:
    - Arduino 与 HC05 模块连接
    - Arduino 与 LED 连接

    这里有两点需要注意,Arduino 上的 TXD 应与 HC05 模块上的 RXD 端连接,Arduino 上的 RXD 应与 HC05 模块上的 TXD 连接。
    在下面的图例中,我的 LED 是直接连接在 Arduino Pin13 上,而实际电路连接中,因根据连接的 Led 灯的设计考虑是否需要串联电阻。
    Hc05_Led.jpg

    Arduino 蓝牙控制 LED 灯 程序设计

    Arduino 程序代码如下:

    void setup()
    {
      // 设置波特率为 38400
      Serial.begin(38400);
      pinMode(13, OUTPUT);
    }
    
    
    void loop()
    {
      while(Serial.available())
      {
        char c=Serial.read();
          if(c=='1')
          {
            Serial.println("BT is ready!");
            // 返回到手机调试程序上
            Serial.write("Serial--13--high");
            digitalWrite(13, HIGH);
          }
         if(c=='2')
         {
           Serial.write("Serial--13--low");
           digitalWrite(13, LOW);
         }
      }
    }

    Android 手机端调试

    在 Android 端上进行调试,需要下载蓝牙串口调试 APP,可以根据喜好在各大应用商场搜索下载。
    下载安装完成 APP 后,我们先打开手机的蓝牙设置,搜索并匹配好我们的蓝牙模块。然后打开 蓝牙串口调试APP ,让 APP 连接上蓝牙模块,然后我们可以在 APP 中输入 1,接下来可以看到 LED 等亮了,并且能在 APP 中看到 Serial--13--high 的返回(有些 APP 返回值可能不是返回在同一行)。我们再在 APP 中输入 2,可以看到 LED 熄灭, APP 中返回 Serial--13--low

    小结

    在这篇文章中,我们了解了在 Arduino 中使用 HC05 蓝牙模块的两个主要步骤,首先是进入 AT模式 对蓝牙模块进行设置,这里要注意接线的正确性,设置完成后,就可以将蓝牙模块的 TXArduino RX 连接,RXArduino TX 连接,再通过 Arduino 程序中的 Serial 来实现数据的传输与读取。最后,在通过 Android 上的蓝牙串口调试APP,来测试我们的试验是否成功。

    参考资料

    蓝牙模块HC05
    Arduino Bluetooth Basic Tutorial


    本文为原创内容,由同一作者于早前发表于简书,Arduino使用HC05蓝牙模块与手机连接

    展开全文
  • AndroidHC-05

    2020-06-12 19:33:08
    用于测试安卓与蓝牙05模块通信,支持开发者自己编写部分功能,如更改接收或者发送字符格式,具有较强的可扩展空间,
  • 前言:  由于17年机械创新设计大赛要使用蓝牙通讯,被迫缺少一个触摸显示器,所以只有在手机上开发界面来进行控制,其中最主要的就是蓝牙...这个蓝牙配置只可在Android上运行!  首先的就是配置一个蓝牙的类...
  • 假期和同伴做了一个android蓝牙控制小车的项目,他负责下位机代码实现,我负责上位机代码实现。但在蓝牙开发上的经验不算熟悉,在网上查找相关资料的时候也发现很多答案参差不齐,并且也不是用于蓝牙上位机连接的,...
  • Android蓝牙2.0app,若需要蓝牙2.0和蓝牙4.0的源码,可以去百度云盘下载。链接:http://pan.baidu.com/s/1eSygHLg 密码:knm6。这里面有介绍和相应蓝牙2.0和蓝牙4.0的源码和app的下载链接
  • 蓝牙舵机云台控制花了两天时间实现简单的APP蓝牙舵机云台设置Android蓝牙协议分为两种,SPP协议和BLE(Bluetooth low energy)本项目采用的HC-05蓝牙4.0模块。BLE协议主要适用低功耗,具体其他的概念我暂时也不太明白...
  • 引脚2连接蓝牙模块vcc,引脚6连接蓝牙模块GND端,引脚8连接RXD端,引脚10连接TXD端。如下图所示 树莓端配置 步骤简介: 1. 配置树莓派的baud rate 默认情况下,树莓派读写串口的boud rate是115200,而HM-05...
  • Android studio之蓝牙

    2019-04-27 18:39:03
    (Android Studio)Android 手机设备与HC05 蓝牙设备的通信(成功案例+源码) - 谈笑风生不动情 - CSDN博客...实现蓝牙HC-05、06与单片机的连接及与手机通信 - 莫慌的博客 - CSDN博客 https://blog.csdn.net/wuermohu...
  • 实现HC-05蓝牙模块与安卓手机app的连接及通信,亲测可用,适合初学者借鉴
  • 通过蓝牙助手(或串口调试助手)调试,HC-05与PC机能正常通信; 与89C51相连接,HC-05也能接收到数据,但接收到的是乱码。 二、解决办法 波特率一致(我设置的是4800); 波特率加倍(不知道为啥要加倍,或者可能是...
1 2 3 4 5 ... 20
收藏数 661
精华内容 264