加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 相关推荐
申请入驻 产业图谱

实践篇 跑步机和划船机的蓝牙开发

9小时前
87
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

前面的文章里面讲了很多蓝牙基础的协议和硬件方面的知识,现在进入实践篇

今天我介绍一下,我使用磐启微的PAN1070来实现一个室内自行车的应用,最后把源码和硬件放在gitee上面,大家可以回家改造一下自己的傻瓜运动器械。

先介绍一下PAN1070,这是一个蓝牙SOC,主打低功耗来替换Nordic的蓝牙SOC,众所周知哈,国产替代势不可挡。

这个芯片的接收功耗还是比较低的,并且有512KB的FLASH,可以实现非常多的功能,最主要是的磐启微自己提供了很多的实际的案例,在开发的时候,我们可以直接参照案例修改一下就可以应用起来。

同时,PAN1070的最新的SDK是基于开源的NimBLE协议栈开发,和火热的ESP32的蓝牙协议栈一样,这样上手起来也会比较轻松。

首先,我们先把官方的SDK下载到本地,然后在我们的Gitee上创建一个仓库,并将SDK上传上去,作为一个基础版本。

https://gitee.com/geek-pi/pan1070.git

官方的SDK从这里下载:https://wiki.panchip.com/download/2799/

官方文档地址:https://docs.panchip.com

也可以从上面网址进入文档介绍后,从最左下角选择对应的版本的SDK,对了官方叫NDK,是指的基于NimBLE协议栈的版本,后续还有ZDK,这个是基于Zephyr的,所以别迷糊了。

整个SDK包括几个内容

SDK包含了我们编程序是需要的源代码和示例代码,HDK更多的是硬件相关的,比如各种开发板等,我们可以先不理会。MCU是一些控制器相关的使用例程,我们可以在用到某些单片机外设的时候再去了解,DOC和Tools都是一些文档和工具。遇到问题时在去看吧。

我们先来看原厂提供的例程有哪些?

在目录SDK→nimble→samples→solutions中有很多现成的解决方案,我们做新的应用的时候,可以在这里找相似的去做修改,有一些也可以直接用,比如透传模块,直接使用appuart,还有多主机多从机连接的案例,可以使用blehiduartmult_roles这个案例。

因为我本期介绍的是实现一个室内自行车的方案,所以我选择了一个比较简单的案例来修改,也就是blevehicleskey 。

这个方案本来功能是实现接近解锁的,内部通过RSSI来判断是否要对电动车或者电动门之类的设备进行解锁。这个有空可以了解下,今天主要看如何在这个例程上修改为室内自行车。

先说一下我的开发习惯

在基础的仓库上,我会新建一个分支,并以实现的功能作为命名,然后直接在官方的例程上做修改,这样基本上不需要自己搭建环境,同时还可以在vs code中看到所有例程的代码,方便来回copy。

每个例程中的代码其实很简单,一个文件件存放工程配置信息,一个文件件存放源代码,用户自己添加的代码都可以放到src中。

我们使用keil打开工程

虽然这里引用了很多文件,大部分都是蓝牙协议栈和freeRTOS相关的底层代码,我们可以先不关心他们,主要先要了解的是上图中的2部分,第一个是SDK的配置文件,他里面是一些配置选型,利用的keil的头文件注释界面来配置各种参数。第二部分就是调用nimble相关的API来实现蓝牙的功能,基本上就是配置广播帧广播,然后配置服务和服务对应的读写接口。

先来看一下配置界面

由于配置信息很多,这里只介绍我用到的,就是这里的log打印系统,这里要根据我们手里的板子的链接来选择一下,我的板子使用的串口log输出引脚是P05,波特率我选择的115200 。

之后,我们编译这个项目,下载运行后,就可以看到串口的logo信息了。

下载不了?是不是烧录算法没有找到,我们需要把SDK目录下的烧录算法拷贝到keil中,keil就可以找到了,SDK烧录算法的路径为:SDK3MCUmcumisc 。

下图是串口打印信息

现在,我们的例程已经跑起来了,我们的DIY才刚刚开始。

一、创建新的分支来开发室内自行车,命名为ftms

在基础工程上新建分支来开发新功能,可以保证各个项目公用一个基础,不必新建立很多工程,直接利用SDK现有的工程即可。通过git管理,还可以保证他们之间互不影响。

ftms是运动健康协议的缩写,这里使用它来作为分支名。

二、修改广播信息,让顽鹿等APP认识我们的蓝牙设备

广播信息的修改在main函数中,函数名称为:bleprph_advertise(),所有的广播参数都是在这里写入到一个缓存中,基本上就是按照数据+长度这样的结构堆积进去的。

这里我们需要把广播帧设置为下图这样:

具体含义可以参考这个文章

//首先增加UUID,也就是FTM的标准UUID,这个是一个宏定义。fields.uuids16 = (bleuuid16t[]) {        BLEUUID16INIT(BTUUIDFTM)    };    fields.num_uuids16 = 1;// Service Data AD Type: 0x16 (1 byte)uint8_t service_data[] = {    0x26, 0x18,         // Fitness Machine Service UUID (0x2618, 小端存储)    0x01,               // Flags (0x01, bit0 set to indicate Fitness Machine Available)    0x30, 0x00          // Fitness Machine Type (0x1000, 表示划船机类型,2字节小端)};
fields.svc_data_uuid16 = service_data;fields.svc_data_uuid16_len = sizeof(service_data);

这样广播以后,顽鹿APP中就可以看到我们的设备了。

三、添加一些对应的服务和特性

上位机APP发现我们的设备只是第一步,第二部是让我们的设备可以和APP通信。那么,我们就需要设定一个接口协议来和上位机通信,这就是蓝牙协议中的标准,我们要配置多个服务,以及服务内部包含的特征。这些特征有的是可读写的,有的是只读的,也有的是可以Notify的,可以理解为蓝牙设备主动给APP发的。

我们下面在代码中看看如何增加这样的属性和特性进去。这个修改要在gatt_svr.c中进行,它是定义了一个数据类型,可以说是结构体套着结构体的一个结构,这样写主要是为了直观,因此我们改代码也就直观了。

static const struct blegattsvcdef gattsvrsvcs[] = {    //服务    {        /* Service: 显示属性的DIS/        .type = BLEGATTSVCTYPEPRIMARY,        .uuid =  BLEUUID16DECLARE(BTUUIDDIS),        .characteristics = (struct blegattchrdef[]) {         {            .uuid =  BLEUUID16DECLARE(BTUUIDDISMODEL),            .accesscb = gattsvrchraccessftminfo,  //只读的只需要回调函数            .flags = BLEGATTCHRFREAD, //只读        },        {            .uuid =  BLEUUID16DECLARE(BTUUIDDISMNS),            .accesscb = gattsvrchraccessftminfo,  //只读的只需要回调函数            .flags = BLEGATTCHRFREAD, //只读        },        {            0, / No more characteristics in this service /        }, }    },    //新的服务    {        / Service: vendor ble uart /        .type = BLEGATTSVCTYPEPRIMARY,        .uuid =  BLEUUID16DECLARE(BTUUIDFTM),        .characteristics = (struct blegattchrdef[]) {             {                / Characteristic: Heart-rate measurement /                .uuid = BLEUUID16DECLARE(BTUUIDFTMINDOORBIKE),                .accesscb = gattsvrchraccessftms,                .valhandle = &hrsftmshandle,  //Notify 对应的handle句柄                .flags = BLEGATTCHRFNOTIFY,            }, //            {//                / Characteristic: Heart-rate measurement ///                .uuid = BLEUUID16DECLARE(BTUUIDFTMSTATUS),//                .accesscb = gattsvrchraccessftms,//                .valhandle = &hrsftmshandle,//                .flags = BLEGATTCHRFNOTIFY | BLEGATTCHRFREAD,//            },            {                / Characteristic: Heart-rate measurement /                .uuid = BLEUUID16DECLARE(BTUUIDFTMCTRL),                .accesscb = gattsvrchraccessftms,                .valhandle = &ftmctrlhandle,//Notify 对应的handle句柄                .flags = BLEGATTCHRFWRITE | BLEGATTCHRF_INDICATE,            },            {                0, / No more characteristics in this service /            },         }    },    //其他服务    {        0, / No more services */    },};

第一个属性是FTMS要求的服务,APP会从这个服务中读取各种属性,比如厂家,序列号,型号以及产品类型等等,他们基本上都是只读的,因此,可以从程序中看到,他的flags属性的设置。

对于只读的特性,我们只需要设置一个回调函数就可以了,比如:.accesscb = gattsvrchraccessftminfo,  //只读的只需要回调函数。

在回调函数中,我们来处理上位机的读取请求,就是把我们本地定义好的字符串返回给协议栈。

磐启微电子

磐启微电子

上海磐启微电子有限公司是国内从事无人机、物联网、无线通信芯片及系统解决方案的高新技术企业,公司成立于2010年,由数名留美归国博士创立,在射频、模拟及SOC等集成电路领域均拥有雄厚的研发实力,具有自主知识产权的核心技术并创造了多项国际先进的发明专利。公司总部座落在上海张江高科技园区,在苏州工业园区内设立了研发中心,在深圳设立了分公司。

上海磐启微电子有限公司是国内从事无人机、物联网、无线通信芯片及系统解决方案的高新技术企业,公司成立于2010年,由数名留美归国博士创立,在射频、模拟及SOC等集成电路领域均拥有雄厚的研发实力,具有自主知识产权的核心技术并创造了多项国际先进的发明专利。公司总部座落在上海张江高科技园区,在苏州工业园区内设立了研发中心,在深圳设立了分公司。收起

查看更多

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录