第09节-使用BTStack编写蓝牙程序
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编写蓝牙程序的更多相关文章
- c# 第四节 Net Framework编写应用程序的过程
本节 1:创建.net应用程序所经历的步骤 2:cli是什么 3:程序集是什么 4:jit编辑器 5:托管代码 1:创建.net应用程序所经历的步骤 2:cli是什么 3:程序集是什么 4:jit编辑 ...
- Java编写串口程序
用Java编写串口程序一般都会用到这个 http://fizzed.com/oss/rxtx-for-java 根据电脑的情况下载 解压以后有安装文档 For a JDK installation: ...
- 第3章 编写ROS程序-1
1.创建工作区和功能包 在我们写任何程序之前,第一步是创建一个容纳我们的功能包的工作区,然后再创建功能包本身. 创建工作区 使用标准的mkdir命令行去创建一个目录,我们将把这个新的目录称作工作区目 ...
- hive--构建于hadoop之上、让你像写SQL一样编写MapReduce程序
hive介绍 什么是hive? hive:由Facebook开源用于解决海量结构化日志的数据统计 hive是基于hadoop的一个数据仓库工具,可以将结构化的数据映射为数据库的一张表,并提供类SQL查 ...
- 编写C#程序的IDE
编写C#程序,在Windows平台下,除了昂贵的Visual Studio.NET这个正宗的工具外,你还了解哪些? 听说有个Eclipse,IBM投钱开发的开源工具,有人也做了个for .NET的pl ...
- C#入门到精通系列课程——第2章编写C#程序
◆本章内容 (1)熟悉Visual Studio 2017开发环境 (2)编写第一个C#程序 (3)C#程序结构预览 (4)程序编写规范 (5)难点解答 ◆本章简述 要学习C#编程,必然要熟悉C#程序 ...
- 如何使用c#编写单片机程序
因为个人喜爱想研究单片机,但是不太会c,然后再找资料研究有没有其他的方法发现国外的c# nanoframework 框架可以编写单片机程序,本文我将会用自己踩过的坑来总结一些c#编写单片机的一些经 ...
- CSharpGL(11)用C#直接编写GLSL程序
CSharpGL(11)用C#直接编写GLSL程序 +BIT祝威+悄悄在此留下版了个权的信息说: 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharp ...
- 在Linux上编写C#程序
自从C#开源之后,在Linux编写C#程序就成了可能.Mono-project就是开源版本的C#维护项目.在Linux平台上使用的C#开发工具为monodevelop.安装方式如下: 首先需要安装一些 ...
随机推荐
- 第02组 Beta冲刺(3/4)
队名:十一个憨批 组长博客 作业博客 组长黄智 过去两天完成的任务:了解整个游戏的流程 GitHub签入记录 接下来的计划:继续完成游戏 还剩下哪些任务:完成游戏 燃尽图 遇到的困难:没有美术比较好的 ...
- [LeetCode] 57. Insert Interval 插入区间
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessa ...
- TextView实现文字水平滚动效果
有时候我们使用TextView显示文本,只想把所有内容用一行显示出来,但是一行又显示不完,就需要让文本实现水平滚动的效果. 具体实现方法如下: 1,实现自定义TextView并实现isFocused( ...
- server 2012 r2 配置
filezilla的问题还是让人摸不着头脑,配置和别的机器上一样就是报STL权限错误,最后换了个端口就连上了. 服务器,填远端IP,被动模式打开,生成一个证书,被动模式的商品一定要在入站规则里 客户端 ...
- 集合类源码(五)Collection之BlockingQueue(LinkedTransferQueue, PriorityBlockingQueue, SynchronousQueue)
LinkedTransferQueue 功能 全名 public class LinkedTransferQueue<E> extends AbstractQueue<E> i ...
- Java学习:网络编程总结
Java网络编程总结 一.概述 计算机网络是通过传输介质.通信设施和网络通信协议,把分散在不同地点的计算机设备互连起来,实现资源共享和数据传输的系统.网络编程就就是编写程序使联网的两个(或多个)设备( ...
- vue基础之data
使用 调用data onLoad(option) { _self = this; _self.$data.xxxx = "te"; } 绑定节点 元素~~~~ <input ...
- Application类-欢迎页(初始界面)
在程序界面显示前,如果我们处理了很多耗时操作,这个时候给用户提示一个欢迎页便是十分友好的.WPF为我们提供了这个特性: 第一种方法:通过设置图片资源的生成操作 粘贴一个图片到我们的项目中 在解决方案管 ...
- [转载].NET Core 轻量级模板引擎 Mustachio
.NET Core 轻量级模板引擎 Mustachio 晓晨Master 一. 前言 Mustachio 是一款轻量级且强大的模板引擎,可以用在网页渲染.代码生成器等需要模板引擎的场景.我用它是用在配 ...
- C# 用Singleton类构建多线程单例模式
public sealed class Singleton { private static volatile Singleton uniqueInstance; p ...