• 打算利用蓝牙芯片HC06实现手机和单片机之间的简单通信。工具包括淘宝上淘的stc单片机实验板一块,hc-06蓝牙模块一个,杜邦线,win7电脑一部,安卓手机一部,相关软件:单片机小精灵,串口通讯助手,keil以及单片机...

    打算利用蓝牙芯片HC06实现手机和单片机之间的简单通信。工具包括淘宝上淘的stc单片机实验板一块,hc-06蓝牙模块一个,杜邦线,win7电脑一部,安卓手机一部,相关软件:单片机小精灵,串口通讯助手,keil以及单片机烧录软件,蓝牙通讯软件APP。软件基本上都是免安装直接运行的。

    工作流程简单总结下为以下3步:
    1.利用单片机小精灵软件,做好烧录程序,确定波特率应该设置为2400
    2.hc-06蓝牙模块进入AT模式,串口通讯助手成功将蓝牙模块波特率设置为2400
    3.将烧录程序通过keil编译成功后烧录至单片机实验板上,手机上安装好APP,设置完成后运行,确定成功。

    步骤(2)见


    https://blog.csdn.net/dok12/article/details/80152239
    步骤(3)见
    https://blog.csdn.net/dok12/article/details/801730

    本篇先介绍步骤1。工具,单片机小精灵软件,免安装,直接运行。

    打开单片机小精灵软件,选择串口波特率选项。必须选择好晶振和波特率。其他选项,c语言还是汇编,是否串口中断,波特率加倍,允许接收都自己决定。
    因为淘宝买到的单片机实验板是12M晶振,蓝牙模块的默认波特率是9600。所以一开始输入这两项数据。
    结果发现误差太大,必须修改。晶振改不了,只好改波特率了。
    修改波特率为2400后误差控制在千分之一点六,效果不错,得到了一个C语言的串口通信基本框架了。

    根据这个框架做了个C语言程序,目标是对单片机实现蓝牙通讯,实现不同的单片机流水灯效果,并且得到回复数字8。
    #include <reg51.h>
    unsigned char k;
    void InitUART(void)
    {
        TMOD = 0x20;
        SCON = 0x50;
        TH1 = 0xF3;
        TL1 = 0xF3;
        PCON = 0x00;
        EA = 1;
        ES = 1;
        TR1 = 1;
    }
    /*******延时函数*************/
    void delay(unsigned int i)
    {
        unsigned char j;
        for(i; i > 0; i--)   
            for(j = 255; j > 0; j--);
    }
    void main(void)
    {	k=0;
        InitUART();
    	while  (1){
    	if(k==1)
    	{P1=0xff;delay(500);P1=0x00;delay(500);}
    	else if (k==2)
    	{P1=0x01;delay(500);P1=0xfe;delay(500);}
    	else 
    	{P1=0x02;delay(500);P1=0xfd;delay(500);}
    	}
    }
    void SendOneByte(unsigned char c)
    {
        SBUF = c;
        while(!TI);
        TI = 0;
    }
    
    void UARTInterrupt(void) interrupt 4
    {
        if(RI)
        {
            RI = 0;
            //add your code here!
    		k++;
    		if(k>2)k=0;
    		SendOneByte(8);
        }
        else
            TI = 0;
    }
    
    
    




    展开全文
  • 首先将HC-06蓝牙通信模块单片机串口通过杜邦线连接,接线如图所示:RX-P30 TX-P31tips:淘宝购买HC06模块的时候,卖家表示蓝牙模块的TX,RX端的丝印搞反了,所以如果你发现蓝牙模块无法和单片机通信的话,可以尝试...

    本篇介绍如何将蓝牙模块进入AT模式,调整波特率。

    工具:软件串口通讯助手,免安装,直接在win7电脑上运行。

    首先将HC-06蓝牙通信模块和单片机串口通过杜邦线连接,接线如图所示:
    RX-P30                TX-P31
    tips:淘宝购买HC06模块的时候,卖家表示蓝牙模块的TX,RX端的丝印搞反了,所以如果你发现蓝牙模块无法和单片机通信的话,可以尝试调换下TX,RX两端的杜邦线


    将单片机连上电脑,(电脑需要安装单片机的相关驱动,买单片机实验板时候卖家附送的驱动我发现在win10下没用,win7下正常运行),我的电脑——》计算机管理,端口显示端口4
    然后在打开串口调试助手软件。

    串口com4,波特率是9600,输入AT,得到OK就表明成功进入AT模式。

    之后在输入AT+BAUD2,将波特率改为2400.会显示OK2400.
    将串口助手波特率改为2400,输入AT显示OK,表明成功修改至2400



    展开全文
  • 刚好碰到这蓝牙通信方面的项目,上网也看过其他人在蓝牙这方面写的博客,但大多都不全,给一些初触蓝牙的开发者造成一定的麻烦,自己当初也费了不少劲。所以把自己参考网上的一些资料用Android studio写的代码完全放...

    刚好碰到这蓝牙通信方面的项目,上网也看过其他人在蓝牙这方面写的博客,但大多都不全,给一些初触蓝牙的开发者造成一定的麻烦,自己当初也费了不少劲。所以把自己参考网上的一些资料用Android studio写的代码完全放出来,分享一下。菜鸟初写博客,若有不恰之处,请指出,必改正。下面我会把自己的思路和代码一一呈现。(PS:由于后期做了些逻辑操作,代码可能有点臃肿,请勿怪。还好完整的代码是会有的,里面有多出来的一两个类没有用的,但懒得重新打包了)

    第一篇博客写完,感觉好菜。资源下载:http://download.csdn.net/detail/u013168302/9146907

    1.添加权限

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

    2.成员变量跟onCreate()方法,为了方便阅读,把这些摆出来

    public class PipelineActivity extends Activity {
        public static BluetoothSocket btSocket;
        private BluetoothAdapter bluetoothAdapter;
        private ArrayAdapter<String> deviceAdapter;
        private List<String> listDevices;
        private ListView listView;
        private LinearLayout btContent;
        private TextView btAllData;
        private Button openBT;
        private Button searchBT;
        final private static int MESSAGE_READ = 100;
        int i = 0;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.pipeline);
    
            listView = (ListView) this.findViewById(R.id.list);
            btContent = (LinearLayout) findViewById(R.id.bt_content_llt);
            btAllData = (TextView) findViewById(R.id.all_data);
            btAllData.setText(btAllData.getText(), TextView.BufferType.EDITABLE);//这行可实现TextView尾部追加http://blog.csdn.net/u013168302/article/details/48785927
    
            openBT = (Button) findViewById(R.id.open_btn);
            searchBT = (Button) findViewById(R.id.search_btn);
    
            listDevices = new ArrayList<String>();
            bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            if (bluetoothAdapter.isEnabled()) {
                openBT.setText("关闭蓝牙");
            }
            deviceAdapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.list_item, listDevices);
    
            openBT.setOnClickListener(new BTListener());
            searchBT.setOnClickListener(new BTListener());
    
            listView.setAdapter(deviceAdapter);
            listView.setOnItemClickListener(new ItemClickListener());//添加监听
        }
    


    3.注册广播(因为下面搜索时要用到,所以现在前面注册)

    private BroadcastReceiver receiver = new BroadcastReceiver() {
    
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                
                //下面几行是为了在logcat里面看到搜索到的设备细节,需要的话,可以将注释打开
    //            Bundle b = intent.getExtras();
    //            Object[] lstName = b.keySet().toArray();
    //            // 显示所有收到的消息及其细节
    //            for (int i = 0; i < lstName.length; i++) {
    //                String keyName = lstName[i].toString();
    //                Log.e("-----" + keyName, String.valueOf(b.get(keyName)));
    //            }
                
                //搜索设备时,取得设备的MAC地址
                if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                    BluetoothDevice device = intent
                            .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    String str = device.getName() + "|" + device.getAddress();
                    if (listDevices.indexOf(str) == -1)// 防止重复添加
                        listDevices.add(str); // 获取设备名称和mac地址
                    if (deviceAdapter != null) {
                        deviceAdapter.notifyDataSetChanged();
                    }
                }
            }
        };
    



    
    
    
    4.点击开启蓝牙,搜索蓝牙设备。 将搜索到设备名称和mac地址通过BroadcastReceiver保存到list集合,再在listview中展示
    

    /**
         * 蓝牙开启与搜索按钮点击监听
         */
        class BTListener implements View.OnClickListener {
            @Override
            public void onClick(View view) {
                if (view.getId() == R.id.open_btn) {
                    if (!bluetoothAdapter.isEnabled()) {
                        bluetoothAdapter.enable();//开启蓝牙
                        Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                        enable.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); //300秒为蓝牙设备可见时间
                        startActivity(enable);
                        openBT.setText("关闭蓝牙");
    
                    } else {
                        bluetoothAdapter.disable();//关闭蓝牙
                        openBT.setText("开启蓝牙");
                        if (btSocket != null) {
                            try {
                                btSocket.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                } else if (view.getId() == R.id.search_btn) {
                    if (!bluetoothAdapter.isEnabled()) {
                        Toast.makeText(getApplicationContext(), "请先开启蓝牙", Toast.LENGTH_SHORT).show();
                    } else {
                        btContent.setVisibility(View.GONE);
                        listView.setVisibility(View.VISIBLE);
                        if (listDevices != null) {
                            listDevices.clear();
                            if (deviceAdapter != null) {
                                deviceAdapter.notifyDataSetChanged();
                            }
                        }
                        bluetoothAdapter.startDiscovery();
                        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
                        registerReceiver(receiver, filter);
    
                    }
                }
            }
        }



    5.点击listview的item,通过反射连接设备。连接设备之前需要UUID来配对。查看网上的例子和自己的一些实践发现,通过UUID会出现一些问题,当然也有可能只是我自己的代码有问题。所以在此采取反射来获取蓝牙socket对象。

    /**
         * 蓝牙选项,listview列表点击监听
         */
        class ItemClickListener implements AdapterView.OnItemClickListener {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
    
                if (!bluetoothAdapter.isEnabled()) {
                    Toast.makeText(getApplicationContext(), "请先开启蓝牙", Toast.LENGTH_SHORT).show();
                } else {
                    bluetoothAdapter.cancelDiscovery();//停止搜索
                    String str = listDevices.get(position);
                    String macAdress = str.split("\\|")[1];
    
                    BluetoothDevice device = bluetoothAdapter.getRemoteDevice(macAdress);
                    try {
                        Method clientMethod = device.getClass()
                                .getMethod("createRfcommSocket", new Class[]{int.class});
                        btSocket = (BluetoothSocket) clientMethod.invoke(device, 1);
                        connect(btSocket);//连接设备
    
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }
        }


    6.连接蓝牙设备,并开辟子线程通信

    在这里值得注意while里面的2行代码。这2行代码花了不少功夫才弄到的

    (1)if(inputStream.available() >0==false)

    (2)Thread.sleep(400);//等待0.4秒,作用:让数据接收完整
    这2行用于处理inputStream读取数据不完整或混乱的问题,但感觉还是不够好。若谁有更好的方法,欢迎提出。
    另外inputStream在这里是关不掉的,因为这是蓝牙通信,单片机每产生的数据都要传输到手机端。试过多次:一旦断开inputstream,while循环结束,单片机再次产生的数据无法传送。不知道我有没有弄错,欢迎指出。

    
    

     /**
         * 连接蓝牙及获取数据
         */
        public void connect(final BluetoothSocket btSocket) {
            try {
                btSocket.connect();//连接
                if (btSocket.isConnected()) {
                    Log.e("----connect--- :", "连接成功");
                    Toast.makeText(getApplicationContext(), "蓝牙连接成功", Toast.LENGTH_SHORT).show();
                    listView.setVisibility(View.GONE);
                    btContent.setVisibility(View.VISIBLE);
                    new ConnetThread().start();//通信
    
                } else {
                    Toast.makeText(getApplicationContext(), "蓝牙连接失败", Toast.LENGTH_SHORT).show();
                    btSocket.close();
                    listView.setVisibility(View.VISIBLE);
                    btContent.setVisibility(View.GONE);
                    Log.e("--------- :", "连接关闭");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
        /**
         * 蓝牙通信管理
         */
        private class ConnetThread extends Thread {
            public void run() {
                try {
                    InputStream inputStream = btSocket.getInputStream();
                    byte[] data = new byte[1024];
                    int len = 0;
                    String result = "";
    
                    while (len != -1) {
                        if (inputStream.available() > 0 == false) {//inputStream接收的数据是一段段的,如果不先
                            continue;
                        } else {
                            try {
                                Thread.sleep(500);//等待0.5秒,让数据接收完整
                                len = inputStream.read(data);
                                result = URLDecoder.decode(new String(data, "utf-8"));
    //                          Log.e("----result:----- :", ">>>" + result);
                                Message msg = new Message();
                                msg.what = MESSAGE_READ;
                                msg.obj = result;
                                handler.sendMessage(msg);
    
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    inputStream.close();//关不了,也好像不能关
                    Log.e("--------- :", "关闭inputStream");
                    if (btSocket != null) {
                        btSocket.close();
                    }
                } catch (IOException e) {
                    Log.e("TAG", e.toString());
                }
            }
    
        }


    7.用Handler处理Message

    private Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case MESSAGE_READ:
                        String result = (String) msg.obj;
                        String data = result.split("\\r\\n")[0];
                        Log.e("----data:----- :", ">>>" + data);
                        if (i < 6) {
                            Editable text = (Editable) btAllData.getText();
                            text.append(data);
                            btAllData.setText(text + "\r\n");
                            i++;
                        } else {
                            btAllData.setText(data + "\r\n");
                            i = 0;
                        }
                        break;
                }
            }
        };
    
        @Override
        protected void onDestroy() {
            unregisterReceiver(receiver);
            super.onDestroy();
        }




    8.1布局文件(尚未优化)

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#000000"
        android:orientation="vertical"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".MainActivity">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:background="#000000"
            android:gravity="center"
            android:paddingLeft="20dp"
            android:text="@string/pipeline"
            android:textColor="#ffffff"
            android:textSize="20sp" />
    
        <LinearLayout
            android:visibility="gone"
            android:id="@+id/bt_content_llt"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_weight="1"
            android:background="#ffffff"
            android:orientation="vertical">
    
            <LinearLayout style="@style/bt_llt_style"
                android:layout_weight="3">
    
                <TextView
                    style="@style/btTV_style"
                    android:gravity="left"
                    android:layout_weight="1"
                    android:paddingTop="20dp"
                    android:text="@string/all_data" />
    
                <TextView
                    android:id="@+id/all_data"
                    style="@style/btTV_style"
                    android:gravity="left"
                    android:paddingLeft="2dp"
                    android:paddingTop="20dp"
                    android:textSize="16sp"
                    android:layout_weight="2" />
    
            </LinearLayout>
    
        </LinearLayout>
    
        <ListView
            android:id="@+id/list"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_weight="1"
            android:background="#f0f0f0"
            android:divider="#c0c0c0"
            android:dividerHeight="1dp" />
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_gravity="center"
            android:layout_marginTop="10dp"
            android:orientation="horizontal">
    
            <Button
                android:id="@+id/open_btn"
                style="@style/bt_button_style"
                android:text="@string/open_bluetooth" />
    
            <Button
                android:id="@+id/search_btn"
                style="@style/bt_button_style"
                android:text="@string/search_bluetooth" />
        </LinearLayout>
    
    </LinearLayout>
    


    8.2 item布局

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/device_name_tv"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:paddingLeft="15dp"
        android:gravity="center|left"
        android:textColor="#000000"
        android:background="@drawable/list_item_selector"
        android:textSize="18sp">
    
    </TextView>
    

    8.3 资源文件strings.xml

    <resources>
        <string name="app_name">bluetooth</string>
    
        <string name="hello_world">Hello world!</string>
        <string name="action_settings">Settings</string>
      
        <string name="pipeline">管道检测仪</string>
        <string name="open_bluetooth">开启蓝牙</string>
        <string name="close_bluetooth">关闭蓝牙</string>
        <string name="search_bluetooth">搜索蓝牙</string>
        <string name="all_data">全部数据:</string>
        <color name="item_default">#F0F0F0</color>
        <color name="item_press">#A5D8F5</color>
    </resources>
    

    8.4 style

    <resources>
    
        <!-- Base application theme. -->
        <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
            <!-- Customize your theme here. -->
        </style>
    
        <style name="btTV_style">
            <item name="android:background">#ffffff</item>
            <item name="android:gravity">left|center</item>
            <item name="android:paddingLeft">10dp</item>
            <item name="android:paddingRight">10dp</item>
            <item name="android:textSize">20sp</item>
            <item name="android:layout_width">1dp</item>
            <item name="android:layout_height">match_parent</item>
        </style>
    
        <style name="bt_llt_style">
            <item name="android:layout_width">match_parent</item>
            <item name="android:layout_height">1dp</item>
            <item name="android:layout_weight">1</item>
            <item name="android:orientation">horizontal</item>
        </style>
    
        <style name="bt_button_style">
            <item name="android:layout_width">1dp</item>
            <item name="android:layout_height">match_parent</item>
            <item name="android:layout_marginLeft">20dp</item>
            <item name="android:layout_marginRight">20dp</item>
            <item name="android:layout_weight">1</item>
            <item name="android:background">#5CB85C</item>
        </style>
    
    </resources>
    


    8.5  listview的item选择器

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
        <!-- 选中 -->
        <item android:state_pressed="true" android:drawable="@color/item_press" />
        <!-- 默认 -->
        <item android:drawable="@color/item_default"/>
    
    </selector>








    展开全文
  •  手机端打开编写的蓝牙通信软件,与单片机蓝牙串口模块连接,而后,手机通过蓝牙发送读数据命令到单片机单片机开始读取传感器信息,将采集到得传感器信息通过蓝牙发送到手机端,手机端软件接收到后,显示。...

            概述:

               手机端打开编写的蓝牙通信软件,与单片机端蓝牙串口模块连接,而后,手机通过蓝牙发送读数据命令到单片机,单片机开始读取传感器信息,

    将采集到得传感器信息通过蓝牙发送到手机端,手机端软件接收到后,显示。

           整体图:

            

           

          焊接板图:

         



            本项目涉及四个部分。

       一、手机端软件

       二、单片机端编程

       三、外设电路设计

       四、手机与单片机通信

         下面对四个部分进一步叙述。

      1、手机端软件

          手机端软件为安卓软件,只需要编写一个普通的蓝牙串口调试软件即可。但在编写手机端按安卓软件时,我利用一年前做安卓手机通

    过蓝牙远程控制指纹识别器的源码改进,但却始终不能接收到蓝牙串口模块发送的数据。也就是说,手机可以给下位机发送信息,下位机成功接收,

    但是却接收不到下位机上传的信息。我很是疑惑,我以为是蓝牙串口模块的问题,于是换了一个,结果还是一样。我一直坚信去年的源码没有问题,

    但是却查不出原因在哪里。于是,我在相应的安卓蓝牙编程的书本上,找到讲解蓝牙部分的章节,按照步骤重新编写带代码,结果双向通信可以调通。

    先前的问题正在研究之中,下面是正常运行源码中的部分代码:

      (1)蓝牙连接代码

     //接收活动结果,响应startActivityForResult()
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
        	switch(requestCode){
        	case REQUEST_CONNECT_DEVICE:     //连接结果,由DeviceListActivity设置返回
        		// 响应返回结果
                if (resultCode == Activity.RESULT_OK) {   //连接成功,由DeviceListActivity设置返回
                    // MAC地址,由DeviceListActivity设置返回
                    String address = data.getExtras()
                                         .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
                    // 得到蓝牙设备句柄      
                    _device = _bluetooth.getRemoteDevice(address);
     
                    // 用服务号得到socket
                    try{
                    	_socket = _device.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));
                    }catch(IOException e){
                    	Toast.makeText(this, "连接失败!", Toast.LENGTH_SHORT).show();
                    }
                    //连接socket
                	Button btn = (Button) findViewById(R.id.Button03);
                    try{
                    	_socket.connect();
                    	Toast.makeText(this, "连接"+_device.getName()+"成功!", Toast.LENGTH_SHORT).show();
                    	btn.setText("断开");
                    }catch(IOException e){
                    	try{
                    		Toast.makeText(this, "连接失败!", Toast.LENGTH_SHORT).show();
                    		_socket.close();
                    		_socket = null;
                    	}catch(IOException ee){
                    		Toast.makeText(this, "连接失败!", Toast.LENGTH_SHORT).show();
                    	}
                    	
                    	return;
                    }
                    
                    //打开接收线程
                    try{
                		is = _socket.getInputStream();   //得到蓝牙数据输入流
                		}catch(IOException e){
                			Toast.makeText(this, "接收数据失败!", Toast.LENGTH_SHORT).show();
                			return;
                		}
                		if(bThread==false){
                			ReadThread.start();
                			bThread=true;
                		}else{
                			bRun = true;
                		}
                }
        		break;
        	default:break;
        	}
        }
        
    
     
    (2)手机蓝牙发送数据代码
     //发送数据线程
        public class SendThread extends Thread{
        	public void run(){
        		int i=0;
            	int n=0;
            	try{
            		OutputStream os = _socket.getOutputStream();   //蓝牙连接输出流
            		byte[] bos = edit0.getText().toString().getBytes();
            		for(i=0;i

      (3)手机蓝牙接收数据代码
    //接收数据线程
        Thread ReadThread=new Thread(){
        	
        	public void run(){
        		int num = 0;
        		byte[] buffer = new byte[1024];
        		byte[] buffer_new = new byte[1024];
        		int i = 0;
        		int n = 0;
        		bRun = true;
        		//接收线程
        		while(true){
        			try{
        				while(is.available()==0){
        					while(bRun == false){}
        				}
        				while(true){
        					num = is.read(buffer);         //读入数据
        					n=0;
        					
        					String s0 = new String(buffer,0,num);
        					fmsg+=s0;    //保存收到数据
        					for(i=0;i

       
      2、单片机端
           单片机采用Arduino开发板,因其简单易学。
           单片机端的代码比较简单,是一些对应的传感器采集数据代码和串口通讯代码。

      3、外设焊接。
        外设有两个传感器,一个蓝牙串口模块。
        蓝牙串口模块负责蓝牙通信,传感器负责采集信息。
       
      4、手机与单片机通信
        首先,约定一个命令 符,当单片机端接收到手机端发送的命令符时,即开始采集传感器信息,将采集到得信息进行加工,然后传给
    安卓手机。安卓手机接收数据后,随即显示出来。

       做成此项目用了三天时间,其中两天时间纠结与蓝牙单向通信问题,一直没有眉目。
    剩下一天用半天调通手机端蓝牙串口调试软件,半天焊接电路板,写Arduino端程序,连接布线等。



    展开全文
  • 之前两篇都是在说与手机的连接,连接方法,主动配对连接,都是手机与手机的操作,做起来还是没问题的,但是最终的目的是与单片机蓝牙模块的通信。   下面是到目前为止尝试的与单片机通信方法,没有成功,但是...

    之前两篇都是在说与手机的连接,连接方法,和主动配对连接,都是手机与手机的操作,做起来还是没问题的,但是最终的目的是与单片机的蓝牙模块的通信。

     

    下面是到目前为止尝试的与单片机的通信方法,没有成功,但是从思路上来说没有问题,最大的问题是与单片机配对的时候,单片机的蓝牙模块的PIN配对码是写死的,固定为1234,

    而手机这边连接配对都是自动生成的PIN配对码,这种方式在手机与手机配对的时候是极为方便的,但是在这里与单片机连接却成了最大的问题,因为手机自动生成而且每次都不一样,所以没法与单片机蓝牙模块的1234相同也就没法陪对了。下面只是介绍的到目前为止我们的大题思路,具体代码很多,而且涉及到项目也就没有贴。

    如果关于上面的问题哪位同学有思路或者做过类似的项目还请指点。

     

    首先,如何开启蓝牙设备和设置可见时间:

    private void search() {
            BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
            if (!adapter.isEnabled()) {
                adapter.enable();
            }
            Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
            enable.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 3600); //3600为蓝牙设备可见时间
             startActivity(enable);
            Intent searchIntent = new Intent(this, ComminuteActivity.class);
            startActivity(searchIntent);
        }


    正式开始与蓝牙模块进行通信

    public class ComminuteActivity extends Activity {
        private BluetoothReceiver receiver;
        private BluetoothAdapter bluetoothAdapter;
        private List<String> devices;
        private List<BluetoothDevice> deviceList;
        private Bluetooth client;
        private final String lockName = "YESYOU";
        private String message = "000001";
        private ListView listView;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.search_layout);
    
            listView = (ListView) this.findViewById(R.id.list);
            deviceList = new ArrayList<BluetoothDevice>();
            devices = new ArrayList<String>();
            bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            bluetoothAdapter.startDiscovery();
            IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
            receiver = new BluetoothReceiver();
            registerReceiver(receiver, filter);
    
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    setContentView(R.layout.connect_layout);
                    BluetoothDevice device = deviceList.get(position);
                    client = new Bluetooth(device, handler);
                    try {
                        client.connect(message);
                    } catch (Exception e) {
                        Log.e("TAG", e.toString());
                    }
                }
            });
        }
    
        @Override
        protected void onDestroy() {
            unregisterReceiver(receiver);
            super.onDestroy();
        }
    
        private final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case Bluetooth.CONNECT_FAILED:
                        Toast.makeText(ComminuteActivity.this, "连接失败", Toast.LENGTH_LONG).show();
                        try {
                            client.connect(message);
                        } catch (Exception e) {
                            Log.e("TAG", e.toString());
                        }
                        break;
                    case Bluetooth.CONNECT_SUCCESS:
                        Toast.makeText(ComminuteActivity.this, "连接成功", Toast.LENGTH_LONG).show();
                        break;
                    case Bluetooth.READ_FAILED:
                        Toast.makeText(ComminuteActivity.this, "读取失败", Toast.LENGTH_LONG).show();
                        break;
                    case Bluetooth.WRITE_FAILED:
                        Toast.makeText(ComminuteActivity.this, "写入失败", Toast.LENGTH_LONG).show();
                        break;
                    case Bluetooth.DATA:
                        Toast.makeText(ComminuteActivity.this, msg.arg1 + "", Toast.LENGTH_LONG).show();
                        break;
                }
            }
        };
    
        private class BluetoothReceiver extends BroadcastReceiver {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    if (isLock(device)) {
                        devices.add(device.getName());
                    }
                    deviceList.add(device);
                }
                showDevices();
            }
        }
    
        private boolean isLock(BluetoothDevice device) {
            boolean isLockName = (device.getName()).equals(lockName);
            boolean isSingleDevice = devices.indexOf(device.getName()) == -1;
            return isLockName && isSingleDevice;
        }
    
        private void showDevices() {
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
                    devices);
            listView.setAdapter(adapter);
        }
    }

    这里需要提一下的是,startDiscovery()这个方法和它的返回值,它是一个异步方法,会对其他蓝牙设备进行搜索,持续时间为12秒。

    搜索过程其实是在System Service中进行,我们可以通过cancelDiscovery()方法来停止这个搜索。在系统搜索蓝牙设备的过程中,系统可能会发送以下三个广播:ACTION_DISCOVERY_START(开始搜索),

    ACTION_DISCOVERY_FINISHED(搜索结束)

    和ACTION_FOUND(找到设备)。

    ACTION_FOUND这个才是我们想要的,这个Intent中包含两个extra fields:    EXTRA_DEVICE和EXTRA_CLASS,

    包含的分别是BluetoothDevice和BluetoothClass

    EXTRA_DEVICE中的BluetoothDevice就是我们搜索到的设备对象,从中获得设备的名称和地址。

    EXTRA_CLASS中的BluetoothClass是搜索到的设备的类型,比如搜索到的是手机还是耳机或者其他,之后我会写一篇关于它的介绍

    在这个上面我现在在想,是否通过判断搜索到的设备类型来识别单片机蓝牙模块与手机蓝牙的不同,采取不一样的配对方式,从而不自动生成配对码。不知是否可行,一会尝试。

     

     搜索到该设备后,我们就要对该设备进行连接和通信。

    public void connect(final String message) {
            Thread thread = new Thread(new Runnable() {
                public void run() {
                    BluetoothSocket tmp = null;
                    Method method;
                    try {
                        method = device.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
                        tmp = (BluetoothSocket) method.invoke(device, 1);
                    } catch (Exception e) {
                        setState(CONNECT_FAILED);
                        Log.e("TAG", e.toString());
                    }
                    socket = tmp;
                    try {
                        socket.connect();
                        isConnect = true;
                    } catch (Exception e) {
                        setState(CONNECT_FAILED);
                        Log.e("TAG", e.toString());
                    }
    	       if (isConnect) {
                        try {
                            OutputStream outStream = socket.getOutputStream();
                            outStream.write(getHexBytes(message));
                        } catch (IOException e) {
                            setState(WRITE_FAILED);
                            Log.e("TAG", e.toString());
                        }
                        try {
                            InputStream inputStream = socket.getInputStream();
                            int data;
                            while (true) {
                                try {
                                    data = inputStream.read();
                                    Message msg = handler.obtainMessage();
                                    msg.what = DATA;
                                    msg.arg1 = data;
                                    handler.sendMessage(msg);
                                } catch (IOException e) {
                                    setState(READ_FAILED);
                                    Log.e("TAG", e.toString());
                                    break;
                                }
                            }
                        } catch (IOException e) {
                            setState(WRITE_FAILED);
                            Log.e("TAG", e.toString());
                        }
                    }
    
                    if (socket != null) {
                        try {
                            socket.close();
                        } catch (IOException e) {
                            Log.e("TAG", e.toString());
                        }
                   }
           }
    }

     这里包括写入和读取,用法和基本的Socket是一样的,但是写入的时候,需要将字符串转化为16进制:

    private byte[] getHexBytes(String message) {
            int len = message.length() / 2;
            char[] chars = message.toCharArray();
            String[] hexStr = new String[len];
            byte[] bytes = new byte[len];
            for (int i = 0, j = 0; j < len; i += 2, j++) {
                hexStr[j] = "" + chars[i] + chars[i + 1];
                bytes[j] = (byte) Integer.parseInt(hexStr[j], 16);
            }
            return bytes;
        }


     

    连接设备之前需要UUID,所谓的UUID,就是用来进行配对的,全称是Universally Unique Identifier,是一个128位的字符串ID,用于进行唯一标识。网上的例子,包括谷歌的例子提供的uuid,通用的"00001101-0000-1000-8000-00805F9B34FB"也试过了,在配对的时候都是自动生成了配对码,也无法正常与单片机的蓝牙模块连接,所以,我就利用反射的原理,让设备自己提供UUID尝试。到这里其实我有点怀疑自己对于UUID的理解是否正确了。

                在谷歌提供的例子中,我们可以看到谷歌的程序员的程序水平很高,一些好的编码习惯我们可以学习一下,像是在try..catch中才定义的变量,我们应该在try...catch之前声明一个临时变量,然后再在try...catch后赋值给我们真正要使用的变量。这种做法的好处就是:如果我们直接就是使用真正的变量,当出现异常的时候,该变量的使用就会出现问题,而且很难进行排查,如果是临时变量,我么可以通过检查变量的值来确定是否是赋值时出错。

       

    作者:jason0539

    微博:http://weibo.com/2553717707

    博客:http://blog.csdn.net/jason0539(转载请说明出处)

    展开全文
  • 1.单片机发的是ASCII码,手机这边收的是
  • 可以测试通过串口的收发,有安卓eclipse的工程代码。适合新手。在淘宝上花钱买的基础上添加了一些功能,注释比较清晰。
  • ... QQ技术交流群:129518033 STC89C52单片机通过HC-06蓝牙模块...基于Android和蓝牙单片机温度采集系统     注意: APP需要点击菜单键进行蓝牙连接 整个工程下载:http://download.csdn.net/detail/itas...
  • HC-05蓝牙串口通信模块应该是使用最广泛的一种蓝牙模块之一了。为什么呢? 因为HC05模块是一款高性能主从一体蓝牙串口模块,可以不用知道太多蓝牙相关知识就可以很好的上手。说白了,只是个蓝牙转串口的设备,你...
  • android手机接收并波形图显示单片机通过蓝牙传输的传感器数据
  • 最近辛辛苦苦的终于把落下了七八个月的Android蓝牙开发搞完了,其中的痛苦不堪回首啊。感谢那些帮了大忙的老师同学们!辛苦归辛苦,收获总是有的,...而单片机上的蓝牙模块与手机蓝牙连接有点不同,它的UUID号需要
  • 手机是安卓系统的,蓝牙模块采用hc-06,单片机用msp430f149.具体要求是手机发数据能通过蓝牙模块传给单片机然后做出相应的反应(如控制LED的亮灭等)。
  • 目录说在前面说明关键代码结果 说在前面 单片机:HC6800-ES,...蓝牙通信代码仿照参考代码进行编写,不再提供github代码 关键代码 主要是接收发送数据,在参考的代码里面设置了数据格式,有些东西我...
  • 该程序实现了51单片机蓝牙通信程序,并在适当地方做了注释
  • 利用单片机来控制蓝牙进行无线通信的简易说明
  • 首先运行sudo apt-get install bluez看看bluez是不是最新的...再使用bluetoothctl工具打开蓝牙,并查询蓝牙的地址,同时可以尝试进行连接。最后别忘了要断开连接,不然用其他工具就无法再次连接蓝牙了。 bluetoothct...
  • 电路查了又查,单片机和app的程序改了又改,在第三点里连最简单的一个字符都收不到,前面两点进行长字符串传输毫无问题。现在求大神给个思路。 补充一下,第三点是APP能完美地收到字符,字符串,但是从手机蓝牙发...
  • 51单片机蓝牙模块的串口51单片机蓝牙模块的串口通信C程序通信C程序
1 2 3 4 5 ... 20
收藏数 2,580
精华内容 1,032