Bluetooth LE Exploer(微软提供的)可以读取BLE蓝牙设备,可以读写它的值。本篇博客将使用BTStack写出一个精简版的Bluetooth LE Exploer。

涉及文件:

btstack-master\example\le_data_channel_client.c

btstack-master\example\Makefile.inc

注意:在PC上使用软件Bluetooth LE Exploer来操作蓝牙模块时,使用系统自带的驱动;

使用btstack来操作蓝牙模块时,使用winusb驱动(使用zadig-2.4.exe安装此驱动)

在手机上使用蓝牙时,过程如下:

1. 扫描周边的蓝牙设备

2. 选择某个设备,连接它

3. 使用该设备

一、程序效果:

我们写的蓝牙程序也包含这3个过程,我设计出4个菜单:

1.主菜单:

********* Main Menu *********

[s] show scan menu

[c] show connect menu

[t] show test menu

可以在主菜单中:

输入s进入“Scan Menu”,

输入c进入“Connect Menu”,

输入t进入“Test Menu”。

2. 扫描菜单:

********* Scan Menu *********

[s] scan ble devices

[t] stop scan ble devices

[l] list ble devices

[q] Back to main menu

可以在扫描菜单中:

输入s开始扫描周边设备,扫描结果会打印出来,并在程序中保存起来;

输入t停止扫描;

输入l列出扫描到的设备;

输入q退回到主菜单。

3. 连接菜单:

********* Connect Menu *********

List devices have beenn scanned

[0] 100ASK

[1] Mi Band 2

[?] Enter the device's number to connect

[d] Disconnet

[q] Back to main menu

在连接菜单的前面,会首先列出之前扫描到的设备。

在连接菜单中,

输入所列设备的序号,就会连接它;

输入d则断开连接;

输入q退回到主菜单。

4. 测试菜单:

********* Test Menu *********

[r] read att handle 42

[w] write att handle 42

[q] back to main menu

在测试菜单中,

输入r则会读取handle等于42的属性的值;

输入w则写handle等于42的属性的值;

输入q退回到主菜单。

注意

之所以固定读写handle 42是为了简化程序,

42这个值是事先使用软件Bluetooth LE Explorer连接设备后确定的,你的设备可能有所不同。

二、程序演示:

启动MSYS2 MinGW 64-bit,进入btstack-master/port/windows-winusb目录:

1. 执行 make 命令编译程序

2. 执行以下命令启动程序:

winpty  ./le_data_channel_client.exe

注意:在MSYS2下Windows的stdin无法使用,必须通过winpty来启动程序。

3. 在主菜单中:输入s进入扫描菜单

4. 在扫描菜单中:输入s开始扫描设备

在手机上,启动“Bluetooth LE Peripheral”,选择“100ASK”,点击“START”按钮。

这时在MSYS2中可以看到不断打印如下信息(这表示不断收到手机发来的广播信号):

advertisement_report_gets_name get 100ASK

5. 在扫描菜单中:输入t停止扫描设备

6. 在扫描菜单中:输入q退回到主菜单

7. 在主菜单中:输入c进入连接菜单

8. 在连接菜单中:输入0表示连接第扫描到的第0个设备

9. 在连接菜单中:输入q退回到主菜单

10. 在主菜单中:输入t进入测试菜单

11. 在测试菜单中:输入w写数值

观察手机上“Bluetooth LE Peripheral”的Service-1中收到的值。

不断输入w,可以观察到手机上收到的值不断加1。

12. 在测试菜单中:输入r读取数值

13. 在测试菜单中:输入q退回到主菜单

14. 在主菜单中:输入c进入连接菜单

15. 在连接菜单中:输入d断开连接

三、主要函数:

本程序主要源文件是btstack-master\example\le_data_channel_client.c,我在上面做了大量的修改。

1.要用键盘来控制程序,需要给程序增加一个“数据源”,即btstack_data_source_t结构体。

这个数据源从stdin获得数据,根据这些数据进行菜单操作。

使用如下代码增加数据源:

btstack_stdin_setup(stdin_process);

stdin_process是我们编写的处理函数。

2. 启动扫描:

printf("Start scanning!\n");

state = TC_W4_SCAN_RESULT;

gap_set_scan_parameters(0,0x0030, 0x0030);

gap_start_scan();

3. 记录打描结果:

扫描到的设备会上报3种信息:MAC地址、地址类型、名。我们要从上报的信息中取出这些信息,记录起来。

使用函数gap_event_advertising_report_get_address获得地址;

使用函数gap_event_advertising_report_get_address_type获得地址类型;

使用函数advertisement_report_gets_name获得名字(这函数是我从advertisement_report_contains_name改出来的)。

这3个信息会保存在ble_devs结构体数组中。

4. 连接设备:

gap_connect(ble_devs[i].le_data_channel_addr, ble_devs[i].le_data_channel_addr_type);

gap_connect函数只需要2个参数:MAC地址、地址类型。

连接成功后会返回一个hci_con_handle_t,也就是一个16位的整数。

一个中央设备可以连接多个外设,每一个连接都用一个hci_con_handle_t来分辨。

5. 断开连接:

gap_disconnect(connection_handle);

6. 写数据:

gatt_client_write_value_of_characteristic_without_response(connection_handle, 42, 1, &g_value);

第1个参数表示要写哪一个设备,用connection_handle 来表示(哪一个连接对应的设备);

第2个参数表示要写哪一个属性,每一个属性也都有一个标号即handle;

第3个参数表示要写多少字节的数据;

第4个参数表示数据的buffer。

7. 读数据:

gatt_client_read_value_of_characteristic_using_value_handle(handle_gatt_client_event,connection_handle, 42);

第2个参数表示要写哪一个设备,用connection_handle 来表示(哪一个连接对应的设备);

第3个参数表示要写哪一个属性,每一个属性也都有一个标号即handle;

第1个参数比较特殊:读数据时,要先向外设备发出无线信号,过一会收到对方发回到信号后,才可以解析出数据。所以读函数不可能立刻返回结果,我们需要提供一个回调函数。第1个参数就是一个回调函数。

在回调函数中,我们去解析数据,从中取出我们关注的数值。

回调函数handle_gatt_client_event源自btstack-master\test\pts\Ble_central_test.c,我做了一些精简。

第09节-使用BTStack编写蓝牙程序的更多相关文章

  1. c# 第四节 Net Framework编写应用程序的过程

    本节 1:创建.net应用程序所经历的步骤 2:cli是什么 3:程序集是什么 4:jit编辑器 5:托管代码 1:创建.net应用程序所经历的步骤 2:cli是什么 3:程序集是什么 4:jit编辑 ...

  2. Java编写串口程序

    用Java编写串口程序一般都会用到这个 http://fizzed.com/oss/rxtx-for-java 根据电脑的情况下载 解压以后有安装文档 For a JDK installation: ...

  3. 第3章 编写ROS程序-1

    1.创建工作区和功能包 在我们写任何程序之前,第一步是创建一个容纳我们的功能包的工作区,然后再创建功能包本身. 创建工作区  使用标准的mkdir命令行去创建一个目录,我们将把这个新的目录称作工作区目 ...

  4. hive--构建于hadoop之上、让你像写SQL一样编写MapReduce程序

    hive介绍 什么是hive? hive:由Facebook开源用于解决海量结构化日志的数据统计 hive是基于hadoop的一个数据仓库工具,可以将结构化的数据映射为数据库的一张表,并提供类SQL查 ...

  5. 编写C#程序的IDE

    编写C#程序,在Windows平台下,除了昂贵的Visual Studio.NET这个正宗的工具外,你还了解哪些? 听说有个Eclipse,IBM投钱开发的开源工具,有人也做了个for .NET的pl ...

  6. C#入门到精通系列课程——第2章编写C#程序

    ◆本章内容 (1)熟悉Visual Studio 2017开发环境 (2)编写第一个C#程序 (3)C#程序结构预览 (4)程序编写规范 (5)难点解答 ◆本章简述 要学习C#编程,必然要熟悉C#程序 ...

  7. 如何使用c#编写单片机程序

    ​ 因为个人喜爱想研究单片机,但是不太会c,然后再找资料研究有没有其他的方法发现国外的c# nanoframework 框架可以编写单片机程序,本文我将会用自己踩过的坑来总结一些c#编写单片机的一些经 ...

  8. CSharpGL(11)用C#直接编写GLSL程序

    CSharpGL(11)用C#直接编写GLSL程序 +BIT祝威+悄悄在此留下版了个权的信息说: 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharp ...

  9. 在Linux上编写C#程序

    自从C#开源之后,在Linux编写C#程序就成了可能.Mono-project就是开源版本的C#维护项目.在Linux平台上使用的C#开发工具为monodevelop.安装方式如下: 首先需要安装一些 ...

随机推荐

  1. Web协议详解与抓包实战:HTTP1协议-如何传递 IP 地址?(6)

    一.HTTP消息在服务器端的路由 Host 头部 规范与实现间是有差距的 二.代理服务器转发消息时的相关头部 1.Host 头部与消息的路由 2.客户端与源服务器间存在多个代理 三.如何传递 IP 地 ...

  2. [LeetCode] 920. Number of Music Playlists 音乐播放列表的个数

    Your music player contains N different songs and she wants to listen to L (not necessarily different ...

  3. 申请Github学生包(用学生证就行,免教育邮箱)

    GitHub教育包的福利: 大名鼎鼎的JetBrains给学生教师的免费个人许可 https://education.github.com/pack/redeem/jetbrains 有Github学 ...

  4. Git的学习总结

    首先,Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目.  Git 也是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件. ...

  5. <a href="javascript:;">的用法说明

    <a href="javascript:;">的用法说明 1.标签的 href 属性用于指定超链接目标的 URL,href 属性的值可以是任何有效文档的相对或绝对 UR ...

  6. 用欧拉计划学Rust编程(第26题)

    最近想学习Libra数字货币的MOVE语言,发现它是用Rust编写的,所以先补一下Rust的基础知识.学习了一段时间,发现Rust的学习曲线非常陡峭,不过仍有快速入门的办法. 学习任何一项技能最怕没有 ...

  7. sql server删除重复记录只保留一条

    今天遇到一个历史导入数据重复的问题,于是要删除重复的记录,一开始想用子查询的方式找到要删除记录的id删除,后来发现DELETE语句可以直接用外连接,这样更加简单,效率也更高. delete sys_p ...

  8. log4j打印抛出异常时堆栈内容

    JAVA 中为快速定位,抛出异常的位置.往往需要在日志中描述. log.err("异常出错点", e); 会将出错时的堆栈信息显示出来. package com.jqyc.jase ...

  9. Notepad++使用护眼便捷小技巧

    Notepad++是一款很好用的写笔记和代码的应用. 我们可以用它来写博客草稿和日常的笔记.那么,长时间看一个界面,当然会对眼睛有伤害. 所以,一个护眼的背景.是必须的. 下面就是我经常用到的护眼色, ...

  10. KVM虚拟机典型配置文件xml

    <domain type='kvm'> <name>vm64-1</name> //虚拟机名称 <memory unit='MiB'>2300</ ...