• 最近公司要搞一智能硬件,通过APP连接硬件,发指令达到某些目的,对于从没有接触过蓝牙的小白,简直是两眼一抹黑,于是从网上找例子,找攻略,例子和代码都不是自己想要的,于是只能求助于谷歌API,拿着某翻译,一...

    最近公司要搞一个智能硬件,通过APP连接硬件,发指令达到某些目的,对于从没有接触过蓝牙的小白,简直是两眼一抹黑,于是从网上找例子,找攻略,例子和代码都不是自己想要的,于是只能求助于谷歌API,拿着某翻译,一个个对着看,终于调试成功了,下面直接上思路及代码。

    1、从谷歌官网下载一份demo(通用的),对于任何串口,只要符合规范,这个demo都能调试。

    2、谷歌官方代码共有4个类,其中两个比较重要,如下:

    BluetoothleService 蓝牙服务:里面有蓝牙的连接,写入命令后,蓝牙所返回的协议(这个协议是厂家给你的)

    DeviceControlActivity 设备控制类:连上蓝牙后进入这个界面,会出现一大堆服务,及服务的特征

    3、了解两个类,接下来我们要连上蓝牙给单片机发送指令,首先打开DeviceControlActivity类,找到如下代码:

      //如果该char可写
                            if ((charaProp | BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
                               LayoutInflater factory = LayoutInflater.from(parent.getContext());
                                final View textEntryView = factory.inflate(R.layout.dialog, null);
                                final EditText editTextName = (EditText) textEntryView.findViewById(R.id.editTextName);
                                final EditText editTextNumEditText = (EditText)textEntryView.findViewById(R.id.editTextNum);
                                AlertDialog.Builder ad1 = new AlertDialog.Builder(parent.getContext());
                                ad1.setTitle("WriteCharacteristic");
                                ad1.setView(textEntryView);
                                ad1.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int i) {
                                        byte[] value = new byte[20];
                                        value[0] = (byte) 0x00;
                                        if(editTextName.getText().length() > 0){
                                            //write string
                                            WriteBytes= editTextName.getText().toString().getBytes();
                                        }else if(editTextNumEditText.getText().length() > 0){
                                            WriteBytes= hex2byte(editTextNumEditText.getText().toString().getBytes());
                                        }
                                        characteristic.setValue(value[0],
                                                BluetoothGattCharacteristic.FORMAT_UINT8, 0);
                                        characteristic.setValue(WriteBytes);
                                        mBluetoothLeService.writeCharacteristic(characteristic);
                                    }
                                });
                                ad1.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int i) {


                                    }
                                });
                                ad1.show();
                            }

    以上这段代码就是写入命令的代码,起初我在这里栽了跟头,发现一件事,直接输入命令,此处的返回和协议文档是对不上的,于是我做了如下修改:

    if ((charaProp | BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
                                byte[] bytes = hexStringToBytes("
    XXXXXXXXXXXX");
    //                            characteristic.setValue(new byte[]{0x
    XX,0xXX,0xXX,0xXX,0xXX, (byte) 0xB2, (byte) 0xXX});
                                characteristic.setValue(bytes);
                                boolean status = mBluetoothLeService.writeCharacteristic(characteristic);
                                Log.e("shjysoft_info","状态:"+status);
                            }

    先把协议的16进制的字符串变成字节,然后放到特征里面,写进去,然后就成功了,但是没有接触过蓝牙的朋友会有疑问,给哪个服务哪个特征写,这边我也遇到 过,我跑过去问前辈们,前辈们说了一句,一个一个试,没错,你一个一个点,哪个返回正确就是哪个。

    展开全文
  • 不久前开始学习使用蓝牙模块,在模块51单片机连接的过程中出现了非常的问题,我想应该也是很新手和我一样会遇到这样的问题,因此特地写这篇文章,想分享下在学习过程中遇到的问题以及解决方法。此次学习用到...

    不久前开始学习使用蓝牙模块,在模块与51单片机连接的过程中出现了非常多的问题,我想应该也是很多新手和我一样会遇到这样的问题,因此特地写这篇文章,想分享下在学习过程中遇到的问题以及解决方法。


    此次学习用到模块是HC-06蓝牙模块,如下图:

    该模块某宝有售,价格约为20RMB。某宝上的HC-06有两种,分别是带引脚不带引脚的,建议新手购买带引脚的。我从试验开始到成功,一共使用了四块蓝牙模块。第一次买的是带引脚的,但是模块本身是坏的;第二次买的是不带引脚的,但是由于自身的焊功有限,导致模块损坏,无法使用;第三次是朋友送的蓝牙4.0,由于某些原因无法使用,在此也特别感谢朋友送我蓝牙;第四次购买,就是上图所示的蓝牙,才最终完成了试验。

    总结:在某宝购买时,最好货比三家,虽然模块不值钱,但是在购买过程遇到问题会耽误时间,影响开发,非常麻烦。

    单片机用了两个,分别是新手常用的开发板还有一个单片机最小模块,两者有什么区别我稍后会说明。

    开发板:


    单片机最小模块:


    我特别标注了两者的晶振,分别为12MHZ11.0594MHZ,就是晶振的不同导致我在学习中问题的发生。以下是学习试验过程。


    蓝牙模块的调试:

    接线,蓝牙模块的RX接转换模块的TX蓝牙模块的TX接转换模块的RX,如下图所示:


    接入电脑,在PC端下载好串口调试助手,软件自搜,此处不再赘述。

    附可能会用到的驱动:链接:https://pan.baidu.com/s/1bpYLfCr 密码:yabv

    进入到调试助手,其实基本不怎么用调参数了,蓝牙模块基本都默认设置好波特率为9600,因此直接启动软件调试即可。具体调参数的方法可以自行百度其他文章,都有很详细的介绍。

    启动串口,成功后左下角显示成功:


    发送AT指令,返回OK:


    表明串口正常,此时用手机连接蓝牙模块。手机端也是用到调试助手,请自行下载。

    搜索蓝牙模块:

    备注:我的蓝牙模块此前已经被我改名为Ezio,未改名前默认为HC06。


    连接成功:


    尝试发送消息hello:


    此时在PC端的串口助手上,可以收到来自手机端发送的消息:


    在此说明一点,在蓝牙模块上电以后,模块上的LED灯为闪烁状态,此时处于从机模式,与手机成功连接后,LED灯会变为常亮。自此,蓝牙模块调试成功,可以与单片机连接进行试验


    蓝牙模块与51单片机接线:

    和连接转换模块一样,蓝牙模块的RX连接单片机的TX,蓝牙模块的TX连接单片机的RX,此处说明单片机的RX和TX引脚分别为P3.0和P3.1,如图(图片来自网络):


    正确接线后,向单片机中写入程序,程序如下:

    #include <reg52.h>
    
    sbit P1_0 = P1^0;	//测试口,可用可不用
    sbit P1_3 = P1^3;	//输出口
    
    unsigned char tempbuf;	//存储接收到的信息
    
    /*初始化串口*/
    void BlueteethInit()
    {
    	SCON = 0x50;	//串口模式1,允许接收
    	TMOD = 0x20;	//T1工作模式为2,自动重装
    	PCON = 0x00;	//波特率不倍增
    
    	REN = 1;
    
    	TH1 = 0xfd;		//设置波特率为9600
    	TL1 = 0xfd;
    
    	RI = 0;
    
    	EA = 1;
    	ES = 1;
    
    	TR1 = 1;
    }
    
    void main()
    {
    	BlueteethInit();
    	P1_0 = 0;
    	P1_3 = 0;
    	TI = 0;
    	while(1)
    	{
    		if(tempbuf == 0x31)	//可以使用
    			P1_3 = 1;
    		if(tempbuf == 0)	//不可以使用
    			P1_3 = 0;
    		if(tempbuf == 'A')	//可以使用
    			P1_3 = 1;
    		if(tempbuf == 'B')	//可以使用
    			P1_3 = 0;
    	}
    }
    
    void Serial(void) interrupt 4
    {
    	tempbuf = SBUF;
    	RI = 0;	//读标志清零
    	SBUF = tempbuf;	//将内容返回到手机端,可在手机查看发送的内容
    	while(!TI);
    	TI = 0;	//写标志清零
    }

    该程序为最简单的测试程序,利用蓝牙接收手机发来的信息,控制P1.3口输出高或者低电平,以测试是否正确接收到信息。


    第一步,用蓝牙模块与开发板接线,并成功用手机与蓝牙模块连接,尝试发送信息,过程如图所示:


    无论是发送数字或者是其他字符,都可以看见返回的是乱码,因此可以知道,单片机接收的也是乱码,故程序中的判断:

    while(1)
    	{
    		if(tempbuf == 0x31)	//可以使用
    			P1_3 = 1;
    		if(tempbuf == 0)	//不可以使用
    			P1_3 = 0;
    		if(tempbuf == 'A')	//可以使用
    			P1_3 = 1;
    		if(tempbuf == 'B')	//可以使用
    			P1_3 = 0;
    	}

    无法正确执行,P1.3口自然也无法根据需要来输出高或者低电平。

    第二步,用蓝牙模块与单片机最小模块接线,成功用手机连接收尝试发送信息,如下图所示:


    可见,此时返回的内容与发出的内容相同,经测试此时程序也可以正确执行,使用万用表可以检查出P1.3口输出电平的变化,表明此时蓝牙模块可以正常使用。

    特别说明:

    if(tempbuf == 0x31)	//可以使用
    	P1_3 = 1;
    if(tempbuf == 0)	//不可以使用
    	P1_3 = 0;

    当发送数字消息时,应为十六进制,因此在判断时,如接收到1,应判断是否等于0x31,而不是判断是否等于1。此处经过测试,发送1时,判断tempbuf == 0x31,该判断有效;当发送0时,判断tempbuf == 0,判断无效。判断字符加单引号即可。

    第三步,为什么使用两个相同的单片机会导致结果不同?这也是困扰了我很久的问题,后来经过检查,才知道原来就是晶振的问题。此处PO一下大神关于晶振的说明,暂时未看懂:https://www.zhihu.com/question/30930577

    但可以得出的结论就是,如果使用串口通信,应使用的晶振为11.0594MHZ,否则可能出现乱码的情况。

    另附:开发板上的晶振如图:


    是可以更换的,某宝也有售,可以根据需要的晶振购买。


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

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

     

    下面是到目前为止尝试的与单片机的通信方法,没有成功,但是从思路上来说没有问题,最大的问题是与单片机配对的时候,单片机的蓝牙模块的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(转载请说明出处)

    展开全文
  • HC-05蓝牙串口通信模块应该是使用最广泛的一种蓝牙模块之一了。为什么呢? 因为HC05模块是一款高性能主从一体蓝牙串口模块,可以不用知道太多蓝牙相关知识就可以很好的上手。说白了,只是个蓝牙转串口的设备,你...

    HC-05蓝牙串口通信模块应该是使用最广泛的一种蓝牙模块之一了。为什么呢?

    因为HC05模块是一款高性能主从一体蓝牙串口模块,可以不用知道太多蓝牙相关知识就可以很好的上手。说白了,只是个蓝牙转串口的设备,你只要知道串口怎么编程使用,就可以了,实现了所谓的透明传输。

    但是就是这么一个很常见的模块,网上很多的博客写的都是错的,或者都是很不详细的。

    所以本文就介绍一下这款蓝牙通信模块的使用,包括蓝牙模块的调试、手机与蓝牙模块之间的传输、手机蓝牙控制STM32单片机,应该是逐渐深入的一个过程。但是这仅仅是使用,以后有时间应该会对蓝牙有一个稍微深度的学习,而不能仅仅是浮于表面,只会用。

     

    模块名称:HC-05蓝牙串口通信模块

    参考资料:HC-05蓝牙串口通信模块官方资料包

    知识储备:【STM32】串口通信基本原理(超基础、详细版)

    其他模块:USB转TTL模块、手机蓝牙串口助手app

    手机蓝牙串口助手软件,可以点击链接下载:蓝牙串口。因为这是我见过所有手机端界面最好看的了,其他的界面都有点太糟糕了。

     

    蓝牙模块的调试

    准备工作

    USB转TTL模块与HC-05蓝牙模块的接线:

    两模块共地,两模块共VCC(VCC取5V);蓝牙模块的RX接转换模块的TX,蓝牙模块的TX接转换模块的RX。如下图所示:

    这个时候就要将转换模块连接到电脑上,然后利用串口调试助手进行蓝牙模块的调试。

    附可能会用到的驱动:链接:https://pan.baidu.com/s/1bpYLfCr 密码:yabv

    蓝牙模块的调试

    HC-05蓝牙串口通讯模块具有两种工作模式:命令响应工作模式和自动连接工作模式。在自动连接工作模式下模块又可分为主(Master)、从(Slave)和回环(Loopback)三种工作角色。

    • 当模块处于自动连接工作模式时,将自动根据事先设定的方式连接的数据传输;
    • 当模块处于命令响应工作模式时能执行AT命令,用户可向模块发送各种AT 指令,为模块设定控制参数或发布控制命令。

    怎么进入命令响应工作模式?

    进入命令响应工作模式有两种方法:

    • 模块上电,未配对情况下就是AT模式,波特率为模块本身的波特率,默认:9600,发送一次AT指令时需要置高一次PIO11;
    • PIO11 置高电平后,再给模块上电,此时模块进入AT 模式,波特率固定为:38400,可以直接发送AT指令。

    什么叫做置高一次PIO11?

    在蓝牙模块中有一个小按键,按一下就置高一次PIO11。也就是说,第一种方法需要每发送一次AT指令按一次;而第二种方式是长按的过程中上电,之后就无需再管了,直接发送AT命令即可。

    需要注意一下,两种进入命令响应工作模式的方式使用的波特率是不一样的,建议使用第二种方式。

    怎么区分进了命令响应工作模式呢?

    在蓝牙模块上有灯,当灯快闪的时候,就是自动连接工作模式;当灯慢闪的时候,就是命令响应工作模式。

    AT命令

    进入到命令响应工作模式之后,就可以使用串口调试助手进行蓝牙调试了。

    首先有一点,AT指令不区分大小写,均以回车、换行结尾。下面介绍常用的AT指令:

    常用AT指令
    指令名 响应 含义
    AT OK 测试指令
    AT+RESET OK 模块复位
    AT+VERSION? +VERSION:<Param> OK 获得软件版本号
    AT+ORGL OK 恢复默认状态
    AT+ADDR? +ADDR:<Param> OK 获得蓝牙模块地址
    AT+NAME=<Param> OK 设置设备名称
    AT+NAME? +NAME:<Param> OK 获得设备名称
    AT+PSWD=<Param> OK 设置模块密码
    AT+PSWD? +PSWD:<Param> OK 获得模块密码
    AT+UART=<Param1>,<Param2>,<Param3> OK 设置串口参数
    AT+UART? +UART:<Param1>,<Param2>,<Param3> OK 获得串口参数

    对于AT指令,有几点注意:

    • AT+NAME?:获得设备名称,这个AT指令有很大可能性是没有返回的,因为我也看到了很多的例子……,但是其他的指令都是没有问题的,直接设置设备名称就行了;
    • AT+UART?:获得串口参数,串口的参数一共有三个,波特率、停止位、检验位。其取值如下:
    串口参数
    参数名称 取值
    波特率

    2400、4800、9600、19200、38400、5760、

    115200、230400、460800、921600、1382400

    停止位

    0:1位

    1:2位

    校验位 0:NONE  1:Odd  2:Even

    其默认值为:9600,0,0。

    例子:

    本文中,蓝牙串口的波特率设置成115200。之后的内容,就会采用这个波特率来进行通讯了。

     

    手机与蓝牙模块之间的传输

    直接将蓝牙模块与转换模块连接,再讲其连接到电脑上,蓝牙模块直接进入自动连接工作模式。

    此时手机打开蓝牙串口调试应用,用其来连接蓝牙模块。手机蓝牙串口助手软件,可以点击链接下载:蓝牙串口。万分推荐这款,因为界面脱离了那种黑不溜秋的感觉,比较简洁、清爽。

    这个软件的使用:点击界面右下角蓝牙的标志,选择蓝牙进行连接。

    然后在电脑上的调试助手和手机的蓝牙串口调试应用之间就可以相互传输了,比如:

    可以清楚的看到:电脑向手机发送了“hello you”,手机向电脑发送了“hello world”。

     

    手机蓝牙控制STM32单片机

    之前的两个例子都是相比较而言比较简单的,这个例子将会涉及到程序的内容了。

    实现功能:手机通过蓝牙,向STM32单片机发送消息,STM32接收到消息之后原封不动的返回给手机。当然如果掌握了这个例子,也可以修改成,手机发送特定的消息,然后,STM32单片机做出相对应的动作。比如:点亮LED等、发动电机等等。

    连接说明

    使用USART1进行试验,也就是说STM32选取PA9、PA10来和HC-05进行连接。同时手机通过蓝牙来和HC-05进行连接。

    原理就是:手机通过蓝牙传输到HC-05上,再通过串口通信和STM32通信;而之前一般都是电脑上通过USB线转串口的方式,通过串口和STM32通信。本质上没有区别的。

    这个时候就应该更加深刻地体会到了本文开篇的一句话:说白了,只是个蓝牙转串口的设备,你只要知道串口怎么编程使用,就可以了,实现了所谓的透明传输。蓝牙的相关一切都被封装起来了,都不需要接触到。

    STM32控制程序

    #include "stm32f10x.h"
    
     void My_USART1_Init(void)  
    {  
        GPIO_InitTypeDef GPIO_InitStrue;  
        USART_InitTypeDef USART_InitStrue;  
        NVIC_InitTypeDef NVIC_InitStrue;  
          
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//GPIO端口使能  
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//串口端口使能  
          
        GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;  
        GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9;  
        GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;  
        GPIO_Init(GPIOA,&GPIO_InitStrue);  
          
        GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;  
        GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;  
        GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;  
        GPIO_Init(GPIOA,&GPIO_InitStrue);  
          
        USART_InitStrue.USART_BaudRate=115200;  
        USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  
        USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;  
        USART_InitStrue.USART_Parity=USART_Parity_No;  
        USART_InitStrue.USART_StopBits=USART_StopBits_1;  
        USART_InitStrue.USART_WordLength=USART_WordLength_8b;  
          
        USART_Init(USART1,&USART_InitStrue);
          
        USART_Cmd(USART1,ENABLE);//使能串口1  
          
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启接收中断  
          
        NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;  
        NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;  
        NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;  
        NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;  
        NVIC_Init(&NVIC_InitStrue);  
          
    }  
      
    void USART1_IRQHandler(void)  
    {  
        u8 res;  
         if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)  
     {  
         res= USART_ReceiveData(USART1); 	 
         USART_SendData(USART1,res);     
      }  
    }  
       
     int main(void)  
     {    
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  
        My_USART1_Init();  
         while(1);  
           
     } 

    这段程序和【STM32】串口相关配置寄存器、库函数(UART一般步骤)中的程序一模一样,几乎没有什么改动。

    区别就是,在UART实验中,USART1是和USB转串口模块连接在一起的,然后与电脑上的串口调试助手进行通信;现在改成USART1是和蓝牙模块连接在一起的,然后和手机上的蓝牙串口调试助手进行通信。

     

    展开全文
  • 最近辛辛苦苦的终于把落下了七八月的Android蓝牙开发搞完了,其中的痛苦不堪回首啊。感谢那些帮了大忙的老师和同学们!辛苦归辛苦,收获总是有的,...而单片机上的蓝牙模块手机蓝牙连接有点不同,它的UUID号需要

           本文来自CSDN博客,转载请标明出处http://blog.csdn.net/xiluoduyu/

           最近辛辛苦苦的终于把落下了七八个月的Android蓝牙开发搞完了,其中的痛苦不堪回首啊。感谢那些帮了大忙的老师和同学们!辛苦归辛苦,收获总是有的,因而在此总结一下关键所在,以勉励自己!

           网上说的好多的Android蓝牙开发多是基于同类设备之间的通讯,大多需要建立一个服务端和客户端,客户端连接服务器需要服务端的UUID号。而单片机上的蓝牙模块与手机蓝牙连接有点不同,它的UUID号需要用well-know的“"00001101-0000-1000-8000-00805F9B34FB”,AndroidAPI里面强调过。

           接下来的通讯就简单了,跟一般的蓝牙通讯差不多,网上很多文章都有详细介绍,所以偷偷懒啦。。。

           由于蓝牙串口端的开发不是偶负责的,就不好说啥了。不过目测同学的开发调试过程好像也蛮简单的,就是个串口通信过程。我们用的是HWW-S1800蓝牙模块,因为手机端有蓝牙,所以实际上我们只用到了从模块而已,价格也不贵,主从模块才不到三百块。这个模块功能比较简单,但对我们足够用了,而且使用起来很简单。只需要将蓝牙串口模块和单片机连接起来,再在Keil和STC-ISP两个软件上开发就行了,好像这两开发环境都是c语言的,也比较简单,接收一下蓝牙模块发过来的字符信息,判断和处理一下给个回应就行了。具体过程还得请教学过单片机开发的同学了。

           (没想到会有怎么多的人需要,呵呵,看来当初的选题也还好呢,文档放到我的资源里面了 ,需要的可以下载)

            

    展开全文
  • 该App功能为通过蓝牙接收单片机采集的温度传感器数据,同时可以通过蓝牙发送预设温度数据给单片机 蓝牙通信代码仿照参考代码进行编写,不再提供github代码 关键代码 主要是接收和发送数据,在参考的代码里面...
  • ·简介:由于业务关系,需要开发一单片机发送数据的应用,不过由于需求很简单,只  需要发送数据即可,所以该dome的功能只有发送数据功能,并没有对输入的数据  做进一步的处理 这里有蓝牙开发的基本...
  • (2)安卓手机与蓝牙模块联合调试(二)—— 单片机蓝牙控制LED灯亮灭(上) (3)安卓手机与蓝牙模块联合调试(三)—— 单片机蓝牙控制LED灯亮灭(下) (4)安卓手机与蓝牙模块联合调试(四)—— 单片机数据...
  • 蓝牙(Bluetooth):是一种无线技术标准,可实现固定设备、移动设备...蓝牙技术最初由电信巨头爱立信公司于1994年创制,当时是作为RS232数据线的替代方案, 蓝牙可连接多个设备,在与单片机连接使用也得到了广泛应用。
  • (2)安卓手机与蓝牙模块联合调试(二)—— 单片机蓝牙控制LED灯亮灭(上) (3)安卓手机与蓝牙模块联合调试(三)—— 单片机蓝牙控制LED灯亮灭(下) (4)安卓手机与蓝牙模块联合调试(四)—— 单片机数据...
  • 这是博主学了51单片机第一次做的单片机项目,选择了许多人喜欢的蓝牙小车作为第一项目。 准备材料: 1.小车亚克力底盘 2.减速电机4(网上搜索有很) 3.蓝牙 HC-06 4.L298N步进电机 5.7.2V电源(记得配好接口,...
  • 我们平时用蓝牙,一般是单片机的串口与蓝牙的串口连接,实现数据传输,同时,也会用到mcu的其他一些功能,比如IIC,比如定时器,ADC等。但对于一些功能相对较少的产品,或者要求小体积的产品,这时候可以考虑把mcu省...
  • 蓝牙(Bluetooth):是一种无线技术标准,可实现固定设备、移动设备和楼宇...蓝牙可连接多个设备,在与单片机连接使用也得到了广泛应用。 1、端口连接 与单片机串口连接时,两者之间 相互可以读写。例如51给HC-05传递
  • STC89C52通过HC-06蓝牙模块Android手机通信   如需转载请标明出处:http://blog.csdn.net/itas109  QQ技术交流群:129518033  2017-11-04补充 注意问题: 1.确保上位机波特率为9600 2.确保下位机的波特...
  • 刚好碰到这蓝牙通信方面的项目,上网也看过其他人在蓝牙这方面写的博客,但大多都不全,给一些初触蓝牙的开发者造成一定的麻烦,自己当初也费了不少劲。所以把自己参考网上的一些资料用Android studio写的代码完全放...
  • 最近做毕设,需要写一简单的蓝牙APP进行交互,在网上也找了很资料,终于给搞定了,这里分享一下^_^。 1、Android蓝牙编程  蓝牙3.0及以下版本编程需要使用UUID,UUID是通用唯一识别码(Universally Unique ...
  • (2)安卓手机与蓝牙模块联合调试(二)—— 单片机蓝牙控制LED灯亮灭(上) (3)安卓手机与蓝牙模块联合调试(三)—— 单片机蓝牙控制LED灯亮灭(下) 本教程的项目地址:1989Jiangtao/BluetoothSCM: 安卓手机...
  • 下面的文字只是关于蓝芽技术的调制算法方面,我认为只需要将蓝芽模块加在单片机上就可以了,而不必通过单片机编程来实现具体的算法,只需要编写使两模块的接口就可以,也就是单片机发送信号时的激励程序,接受外来...
  • USB转TTL与蓝牙模块连接图 打开串口助手: 一开始用的是丁丁串口助手,发·AT不回OK。 后来用的是友善也不回。 原因是要,加回车。 (光标在蓝色的地方,而不是红色的地方,就算 自动换行 你打 √ 了,还是要加...
  • 本篇只要是实现51单片机的通信功能,所以我想要尽量的简化一下。话不说上代码! //先是ui线程的部分 这部分主意是监听控件 蓝牙的连接需要单独写一线程 //此部分代码只是截取 缺少的部分都可以脑补的出来。。...
1 2 3 4 5 ... 20
收藏数 2,723
精华内容 1,089