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. vue-loader和单页组件介绍

    一.Vue Loader介绍 Vue Loader 是一个 webpack 的loader,它允许你以一种名为 单文件组件(SFCs)的格式撰写 Vue 组件.官方文档地址如下所示: Vue Load ...

  2. Spring 常用配置、Bean

    spring模块 Spring-Core: Core包是框架的最基础部分,并提供依赖注入(Dependency Injection)管理Bean容器功能. Spring-Context:(Spring ...

  3. [LeetCode] 454. 4Sum II 四数之和之二

    Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such t ...

  4. [LeetCode] 390. Elimination Game 淘汰游戏

    There is a list of sorted integers from 1 to n. Starting from left to right, remove the first number ...

  5. Git的学习总结

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

  6. 分库分表数据库自增 id

    分库分表之后,ID 主键如何处理? 面试题 分库分表之后,id 主键如何处理? 面试官心理分析 其实这是分库分表之后你必然要面对的一个问题,就是 id 咋生成?因为要是分成多个表之后,每个表都是从 1 ...

  7. CountDownLatch 一个复杂的例子

    CountDownLatch复杂点的例子 public class CountDownLatchTest2 { private static Random random = new Random(Sy ...

  8. [转帖]分布式事务之解决方案(XA和2PC)

    分布式事务之解决方案(XA和2PC) https://zhuanlan.zhihu.com/p/93459200 3. 分布式事务解决方案之2PC(两阶段提交) 针对不同的分布式场景业界常见的解决方案 ...

  9. springboot xss防护

    概述 XSS(Cross Site Script)全称跨站脚本攻击,为了跟CSS区分开来,所以变成了XSS.它允许恶意代码植入到正常的页面中,盗取正常用户的账号密码,诱使用户访问恶意的网站. 攻击 实 ...

  10. Eureka和ZooKeeper的区别

    首先我们先说下: RDBMS==>(MySql,Oracle,SqlServer等关系型数据库)遵循的原则是:ACID原则(A:原子性.C:一致性.I:独立性.D:持久性.). NoSql==& ...