开发你的第一个BLE应用程序—Blinky

本文将和大家一起编写我们的第一个BLE应用程序:Blinky(闪灯程序),哪怕你之前没有任何BLE开发经验,也不用担心,只要跟着文中所述步骤,你就可以一步步搭建自己的第一个BLE应用程序。通过这个Blinky程序的搭建,你将体会到BLE的一些基本概念,对BLE将会有一个非常直观的认识,为后续自己的BLE应用程序开发打下一个坚实的基础。

1. 开发准备

1)     nRF52或者nRF51开发板1块。请参考“Nordic nRF51/nRF52开发流程说明”,购买相应开发板(DK)。

2)     开发环境搭建。简述如下(详细说明请参考“Nordic nRF51/nRF52开发环境搭建”):

  1. 安装Keil5 MDK
  2. 安装SDK。如果你使用的是nRF52开发板,请安装nRF5 SDK15.0.0,下载链接:https://www.nordicsemi.com/eng/nordic/download_resource/59012/70/52858981/116085。如果你手上是nRF51开发板,请下载nRF5 SDK12.3.0:https://www.nordicsemi.com/eng/nordic/download_resource/54280/56/38442131/32925nRF51最高SDK版本只能到12.3.0,后续SDK就不再支持nRF51
  3. 安装ARM CMSIS4.5.0,下载链接:https://github.com/ARM-software/CMSIS/releases/download/v4.5.0/ARM.CMSIS.4.5.0.pack
  4. 安装Keil5 Device Family Pack,下载链接:https://www.nordicsemi.com/eng/nordic/download_resource/58865/28/26535159/87790
  5. 安装nRF5 Command Line Tools,下载链接(Windows版):https://www.nordicsemi.com/eng/nordic/download_resource/58850/47/60411125/53210
  6. 安装安卓版或者iOS版nRF connect。iOS版nRF connect请到苹果app store下载,搜索“nRF”即可以找到。安卓版nRF connect可以到Nordic Github官网上下载,下载链接为:https://github.com/NordicSemiconductor/Android-nRF-Connect/releases
  7. 安装PC版nRF connect或者nRFgo studio。PC版nRF connect下载链接(Windows版):https://www.nordicsemi.com/eng/nordic/download_resource/58847/15/21277021/108233

注:如果你使用的是Linux系统/Mac系统,或者你使用的不是Keil5-MDK,请参考“Nordic nRF51/nRF52开发环境搭建”来搭建你的开发环境。

2. 运行Blinky程序

请按照如下步骤运行SDK自带的Blinky程序

1)     确认自己的芯片型号或者开发板。如果采用Nordic官方开发板的话,芯片型号和开发板编号对应关系如下:

  • nRF51系列对应开发板编号为PCA10028
  • nRF52832和nRF52810对应开发板编号为PCA10040
  • nRF52840对应开发板编号为PCA10056

这里我会以nRF52832开发板PCA10040为例阐述整个开发过程,其他开发板与之类似,大家自己可以举一反三来开始自己的开发之旅。

2)     将开发板与PC机通过USB线相连,同时打开开发板电源(将左下角的拨位开关打到“ON”位置),打开桌面版nRF Connect,选择启动“Programmer”应用,由于驱动之前已经安装好了,设备可以立即识别成功。执行“full erase”操作,以擦除芯片原始内容。

3)     打开SDK中的Blinky程序。对于blinky程序,如果是52832开发板,请打开:nRF5_SDK_15.0.0_a53641a\examples\ble_peripheral\ble_app_blinky\pca10040\s132\arm5_no_packs;如果是51822开发板,请打开:nRF5_SDK_12.3.0_d7731ad\examples\ble_peripheral\experimental_ble_app_blinky\pca10028\s130\arm5_no_packs

后续将以52832开发板为例来阐述,51822与之类似就不再阐述了。

注:Nordic SDK例程目录结构为:SDK版本/ examples /协议角色/例子名称/开发板型号/协议栈型号/工具链类型/具体工程,比如下面例子:

Nordic每一个例子都支持5种工具链:Keil5/Keil4/IAR/GCC/SES,如下所示:

4)     编译上面的blinky程序。如果你已经按照之前的说明配置好了开发环境,那么这里编译是不会报任何错的。(如果你遇到了编译错误,请重新按照前面说明去搭建你的开发环境,不要怀疑SDK例子代码有问题哦)

5)     程序下载。程序下载包括2步:先下载softdevice,再下载应用。Softdevice是Nordic蓝牙协议栈的名称,整个开发过程中只需下载一次。应用就是我们这里的blinky程序。

  • 蓝牙协议栈下载(整个开发周期只下载一次)。在Keil ‘select target’下拉列表中,默认选择的是Keil工程对应的Target,即‘nrf52832_xxaa’。我们还可以选择另一个target ‘flash_s132_nrf52_6.0.0_softdevice’,即softdevice对应的target,然后点击“下载download”(不需要编译哦!),此时会把softdevice下载到开发板中。

  • 应用下载。重新选择Target:‘nrf52832_xxaa’,点击“下载Download”,此时会把Blinky程序下载到开发板中。此时开发板的LED1常亮,表示程序运行正常。

6)     打开手机蓝牙和手机版nRF connect。在nRF connect中,你将看到一个广播设备:Nordic_Blinky,这个就是我们的开发板。

7)     连接设备。点击“CONNECT”,手机将与设备建立连接,并开始服务发现过程,连接成功后,LED1熄灭,LED2点亮,最后将得到如下界面。

由上图可见,Blinky程序包含三个service:Generic Access(GAP),Generic Attribute(GATT),以及Nordic LED Button Service,GAP和GATT都是标准的蓝牙service,Nordic LED Button Service是Blinky程序自定义的service,它又具体包括两个characteristic:Button和LED。

8)     测试Blinky程序。点击右上角的“Enable CCCDs”以使能notification,如下:

按下开发板上的Button1按键,你会发现nRF connect中的Button characteristic Value会实时显示按键状态:pressed或者released。

点击nRF connect中的LED characteristic右边的向上箭头,选择“ON”并“SEND”,你会发现开发板的LED3将点亮;选择“OFF”并“SEND”,LED3又将熄灭。

3. 定制你的Blinky程序

3.1 修改广播名称

如前所述,Blinky程序默认的广播名字是:Nordic_Blinky,我们现在将其修改为“My_Blinky”,怎么做呢?我们在Keil中全文搜索“Nordic_Blinky”,发现有如下宏定义:

#define DEVICE_NAME                     "Nordic_Blinky"

我们只需将这里的Nordic_Blinky换成My_Blinky,即

#define DEVICE_NAME                     "My_Blinky"

就可以实现我们的目标了。重新编译下载blinky程序,在nRF connect中,你将看到:

你再全文搜索一下“DEVICE_NAME”,你会发现广播名字其实是通过如下API来完成修改的:

    err_code = sd_ble_gap_device_name_set(&sec_mode,

                                          (const uint8_t *)DEVICE_NAME,

                                          strlen(DEVICE_NAME));

注:Keil的搜索功能非常好用,很多问题都可以通过它来解决

3.2 修改广播间隔

如nRF connect界面所示,blinky程序的广播间隔大概为40ms左右,现在为了节省功耗,我们将其改为200ms,通过搜索,我们可以看到如下宏定义:

#define APP_ADV_INTERVAL                64                                      /**< The advertising interval (in units of 0.625 ms; this value corresponds to 40 ms). */

因此为了将广播间隔改为200ms,只需将APP_ADV_INTERVAL改成200/0.625 = 320,即

#define APP_ADV_INTERVAL                320

重新编译下载blinky程序,在nRF connect中,你将发现广播间隔已改为200ms了:

3.3 修改Button characteristic行为 (设备发数据给手机)

现在的Blinky程序,只有按下开发板的Button1时,nRF connect的Button characteristic 值才会更新。我们现在新增一个功能:当按下开发板的Button 2时,让Button characteristic value更新为5(注: nRF connect把1当成按键按下,把0当成按键释放,为了更直观,我们没有选择0或者1,而是随便选择一个值:5)。我们先找到Button1按下的回调函数,如下所示:

       case LEDBUTTON_BUTTON:

            NRF_LOG_INFO("Send button state change.");

            err_code = ble_lbs_on_button_change(m_conn_handle, &m_lbs, button_action);

            if (err_code != NRF_SUCCESS &&

                err_code != BLE_ERROR_INVALID_CONN_HANDLE &&

                err_code != NRF_ERROR_INVALID_STATE &&

                err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)

            {

                APP_ERROR_CHECK(err_code);

            }

            break;

可以看出,我们是通过ble_lbs_on_button_change来更新Button characteristic的值的,ble_lbs_on_button_change具体函数实现如下所示:

uint32_t ble_lbs_on_button_change(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t button_state)

{

    ble_gatts_hvx_params_t params;

    uint16_t len = sizeof(button_state);

    memset(&params, 0, sizeof(params));

    params.type   = BLE_GATT_HVX_NOTIFICATION;

    params.handle = p_lbs->button_char_handles.value_handle;

    params.p_data = &button_state;

    params.p_len  = &len;

    return sd_ble_gatts_hvx(conn_handle, &params);

}

我们可以仿照Button1的做法,来添加Button2的代码。首先初始化app_button模块,让button2按下事件可以被button_event_handler捕获,如下:

    static app_button_cfg_t buttons[] =

    {

        {LEDBUTTON_BUTTON, false, BUTTON_PULL, button_event_handler},

       {BSP_BUTTON_1, false, BUTTON_PULL, button_event_handler}

    };

然后在button_event_handler调用ble_button2_send(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t val),以更新Button characteristic的值,代码如下所示:

        case BSP_BUTTON_1:
                      NRF_LOG_INFO("Button2 pressed.");
                      ble_button2_send(m_conn_handle, &m_lbs, 5);
                      break;

ble_button2_send(m_conn_handle, &m_lbs, 5)实现代码如下所示:

uint32_t ble_button2_send(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t val)

{

    ble_gatts_hvx_params_t params;

    uint16_t len = sizeof(val);

    memset(&params, 0, sizeof(params));

    params.type   = BLE_GATT_HVX_NOTIFICATION;

    params.handle = p_lbs->button_char_handles.value_handle;  //Button characteristic value handle

    params.p_data = &val;

    params.p_len  = &len;

    return sd_ble_gatts_hvx(conn_handle, &params);        

}

重新编译下载blinky程序,连接设备,使能cccd,按下Button2,你会看到Button characteristic的值变为5:

3.4 修改LED characteristic行为(手机发数据给设备)

由于nRF connect把LED characteristic的值写死了,只能发送“ON”或者“OFF”,前面也测试过,发送“ON”之后,LED3将点亮,其实这里的“ON”,就是数值1。我们现在增加一个新的功能:在收到“ON”命令后,把LED4 toggle一下。

这个实现起来比较简单,我们只需在led_write_handler中添加bsp_board_led_invert(BSP_BOARD_LED_3),整体代码如下所示:

static void led_write_handler(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t led_state)

{

    if (led_state)

    {

        bsp_board_led_on(LEDBUTTON_LED);

        NRF_LOG_INFO("Received LED ON!");

        bsp_board_led_invert(BSP_BOARD_LED_3);

    }

    else

    {

        bsp_board_led_off(LEDBUTTON_LED);

        NRF_LOG_INFO("Received LED OFF!");

    }

}

重新编译下载blinky程序,连接设备,你会发现第一次发送“ON”,LED4点亮,第二次发送“ON”,LED4又将熄灭。

通过全文搜索“led_write_handler”,你会发现这个函数是被ble_lbs.c中的on_write调用,而on_write又被ble_lbs_on_ble_evt调用,而ble_lbs_on_ble_evt就是我们的BLE事件回调函数,每当softdevice收到LED characteristic的写操作时,都会调用它,这就是通过nRF connect操作设备的过程和原理。

这篇文章主要让大家对BLE有个大概的认识,后面我会专门写一篇文章来介绍上面提到的BLE service,characteristic,write,notify以及CCCD等,以帮助大家深刻理解这些概念。

原文地址:https://www.cnblogs.com/iini/p/8996025.html

时间: 2024-11-06 22:16:25

开发你的第一个BLE应用程序—Blinky的相关文章

Android adt bundle 开发环境配置及第一个“Hello world”程序运行

    最近在学习Android 顺便记录下学习过程当作复习吧,这是写的第一篇正式博客.  一.jdk环境配置     二.android adt bundle 下载     三.安装SDK     四.模拟器及真机调试     五.第一个程序 Hello world!     六.总结 一.jdk环境配置 jdk下载地址 选中"Accept License Agreement"之后才能下载,如下图: 下载之后 点击安装,一路next 之后配置环境变量 JAVA_HOME,找到jdk安

IMX6开发板创建第一个Android应用程序helloworld

运行行 AndroidStudio 程序.如下图,选择创建一个新的 androidstudio 工程(基于 迅为-i.mx6开发板)应用名称改为“helloworld”,项目保存路径修改为自己的保存路径.连续点击下一步,直到如下界面,选择“Basic Activity”模板.继续点击下一步直到出现如下界面.点击“Finish”按钮,完成创建工程. 部分视频观看地址( 更多视频教程可在B站上搜索‘迅为电子’ ) iTOP-4412精英版开发板硬件连接 https://www.bilibili.co

WP8开发--------------我的第一个wp8小程序

一:截图,功能介绍:点击音乐红色按钮,播放铃声 二:代码 XAML代码 <phone:PhoneApplicationPage x:Class="PhoneApp1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ph

Android平台BLE应用程序开发指南

从Android 4.3开始,BLE(Bluetooth Low Energy)在Android平台上被支持了.但是目前Android上BLE应用程序稀少,尤其是中文应用程序,希望本文对有兴趣开发BLE应用程序的开发者有所帮助.本文主要是对目前已有的Andriod BLE开发相关资料进行整理,给出一个开发资料的索引.(本文会根据大家的问题,不断完善) 基本参考资料 最基本的学习资料是这篇Android官方文档:<Bluetooth Low Energy>.该文档对BLE涉及的基本概念进行了介绍

Netty入门二:开发第一个Netty应用程序

    既然是入门,那我们就在这里写一个简单的Demo,客户端发送一个字符串到服务器端,服务器端接收字符串后再发送回客户端. 2.1.配置开发环境 1.安装JDK 2.去官网下载jar包 (或者通过pom构建) 2.2.认识下Netty的Client和Server 一个Netty应用模型,如下图所示,但需要明白一点的是,我们写的Server会自动处理多客户端请求,理论上讲,处理并发的能力决定于我们的系统配置及JDK的极限. Client连接到Server端 建立链接发送/接收数据 Server端

Web程序员开发App系列 - 开发我的第一个App,源码下载

Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 Web程序员开发App系列 - 开发我的第一个App 待续 目录 前言 源码和App下载 准备工作 查看留言页面 增加留言页面 前言 看了前面几篇文章后我们终于要开始敲代码了,由于所有前端代码都是Html静态问题,所以你用什么开发工具都可以,后台我采用MVC开发,因为Html静态文件需要打包,里面

【物联网(IoT)开发】使用 Arduino 和 Python在 Bluemix 上开发一个 IoT 应用程序之控制LED灯开关

上篇"[物联网(IoT)开发]Arduino 入门 Hello World(LED闪烁)"只是通过将一段程序烧录到Arduino开发板上控制LEC闪烁,没有任何连网动作,也就是说断开网络提供电源依然还可以工作.本文将介绍如何开发一个应用程序,以便使用适用于物联网 (Internet of Things, IoT) 的技术.我们的应用程序通过串口收集数据,将其存储在一个 Web 服务器上,然后在网页上实时显式结果,并可以在网页上控制LED的开关. 构建一个类似的应用程序的前提条件 对于第

李洪强iOS开发之【零基础学习iOS开发】【02-C语言】02-第一个C语言程序

前言 前面已经唠叨了这么多理论知识,从这讲开始,就要通过接触代码来学习C语言的语法.学习任何一门语言,首先要掌握的肯定是语法.学习C语言语法的目的:就是能够利用C语言编写程序,然后运行程序跟硬件(计算机.手机等硬件设备)进行交互.由于我们的最终目的是学习iOS开发,学习iOS开发的话必须在Mac系统下,因此我就在Mac系统环境下开发C语言程序,而不是在Windows环境下. 接下来,就在Mac系统环境下编写第一个C语言程序,最后把程序运行起来,跟计算机做一个小小的互动 一.编写第一个C语言程序-

80. 投奔怒海——一个Domino老程序员眼里的Java开发

这是一个以键盘鼠标为谋生工具已十多年的人初次进行专门的Java开发的体验和感受,对于Java程序员,这些也许早就习以为常,那就把这当成从一个来自不同世界的新人眼里看看他们自己的工作:对于我的Domino同行,这些体验或许将来有更多共鸣的可能. 在加入到这个Java产品开发团队之前,我的Java开发经验如下:十几年前跟着一本Java入门书做练习写的几个Applet,Domino项目开发中写的几个读写数据库和外部邮件的代理,XPages开发中的少量Java Beans和一个流程库.除此之外就只剩下对