基于nRF7002-DK的NFC功能切换系统(nRF Connect SDK+NFC)

目录

  • 项目介绍
  • 硬件介绍
  • 项目设计
    • 开发环境及工程目录
    • 总体流程图
    • 硬件初始化
    • NFC功能实现
      • 文本记录
      • 安卓应用打开
      • 按键切换功能
  • 功能展示
  • 项目总结

👉 【Funpack2-6】基于nRF7002-DK的NFC功能切换系统
👉 Github: EmbeddedCamerata/nRF7002-DK-nfc-function-switching

项目介绍

本项目基于nRF7002-DK,使用nRF Connect SDK v2.4.2 开发,使用NFC外设,实现NFC记录英文文本信息、中文文本信息与打开安卓应用三个功能,并可通过按键切换,通过手机NFC触碰即可触发。

👉 官网:nRF Connect SDK

硬件介绍

nRF7002-DK是用于nRF7002 Wi-Fi 6协同IC的开发套件,该开发套件采用nRF5340多协议片上系统 (SoC) 作为nRF7002的主处理器,在单一的电路板上包含了开发工作所需的一切,可让开发人员轻松开启基于nRF7002 的物联网项目。该 DK 包括 Arduino 连接器、两个可编程按钮、一个 Wi-Fi 双频段天线和一个低功耗蓝牙天线,以及电流测量引脚。

这款DK支持低功耗 Wi-Fi 应用开发,并实现了多项 Wi-Fi 6 功能,比如 OFDMA、波束成型和 TWT。nRF7002 Wi-Fi 6配套IC为另一个主机添加了低功耗Wi-Fi 6功能,提供无缝连接和基于Wi-Fi的定位(本地Wi-Fi集线器的SSID嗅探)功能。该IC设计用于搭配Nordic现有的nRF52®和nRF53®系列多协议片上系统 (SoC) 和nRF91®系列蜂窝物联网系统级封装 (SiP) 使用。nRF7002 IC 还可与非nordic主机器件搭配使用。通过SPI或QSPI与主机通信,并带有额外的共存功能,可与其他协议如蓝牙、Thread或Zigbee无缝共存。

nRF7002在Nordic的nRF Connect SDK中提供集成和支持。

板卡特性:

  • 用于nRF7002双频带Wi-Fi 6配套IC的开发套件
  • nRF5340 SoC主机器件
  • Wi-Fi 6 (IEEE 802.11 a/b/g/n/ac/ax)、蓝牙低功耗(LE)、蓝牙网状网络、802.15.4、Thread、Zigbee®、ANT、2.4GHz专有和NFC无线协议支持2.4GHz、5GHz芯片和NFC天线
  • SWF射频连接器
  • SEGGER J-Link板载编程器/调试器
  • 用户可编程LED (2x) 和按钮 (2x)
  • 用于测量功耗的引脚
  • 来自USB、外部或锂聚合物电池的2.9V至5.0V电源
  • Arduino连接器

nRF7002结构框图

项目设计

开发环境及工程目录

根据 官网文档 手动安装SDK等依赖,nRF Connect SDK 版本 v2.4.2 。由于笔者是Linux环境,且有一定的洁癖,因此在安装 west 的时候单独为其使用Poetry,创建了一个Python虚拟环境。并在此基础上,安装额外的Python依赖。每次使用 west 先激活Python虚拟环境即可。

👉 Poetry

工程目录可根据 ncs/nrf/samples 中的sample复制一份,并在此基础上添加自己的代码或配置。例如:

├ build(编译时所产生的构建文件)
├ src
│ ├ main.c
│ └ ...(如有需要,其他的源代码)
├ CMakeLists.txt
├ prj.conf
├ sample.yaml
├ README.rst(项目说明文档)
└ ...

prj.conf 中配置需要启用的库,从而在编译程序的时候编译对应的头文件。sample.yaml 仅做描述示例程序之用。此外,Kconfig 是为了用户可在menuconfig内手动配置某些选项(主要是可选功能),在本工程中省略。

CMakeLists.txt 内,额外添加 set(BOARD nrf7002dk_nrf5340_cpuapp) ,从而在 west build 时可省略 -b nrf7002dk_nrf5340_cpuapp) 参数。

cmake_minimum_required(VERSION 3.20.0)
set(BOARD nrf7002dk_nrf5340_cpuapp)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(nfc_function_switching)
FILE(GLOB app_sources src/*.c)
# NORDIC SDK APP START
target_sources(app PRIVATE ${app_sources})
# NORDIC SDK APP END

总体流程图

工程流程图

硬件初始化

在此初始化板卡上的LED与按键。并将LED2打开以表示板卡正常工作。

dk_buttons_init(NULL);
dk_leds_init();
dk_set_led_on(SYSTEM_ON_LED);

NFC功能实现

首先通过 nfc_t2t_setup 注册NFC事件的回调函数,其回调函数内主要响应NFC标签检测到外部NFC场时与移除时的事件。当检测到外部NFC场时,LED1亮起,移除时灭。

nfc_t2t_setup(nfc_callback, NULL)static void nfc_callback(void *context,nfc_t2t_event_t event,const uint8_t *data,size_t data_length)
{ARG_UNUSED(context);ARG_UNUSED(data);ARG_UNUSED(data_length);switch (event){case NFC_T2T_EVENT_FIELD_ON:dk_set_led_on(NFC_FIELD_LED);break;case NFC_T2T_EVENT_FIELD_OFF:dk_set_led_off(NFC_FIELD_LED);break;default:break;}
}

文本记录

主要使用nRF提供的nfc库。先生成NDEF文本记录描述符,再将这个记录加入NDEF消息中,之后 nfc_ndef_msg_encode 编码,并存入 buffer 内,长度为 len

static int nfc_text_encode(uint8_t *buffer, uint32_t *len)
{NFC_NDEF_TEXT_RECORD_DESC_DEF(nfc_text_rec,UTF_8,en_code,sizeof(en_code),en_payload,sizeof(en_payload));NFC_NDEF_MSG_DEF(nfc_text_msg, MAX_REC_COUNT);/* Add record */if (nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_text_msg),&NFC_NDEF_TEXT_RECORD_DESC(nfc_text_rec)) < 0){printk("Cannot add record!\n");return -1;}/* Encode text message */if (nfc_ndef_msg_encode(&NFC_NDEF_MSG(nfc_text_msg), buffer, len) < 0){printk("Cannot encode message!\n");return -1;}return 0;
}

需要注意的是如何编码中英文文本信息至NDEF。对于英文使用UTF-8编码,直接编码ASCII字符,例如“Hello, World!”:

static const uint8_t en_payload[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!'};
static const uint8_t en_code[] = {'e', 'n'};NFC_NDEF_TEXT_RECORD_DESC_DEF(nfc_text_rec,UTF_8,en_code,sizeof(en_code),en_payload,sizeof(en_payload));

而对于中文信息,例如“遥遥领先!”,每个中文字符需要UTF-16编码,但是 NFC_NDEF_TEXT_RECORD_DESC_DEF 宏内传入的数据的类型却是 uint8_t const* ,因此需要将“遥遥领先!”对应十六进制“\u6590\u6590\u8698\u4851\u01ff”拆分,先写低位再高位,使用UTF-16编码:

static const uint8_t zh_payload[] = {'\x90', '\x65', '\x90', '\x65', '\x98', '\x86', '\x51', '\x48', '\xff', '\x01'};
static const uint8_t zh_code[] = {'z', 'h'};NFC_NDEF_TEXT_RECORD_DESC_DEF(nfc_text_rec,UTF_16,zh_code,sizeof(zh_code),zh_payload,sizeof(zh_payload));

安卓应用打开

所需要的是安卓应用的名称 android_pkg_name。在此,将打开明日方舟 com.hypergryph.arknights 。并通过 nfc_launchapp_msg_encode 完成该类型消息的创建与编码,并存到 buffer,长度为 len

/* Package: com.hypergryph.arknights */
static const uint8_t android_pkg_name[] = {'c', 'o', 'm', '.','h', 'y', 'p', 'e', 'r', 'g', 'r', 'y', 'p', 'h', '.','a', 'r', 'k', 'n', 'i', 'g', 'h', 't', 's'};
static int nfc_launchapp_encode(uint8_t *buffer, uint32_t *len)
{/* Encode launch app data  */if (nfc_launchapp_msg_encode(android_pkg_name,sizeof(android_pkg_name), NULL, 0, buffer, len) < 0){printk("Cannot encode message!\n");return -1;}return 0;
}

按键切换功能

实现该功能,需要一个 enum 类型变量 nfc_app_t 存储当前功能的类别。并在初始化NFC功能后,在 while (true) 循环内扫描按键,判断 DK_BTN1 是否按下,按下则切换功能类别,同时根据 nfc_app 重新生成NFC payload并设置。

typedef enum
{NFC_APP_TEXT = 0U,NFC_APP_LAUNCHAPP
} nfc_app_t;// In main() function
while (true)
{dk_read_buttons(&button_state, NULL);if (button_state & DK_BTN1_MSK){nfc_app = 1 - nfc_app;/* Stop sensing NFC field */if (nfc_t2t_emulation_stop() < 0){printk("Cannot stop emulation!\n");return -1;}if (nfc_payload_set(nfc_app) < 0){printk("NFC payload set failed!\n");goto fail;}}k_sleep(K_MSEC(200));
}

需要注意的是,两种功能的payload,长度、内容不同,如果它们共用同一个buffer存储NDEF消息,例如 static uint8_t buffer[256]; ,实测会出错。因此,单独为两个功能各自设置一个buffer用于存储NDEF消息。那么,根据 nfc_app 的值,编码与设置不同类别的NDEF消息:

/* Buffer used to hold an NFC NDEF message. */
#define NDEF_MSG_BUF_SIZE 256
static uint8_t text_msg_buf[NDEF_MSG_BUF_SIZE];
static uint8_t launch_app_msg_buf[NDEF_MSG_BUF_SIZE];// When nfc_app_t == NFC_APP_TEXT
len = sizeof(text_msg_buf);
nfc_text_encode(text_msg_buf, &len);
/* Set created message as the NFC payload */
nfc_t2t_payload_set(text_msg_buf, len);// When nfc_app_t == NFC_APP_LAUNCHAPP
len = sizeof(launch_app_msg_buf);
nfc_launchapp_encode(launch_app_msg_buf, &len);
/* Set created message as the NFC payload */
nfc_t2t_payload_set(launch_app_msg_buf, len);

功能展示

板卡:

板卡全貌
通过按键切换NFC功能,串口打印提示语句:

串口打印
当功能为记录英文文本信息时,手机NFC触碰后,可读取文本信息“Hello, World!” UTF-8编码。

NFC读取英文文本信息
当功能为记录中文文本信息时,手机NFC触碰后,可读取文本信息“遥遥领先!” UTF-16编码。

NFC读取中文文本信息
当功能为记录安卓应用信息时,手机NFC触碰后,可读取应用信息“com.hypergryph.arknights”,即明日方舟包名。此外,当不用NFC标签助手等APP读取NFC信息,而直接触碰,则会唤起应用。

NFC读取安卓应用信息
在手机NFC触碰后,LED2将亮起,手机移开后,NFC连接移除,LED2灭。

👉 详细展示参见:B站:基于nRF7002-DK的NFC功能切换系统

项目总结

本次项目使用nRF7002-DK开发板,使我接触了Nordic家产品的开发环境,N家的开发环境如果使用VSCode插件全套的话,体验还算不错。但只是在笔者Linux端上VSCode插件识别不到板子,因此只能手动安装SDK、Zypher等工具,这个流程上倒是不难,只不过west工具还需要依赖Python,但隔离得不如esp-idf优雅。在编译流程上,有esp-idf的经验那么对于N家的流程就差不多。

工程上,借助NFC实现了多个功能切换,这让我学习了有关NFC的概念,对NFC功能了解更为深入,同时还让我接触到安卓设备投屏至Linux端的软件(推荐scrcpy)。希望日后再有机会用N家的开发板,能更深入地学习设备树、Kconfig、prj.conf、Zypher 等知识。

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

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

相关文章

ADS放大器模型参数含义

ADS放大器模型参数含义 S21 : Forward Transmission Coefficient, use xj*y, polar(x,y), dbpolar(x,y) for complex value 增益&#xff0c;X是增益大小&#xff0c;y是相位 S11 : Forward Reflection Coefficient, use xj*y, polar(x,y), dbpolar(x,y), vswrpolar(x,y) for …

新手学习:ArcGIS对shp文件裁剪

新手学习&#xff1a;ArcGIS对SHP文件裁剪 新手学习 记录每个步骤&#xff0c;因为有很多控件可能刚开始还不熟悉&#xff0c;根本不知道在哪里&#xff0c;所以写的比较详细。 1.添加要裁剪的shp文件 2.查看shp文件的地理坐标系 双击shp文件&#xff0c;就可以查看shp文件的…

C语言——贪吃蛇小游戏

目录 一、ncurse 1.1 为什么需要用ncurse&#xff1a; 1.2 ncurse的输入输出&#xff1a; 1.2.1 如何使用ncurse&#xff1a; 1.2.2 编译ncurse的程序&#xff1a; 1.2.3 测试输入一个按键ncurse的响应速度&#xff1a; 1.3 ncurse上下左右键获取&#xff1a; 1.3.1 如…

TypeScript 从入门到进阶之基础篇(一) ts类型篇

系列文章目录 文章目录 系列文章目录前言一、安装必要软件二、TypeScript 基础类型1.基础类型之 数字类型 number2.基础类型之 字符串类型 string3.基础类型之 布尔类型 boolean4.基础类型之 空值类型 void5.基础类型之 null 、undefined类型6.基础类型之 任意类型 any &#x…

解决ModuleNotFoundError: No module named ‘diffusers.models.cross_attention‘

目录 项目场景: 问题描述 原因分析: 解决方案: 方案一:

面向面试知识--Lottery项目

面向面试知识–Lottery项目 1.设计模式 为什么需要设计模式&#xff1f; &#xff08;设计模式是什么&#xff1f;优点有哪些&#xff1f;&#xff09; 设计模式是一套经过验证的有效的软件开发指导思想/解决方案&#xff1b;提高代码的可重用性和可维护性&#xff1b;提高团…

vue3 - Element Plus暗黑模式适配、切换及自定义颜色

GitHub Demo 地址 在线预览 Element Plus 2.2.0 版本开始支持暗黑模式&#xff0c;启用方式参考 Element Plus 官方文档 - 暗黑模式 demo通过Element Plus和VueUse 的 useDark 方法实现具有自动数据持久性的响应式暗黑模式。 安装 npm install element-plus --save npm in…

canvas-绘图库fabric.js简介

一般情况下简单的绘制&#xff0c;其实canvas原生方法也可以满足&#xff0c;比如画个线&#xff0c;绘制个圆形、正方形、加个文案。 let canvas document.getElementById(canvas);canvas.width 1200;canvas.height 600;canvas.style.width 1200px;canvas.style.height 6…

R绘制箱线图

代码大部分来自boxplot()函数的帮助文件&#xff0c;可以通过阅读帮助文件&#xff0c;调整代码中相应参数看下效果&#xff0c;进而可以理解相应的作用&#xff0c;帮助快速掌握barplot()函数的用法。 语法 Usage(来自帮助文件) barplot(height, ...)## Default S3 method: …

就只说 3 个 Java 面试题

在面试时&#xff0c;即使是经验丰富的开发人员&#xff0c;也可能会发现这是一些很棘手的问题&#xff1a; 1、Java中“transient”关键字的用途是什么&#xff1f;如何才能实现这一目标&#xff1f; 在 Java 中&#xff0c;“transient”关键字用于指示类的特定字段不应包含…

使用RKDevTool将update.img完整镜像进行解包,得到单独分区的镜像

(1)使用开发工具高级功能的解包 导入xx.img,然后点击解包(2)在Output/Android/Image得到想要的image

Linux关于memory cgroup的几个要点

概述 本文讲述memory cgroup比较容易误解的一些逻辑&#xff0c;如果不太经常使用和解决问题的话&#xff0c;对于memory cgroup的认知会比较浅显&#xff1a;cgroup memory用来限制进程的内存使用&#xff0c;但是我们进一步想如下的问题&#xff1a; 进程的内存可以分很多类…

Vue的路由使用,Node.js下载安装及环境配置教程 (超级详细)

前言&#xff1a; 今天我们来讲解关于Vue的路由使用&#xff0c;Node.js下载安装及环境配置教程 一&#xff0c;Vue的路由使用 首先我们Vue的路由使用&#xff0c;必须要导入官方的依赖的。 BootCDN - Bootstrap 中文网开源项目免费 CDN 加速服务https://www.bootcdn.cn/ <…

IP协议的相关特性

IP协议相关特性 报头结构 报文结构解释 4位版本号:指定IP协议的版本,对于IPV4来说,就是四位. 4位首部长度:IP头部的长度是多少个32bit,也就是Length4的字节数,4bit表示的最大的数是15,因此IP头部最大长度是60. 8位服务类型:3位优先权字段&#xff08;已经弃用&#xff09;&…

安全生产知识竞赛活动小程序界面分享

安全生产知识竞赛活动小程序界面分享

linux内核分析:进程通讯方式

信号 一旦有信号产生,我们就有下面这几种,用户进程对信号的处理方式。 1.执行默认操作。Linux 对每种信号都规定了默认操作,例如,上面列表中的 Term,就是终止进程的意思。Core 的意思是 Core Dump,也即终止进程后,通过 Core Dump 将当前进程的运行状态保存在文件里面…

Python画图系列——折线图

好看的折线图 import numpy as np import matplotlib.pyplot as plt# 生成随机数据 # np.random.seed(42) # 设置随机种子以确保可重复性 sample_numbers np.arange(1, 21) # 生成1到20的样本编号random_data np.random.rand(20) # 生成20个随机数&#xff0c;范围在0到1之…

淘宝商品详情数据采集

淘宝商品详情数据采集的方法如下&#xff1a; 确定采集目标&#xff1a;明确要采集的商品信息&#xff0c;如商品标题、价格、销量、评论、图片等。选择采集工具&#xff1a;可以选择Scrapy框架、Java的WebMagic框架等。编写爬虫程序&#xff1a;进入目标文件夹&#xff0c;输…

无涯教程-JavaScript - POWER函数

描述 POWER函数返回加到幂的数字的输出。 语法 POWER (number, power)争论 Argument描述Required/OptionalNumber 基数。 它可以是任何实数。 RequiredPowerThe exponent to which the base number is raised.Required Notes 可以使用" ^"运算符代替POWER来指示…

八一书《乡村振兴战略下传统村落文化旅游设计》许少辉瑞博士生辉少许——2023学生开学季许多少年辉光三农

八一书《乡村振兴战略下传统村落文化旅游设计》许少辉瑞博士生辉少许——2023学生开学季许多少年辉光三农