蓝牙调试工具如何使用_使用此有价值的工具改进您的蓝牙项目:第2部分!

蓝牙调试工具如何使用

This post is originally from www.jaredwolff.com.

这篇文章最初来自www.jaredwolff.com。

This is Part 2 of configuring your own Bluetooth Low Energy Service using a Nordic NRF52 series processor. If you haven’t seen Part 1 go back and check it out. I’ll be waiting right here..

这是使用Nordic NRF52系列处理器配置自己的低功耗蓝牙服务的第2部分。 如果您还没有看到第1部分,请返回并进行检查。 我将在这里等

If you’re with me thus far, high five. ?

如果到目前为止你和我在一起,高五。 ?

Let’s jump in!

让我们跳进去!

So far we’ve created an efficient cross platform data structure using Protocol Buffers. This Protocol Buffer in particular can be used to send these defined data structures a Bluetooth Low Energy Service. In this part, I’ll show you the inner workings of creating the service from scratch.

到目前为止,我们已经使用协议缓冲区创建了有效的跨平台数据结构。 该协议缓冲区尤其可以用于向这些定义的数据结构发送蓝牙低功耗服务。 在这一部分中,我将向您展示从头开始创建服务的内部工作原理。

P.S. this post is lengthy. If you want something to download, click here for a a beautifully formatted PDF. (Added bonus, the PDF has all three parts of this series!)

PS这个帖子很长。 如果要下载某些内容, 请单击此处以获取格式精美的PDF。 (此外,PDF具有本系列的所有三个部分!)

创建服务 (Creating the Service)

Door Peoeple

Dealing with Bluetooth Low Energy in general can seem overwhelming. As I discussed here, there’s a few moving parts that you need to keep in mind.

通常,处理低功耗蓝牙似乎不堪重负。 正如我在这里讨论的那样,您需要牢记一些活动部分。

The best way to create a new service is to copy an already existing one! I’ve done this by:

创建新服务的最好方法是复制一个已经存在的服务! 我这样做是:

  1. Go to the sdk -> components -> ble -> ble_services -> ble_bas

    转到sdk->组件-> ble-> ble_services-> ble_bas
  2. Copy ble_bas.h to include/ble

    复制ble_bas.hinclude/ble

  3. Copy ble_bas.c to src/ble

    ble_bas.c复制到src/ble

I’ve then renamed them from ble_bas to ble_protobuf to be consistent. I’ve also done the same inside the files. (BAS is the battery level service used to report battery voltage or relative charge using a percentage)

然后,为了保持一致,我将它们从ble_bas重命名为ble_protobuf 。 我也在文件内部做了同样的事情。 (BAS是电池电量服务,用于以百分比形式报告电池电压或相对电量)

I’ve also gone ahead and removed all the battery measurement functions as they will be replaced. This part of the process is fairly tedious and prone to error. If you’re new to the Nordic SDK, I highly recommend you download the example code for this post.

我也继续进行并删除了所有电池测量功能,因为它们将被替换。 该过程的这一部分相当繁琐并且容易出错。 如果您是Nordic SDK的新手, 我强烈建议您下载本文的示例代码。

添加UUID (Adding a UUID)

Normally, for a vendor defined service you’ll have to use your own UUID. There are certain ranges of UUIDs that are reserved for the Bluetooth SIG. Supposedly you can also reserve your own UUID if you’re a member. Here’s a handy post on Stack Overflow on the subject.

通常,对于供应商定义的服务,您将必须使用自己的UUID。 有某些范围的UUID保留用于Bluetooth SIG。 如果您是会员,还可以保留自己的UUID。 这是有关该主题的Stack Overflow的便捷文章。

In our case, I’ve defined a UUID that I’ve used for other projects. If you go to ble_protobuf.h you can see the UUIDs for both the service and the characteristic:

在我们的案例中,我已经定义了用于其他项目的UUID。 如果转到ble_protobuf.h ,则可以看到该服务和特征的UUID:

// UUID for the Service & Char
#define PROTOBUF_UUID_BASE   {0x72, 0x09, 0x1a, 0xb3, 0x5f, 0xff, 0x4d, 0xf6, \0x80, 0x62, 0x45, 0x8d, 0x00, 0x00, 0x00, 0x00}
#define PROTOBUF_UUID_SERVICE     0xf510
#define PROTOBUF_UUID_CONFIG_CHAR (PROTOBUF_UUID_SERVICE + 1)

Both PROTOBUF_UUID_BASE PROTOBUF_UUID_SERVICE are used in ble_protobuf_init The last one is used in command_char_add (I’ll describe that a bit more below).

这两个PROTOBUF_UUID_BASE PROTOBUF_UUID_SERVICE在使用ble_protobuf_init最后一个是在使用command_char_add (我将介绍更多一点下文)。

You can go without defining a BASE ID but I highly recommend you go the extra mile. That way your application will be impervious to future Bluetooth protocol updates.

您可以在不定义BASE ID的情况下进行操作,但是我强烈建议您多加努力。 这样,您的应用程序将不受以后的蓝牙协议更新的影响。

创建特征 (Creating the Characteristic)

Open Those PICKLES!

Nordic has a fairly straight forward way of initializing separate characteristics in each service. For each characteristic, there is a char_add function which then configures and add the characteristic to the service.

Nordic在每种服务中初始化一个单独特征的方法相当简单。 对于每个特征,都有一个char_add函数,该函数然后配置该特征并将其添加到服务中。

使用ble_add_char_params_t配置特征 (Configure your Characteristic withble_add_char_params_t)

Nordic has put the configurations parameters for a BLE Characteristic into a logical (and helpful) struct. If you’re developing on a different platform you may find the same settings though all not in one place! (Or handled logically… ?)

Nordic已将BLE特性的配置参数放入逻辑(且有用)的结构中。 如果您在不同的平台上进行开发,则可能会发现相同的设置,尽管它们都不在一个地方! (或按逻辑处理……?)

Here’s the breakdown of the struct:

这是该结构的细分:

typedef struct
{uint16_t                    uuid;uint8_t                     uuid_type;uint16_t                    max_len;uint16_t                    init_len;uint8_t *                   p_init_value;bool                        is_var_len;ble_gatt_char_props_t       char_props;ble_gatt_char_ext_props_t   char_ext_props;bool                        is_defered_read;bool                        is_defered_write;security_req_t              read_access;security_req_t              write_access;security_req_t              cccd_write_access;bool                        is_value_user;ble_add_char_user_desc_t    *p_user_descr;ble_gatts_char_pf_t         *p_presentation_format;
} ble_add_char_params_t;

It’s here that you tell the BLE Stack about what type of characteristic this is. In this example I use a handful of parameters to define the Protobuf Command Characteristic.

您在这里告诉BLE堆栈这是什么类型的特征。 在此示例中,我使用了一些参数来定义Protobuf命令特征。

uuid defines the address of how the characteristic will be accessed. If you’re defining your own service. max_len is the maximum length of data that you may send though the characteristic. That’s why it’s important to set max_size in your Protocol Buffer .options file for all variable length parameters. Once you compile your Protocol Buffers you’ll get a *_size variable much like the one defined in command.pb.h Here's a snippet of what it looks like below:

uuid定义将如何访问特征的地址。 如果您要定义自己的服务。 max_len是您可以通过特征发送的最大数据长度。 这就是为什么在Protocol Buffer .options文件中为所有可变长度参数设置max_size的原因。 编译协议缓冲区后,您将获得一个*_size变量,就像在command.pb.h定义的变量一样。这是下面的代码片段:

/* Maximum encoded size of messages (where known) */
#define event_size                               67

Thus when defining ble_add_char_params_t I set max_len to event_size:

因此,在定义ble_add_char_params_t我将max_len设置为event_size

add_char_params.uuid                      = PROTOBUF_UUID_CONFIG_CHAR;
add_char_params.max_len                   = event_size;
add_char_params.is_var_len                = true;

Along the same lines, because we’re using a string as one of the parameters in the Protocol Buffer, this data can be of variable size. is_var_len is handy to make sure that the right amount of bytes is sent and received. The decode function of the Protocol Buffers will fail if more data is fed in than necessary. (I learned this the hard way!)

同样,由于我们使用字符串作为协议缓冲区中的参数之一,因此此数据的大小可以可变。 is_var_len可以方便地确保发送和接收正确数量的字节。 如果输入的数据超出了必要,协议缓冲区的解码功能将失败。 (我经过惨痛的教训才学到这个!)

char_props define the permissions for the characteristic. If you’re familiar with file system permissions on a computer, this will be second nature to you. In this example, read and write is what we’re looking for.

char_props定义特征的权限。 如果您熟悉计算机上的文件系统权限,这将是您的第二天性。 在这个例子中, 读取写入就是我们要寻找的。

Finally, parameters ending in _access determine the security type used. In most cases SEC_OPEN or SEC_JUST_WORKSis more than sufficient. If you’re handling critical data (passwords, etc) you may have to implement a second layer of encryption or enable a higher level security mode.

最后,以_access结尾的参数确定所使用的安全性类型。 在大多数情况下, SEC_OPENSEC_JUST_WORKS 。 如果要处理关键数据(密码等),则可能必须实施第二层加密或启用更高级别的安全模式。

If you’re looking on more info about Bluetooth Low Energy security, here’s a useful post on the subject.

如果您正在寻找有关蓝牙低功耗安全性的更多信息, 这是有关此主题的有用文章。

加。 天 字符 (Add. dat. char.)

Once you’ve defined your params, it’s as easy as calling the characteristic_add function. This will associate this new characteristic with the related service. The first argument is the service handle, the second the configuration parameters and the third is a pointer to the handles for the characteristic. (See below)

定义了参数之后,就像调用characteristic_add函数一样简单。 这会将这个新特性与相关服务相关联。 第一个参数是服务句柄,第二个参数是配置参数,第三个参数是指向特征句柄的指针。 (见下文)

uint32_t characteristic_add(uint16_t                   service_handle,ble_add_char_params_t *    p_char_props,ble_gatts_char_handles_t * p_char_handle)

使其运行 (Getting it Running)

Setting everything up inside ble_protobuf.c is 90% of the battle. The final mile requires some bits being added to services_init in main.c

ble_protobuf.c设置所有内容的工作是90%。 最后一英里需要将一些位添加到main.c services_init

ble_protobuf_init_t       protobuf_init = {0};protobuf_init.evt_handler          = ble_protobuf_evt_hanlder;protobuf_init.bl_rd_sec            = SEC_JUST_WORKS;protobuf_init.bl_cccd_wr_sec       = SEC_JUST_WORKS;protobuf_init.bl_wr_sec            = SEC_JUST_WORKS;err_code = ble_protobuf_init(&m_protobuf,&protobuf_init);APP_ERROR_CHECK(err_code);

The above allows events to be funneled back to the main context. That way your app becomes much more interactive with the core logic of your firmware code. In Nordic’s examples they’ve also brought the security parameters out so they can be defined in the main context as well.

上面的内容使事件可以漏回到主上下文中。 这样,您的应用程序就可以与固件代码的核心逻辑更加互动。 在Nordic的示例中,他们还提出了安全性参数,因此也可以在主要上下文中进行定义。

Side note: m_protobuf is defined using a macro from ble_protobuf.h It not only creates a static instance of the service but it also defines the callback that is used for handling events.

附注: m_protobuf使用宏定义从ble_protobuf.h它不仅创造了该服务的静态实例,但它也定义了用于处理事件的回调。

/**@brief Macro for defining a ble_protobuf instance.** @param   _name  Name of the instance.* @hideinitializer*/
#define BLE_PROTOBUF_DEF(_name)                          \static ble_protobuf_t _name;                         \NRF_SDH_BLE_OBSERVER(_name ## _obs,             \BLE_PROTOBUF_BLE_OBSERVER_PRIO, \ble_protobuf_on_ble_evt,        \&_name)

If you're making your own service, you'll have to update the function name for the event handler. If you need to tweak priorities you can define/update that as well.

如果您要提供自己的服务,则必须更新事件处理程序的函数名称。 如果您需要调整优先级,则也可以定义/更新优先级。

写入此特征后会发生什么? (What happens when this characteristic is written to?)

Smoke Signal

ble_protobuf_on_ble_evt is the main way that events are handled within Bluetooth Low Energy services. We’re most concerned with the BLE_GATTS_EVT_WRITE event but you can trigger on any GATT event that tickles your fancy.

ble_protobuf_on_ble_evt是在蓝牙低功耗服务中处理事件的主要方式。 我们最关心BLE_GATTS_EVT_WRITE事件,但是您可以触发任何让您BLE_GATTS_EVT_WRITE GATT事件。

on_write is where the action happens. It takes the data that is written to the characteristic and decodes it according to event_fields It’s all put conveniently into a struct for additional processing, etc. If an error happens in decoding, pb_decode returns an error. Once modified, the data is encoded and made available for reading. Since reading Part 1, the calls to pb_decode and pb_encode should look very familiar!

on_write是执行操作的地方。 它接受写入特征的数据,并根据event_fields对其进行解码。所有这些都方便地放入结构中以进行其他处理,等等。如果解码中发生错误,则pb_decode将返回错误。 修改后,数据将被编码并可供读取。 自阅读第1部分以来,对pb_decodepb_encode的调用应该看起来非常熟悉!

Of course, you can have your firmware do whatever you want to. The Bluetooth Energy World is your oyster.

当然,您可以让固件做任何您想做的事情。 蓝牙能源世界是您的牡蛎。

最后说明 (Final Notes)

When adding new services to a Bluetooth Low Energy example, you may have to make some changes to the underlying code.

在向低功耗蓝牙示例添加新服务时,您可能必须对基础代码进行一些更改。

For example, sdk_config.h may need some changes. Particularly NRF_SDH_BLE_VS_UUID_COUNT needs to be increased depending how many service UUIDs are made available. For this project, I am also using the DFU service (as it should be a default for all connected projects!!)

例如, sdk_config.h可能需要进行一些更改。 特别是需要增加NRF_SDH_BLE_VS_UUID_COUNT ,具体取决于有多少个服务UUID可用。 对于这个项目,我还使用了DFU服务(因为它应该是所有连接项目的默认设置!)

Another important aspect is memory and flash management. The default .ld file that comes with the BLE DFU service may not be sufficient for another BLE Service. The only way you’ll know there’s not enough is when you compile and flash it to a NRF52 device. If the device boots up stating there’s not enough memory, you’ll have to make the suggested changes. The error will show up on the debug console where this message normally shows up:

另一个重要方面是内存和闪存管理。 BLE DFU服务随附的默认.ld文件可能不足以用于另一个BLE服务。 唯一了解不足的方法是编译并刷新到NRF52设备。 如果设备启动后表明没有足够的内存,则必须进行建议的更改。 该错误将显示在通常显示此消息的调试控制台上:

<info> app: Setting vector table to bootloader: 0x00078000
<info> app: Setting vector table to main app: 0x00026000

Learn more about how to get the Debug Console set up in the example code here.

在此处的示例代码中了解有关如何设置调试控制台的更多信息。

结论 (Conclusion)

In this part I’ve shown you the inner workings of a custom Bluetooth Low Energy service using Protocol Buffers. In the last part, I’ll show you how to load the firmware, run the example javascript app and test our freshly developed Protocol Buffer!

在这一部分中,我向您展示了使用协议缓冲区的自定义低功耗蓝牙服务的内部工作原理。 在最后一部分中,我将向您展示如何加载固件,运行示例javascript应用程序以及测试我们新开发的Protocol Buffer!

翻译自: https://www.freecodecamp.org/news/improve-your-bluetooth-project-with-this-valuable-tool-part-2/

蓝牙调试工具如何使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/391749.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Matplotlib Numpy Pandas构想泰坦尼克号高潮

Did you know, a novel predicted the Titanic sinking 14 years previously to the actual disaster???您知道吗&#xff0c;一本小说预言泰坦尼克号在14年前沉没到了真正的灾难中&#xff1f;&#xff1f;&#xff1f; In 1898 (14 years before the Titanic sank), Amer…

pca数学推导_PCA背后的统计和数学概念

pca数学推导As I promised in the previous article, Principal Component Analysis (PCA) with Scikit-learn, today, I’ll discuss the mathematics behind the principal component analysis by manually executing the algorithm using the powerful numpy and pandas lib…

红黑树分析

红黑树的性质&#xff1a; 性质1&#xff1a;每个节点要么是黑色&#xff0c;要么是红色。 性质2&#xff1a;根节点是黑色。性质3&#xff1a;每个叶子节点&#xff08;NIL&#xff09;是黑色。性质4&#xff1a;每个红色节点的两个子节点一定都是黑色。不能有两个红色节点相…

overlay 如何实现跨主机通信?- 每天5分钟玩转 Docker 容器技术(52)

上一节我们在 host1 中运行了容器 bbox1&#xff0c;今天将详细讨论 overlay 网络跨主机通信的原理。 在 host2 中运行容器 bbox2&#xff1a; bbox2 IP 为 10.0.0.3&#xff0c;可以直接 ping bbox1&#xff1a; 可见 overlay 网络中的容器可以直接通信&#xff0c;同时 docke…

Python:实现图片裁剪的两种方式——Pillow和OpenCV

原文&#xff1a;https://blog.csdn.net/hfutdog/article/details/82351549 在这篇文章里我们聊一下Python实现图片裁剪的两种方式&#xff0c;一种利用了Pillow&#xff0c;还有一种利用了OpenCV。两种方式都需要简单的几行代码&#xff0c;这可能也就是现在Python那么流行的原…

鼠标移动到ul图片会摆动_我们可以从摆动时序分析中学到的三件事

鼠标移动到ul图片会摆动An opportunity for a new kind of analysis of Major League Baseball data may be upon us soon. Here’s how we can prepare.不久之后&#xff0c;我们将有机会对美国职棒大联盟数据进行新的分析。 这是我们准备的方法。 It is tempting to think t…

回到网易后开源APM技术选型与实战

篇幅一&#xff1a;APM基础篇\\1、什么是APM?\\APM&#xff0c;全称&#xff1a;Application Performance Management &#xff0c;目前市面的系统基本都是参考Google的Dapper&#xff08;大规模分布式系统的跟踪系统&#xff09;来做的&#xff0c;翻译传送门《google的Dappe…

如何选择优化算法遗传算法_用遗传算法优化垃圾收集策略

如何选择优化算法遗传算法Genetic Algorithms are a family of optimisation techniques that loosely resemble evolutionary processes in nature. It may be a crude analogy, but if you squint your eyes, Darwin’s Natural Selection does roughly resemble an optimisa…

PullToRefreshListView中嵌套ViewPager滑动冲突的解决

PullToRefreshListView中嵌套ViewPager滑动冲突的解决 最近恰好遇到PullToRefreshListView中需要嵌套ViewPager的情况,ViewPager 作为头部添加到ListView中&#xff0c;发先ViewPager在滑动过程中流畅性太差几乎很难左右滑动。在网上也看了很多大神的介绍&#xff0c;看了ViewP…

神经网络 卷积神经网络_如何愚弄神经网络?

神经网络 卷积神经网络Imagine you’re in the year 2050 and you’re on your way to work in a self-driving car (probably). Suddenly, you realize your car is cruising at 100KMPH on a busy road after passing through a cross lane and you don’t know why.想象一下…

数据特征分析-分布分析

分布分析用于研究数据的分布特征&#xff0c;常用分析方法&#xff1a; 1、极差 2、频率分布 3、分组组距及组数 df pd.DataFrame({编码:[001,002,003,004,005,006,007,008,009,010,011,012,013,014,015],\小区:[A村,B村,C村,D村,E村,A村,B村,C村,D村,E村,A村,B村,C村,D村,E村…

如何在Pandas中使用Excel文件

From what I have seen so far, CSV seems to be the most popular format to store data among data scientists. And that’s understandable, it gets the job done and it’s a quite simple format; in Python, even without any library, one can build a simple CSV par…

数据特征分析-对比分析

对比分析是对两个互相联系的指标进行比较。 绝对数比较(相减)&#xff1a;指标在量级上不能差别过大&#xff0c;常用折线图、柱状图 相对数比较(相除)&#xff1a;结构分析、比例分析、空间比较分析、动态对比分析 df pd.DataFrame(np.random.rand(30,2)*1000,columns[A_sale…

Linux基线合规检查中各文件的作用及配置脚本

1./etc/motd 操作&#xff1a;echo " Authorized users only. All activity may be monitored and reported " > /etc/motd 效果&#xff1a;telnet和ssh登录后的输出信息 2. /etc/issue和/etc/issue.net 操作&#xff1a;echo " Authorized users only. All…

tableau使用_使用Tableau升级Kaplan-Meier曲线

tableau使用In a previous article, I showed how we can create the Kaplan-Meier curves using Python. As much as I love Python and writing code, there might be some alternative approaches with their unique set of benefits. Enter Tableau!在上一篇文章中 &#x…

Nexus3.x.x上传第三方jar

exus3.x.x上传第三方jar&#xff1a; 1. create repository 选择maven2(hosted)&#xff0c;说明&#xff1a; proxy&#xff1a;即你可以设置代理&#xff0c;设置了代理之后&#xff0c;在你的nexus中找不到的依赖就会去配置的代理的地址中找hosted&#xff1a;你可以上传你自…

责备的近义词_考试结果危机:我们应该责备算法吗?

责备的近义词I’ve been considering writing on the topic of algorithms for a little while, but with the Exam Results Fiasco dominating the headline news in the UK during the past week, I felt that now is the time to look more closely into the subject.我一直…

c/c++编译器的安装

MinGW(Minimalist GNU For Windows)是个精简的Windows平台C/C、ADA及Fortran编译器&#xff0c;相比Cygwin而言&#xff0c;体积要小很多&#xff0c;使用较为方便。 MinGW最大的特点就是编译出来的可执行文件能够独立在Windows上运行。 MinGW的组成&#xff1a; 编译器(支持C、…

numpy 线性代数_数据科学家的线性代数—用NumPy解释

numpy 线性代数Machine learning and deep learning models are data-hungry. The performance of them is highly dependent on the amount of data. Thus, we tend to collect as much data as possible in order to build a robust and accurate model. Data is collected i…

spring 注解方式配置Bean

概要&#xff1a; 再classpath中扫描组件 组件扫描&#xff08;component scanning&#xff09;&#xff1a;Spring可以从classpath下自己主动扫描。侦測和实例化具有特定注解的组件特定组件包含&#xff1a; Component&#xff1a;基本注解。标示了一个受Spring管理的组件&…