Funpack第二季第六期活动
—基于nRF7002-DK使用板卡的NFC功能制作B站up主社交主页—
一、项目介绍
本项目基于Funpack2-6活动,采用nRF Connect SDK 2.4.0,板子硬件型号nRF7002-DK,实现了B站up主社交主页的制作。本项目通过手机扫描板卡nRF7002-DK的nfc卡片展示B站up主页信息功能,免去了手动点击输入,打开浏览器的的步骤,可以很方便的一键关注,查看作品,具有一定的价值。
项目任务:
- 使用板卡的NFC功能,模拟出一个自定义功能的卡片,使用手机靠近并能读取卡片信息
二、设计思路
本项目设计围绕板卡nRF7002-DK,首先对nRF7002-DK的板载硬件进行实验使用,初步掌握板载的IO硬件以及nRF7002-DK能够实现的功能与实际性能。再根据硬件nfc卡片的具体功能,实现设计。设计步骤如下:
- 配置nRF Connect SDK并烧录固件,电脑连接nRF7002-DK板卡。
- 如图:
- 烧录成功后开始写程序。因为无需配置网络,只要将外置nfc卡片连接到板卡,将nfc配置好写入文件中,手机nfc扫描即可,获取B站up主社交主页信息。
- 软件流程图及功能如下:
- 用户nRF7002-DK连接外置的NFC卡片靠近NFC功能的手机。
- 手机读取NFC卡片的信息。
- 判断读取的NFC卡片信息是否符合规范
- 如果符合,则打开预设B站up主社交主页,并展示内容。
- 如果不符合,则提示NFC卡片信息错误。
三、硬件介绍
nRF7002 DK是nRF7002 Wi-Fi6协同IC的开发评估板,它包含了在单板上开发所需要的所有元器件。开发板采用nRF5340多协议SoC作为主处理器,配合nRF7002Wi-Fi协同芯片。可以同时支持低功耗蓝牙和Wi-Fi 应用的开发,并实现如 OFDMA、波束成形和目标唤醒时间等多项 Wi-Fi 6 功能。
nRF7002是Nordic的Wi-Fi产品系列中的首款器件,符合802.11ax标准,可提供双频段(2.4和5GHz)连接,支持Matter中使用的全部无线协议,可以为产品中添加最新的Wi-Fi 6技术,该芯片还具有帮助保护用户数据的先进安全功能。并与Nordic现有的超低功率技术无缝结合,可延长电池使用寿命。它提供快速、可靠的连接,具有先进的安全功能,并且方便集成到各个应用当中。
板上的nRF5340是支持低功耗蓝牙、蓝牙Mesh、NFC、Thread和Zigbee的双核蓝牙5.3 SoC,并且蓝牙测向可实现所有到达角(AoA)和出发角(AoD)的测量功能。此外,它支持低功耗蓝牙音频,2Mbps高吞吐量、广播扩展和长距离。像蓝牙Mesh、Thread和Zigbee这样的Mesh协议可以与低功耗蓝牙同时运行,从而使智能手机能够配网、入网、配置和控制Mesh节点。还支持NFC、ANT、802.15.4和2.4 GHz专有协议。
四、关于硬件:
控制器:nRF7002是一款无线IC,其控制器部分由nRF5340系列芯片提供。nRF5340芯片具有高性能、低功耗、低成本的特点,适用于各种物联网应用。
外设:nRF7002包括多个外设,如系统定时器、16通道通用GPIO、两路DAC、两路ADC、UART、SPI、I2C、SWCNT、RTC等。这些外设使得nRF7002可以轻松地与各种外设进行交互,扩展其功能。
应用方向:
智能家居、工业自动化、医疗设备和智能交通都通过无线连接实现各种智能设备之间的连接,从而提高了生活质量、生产效率、医疗服务水平和交通管理效率。应用场景包括家庭环境、工厂环境、医院环境和城市环境。
总之,nRF7002是一款功能强大的协同IC,适用于各种物联网应用场景,能够实现各种设备的无线连接,具有广泛的应用前景。
五、功能展示
1.开启手机的NFC功能,扫描nRF7002-DK外置NFC卡片。
2.手机自动打开网页,并跳转到B站up主信息展示页面。
六、主要代码
通过nrf7002板子NFC卡片模拟的功能,通过编码 Android 包名和通用链接为 NDEF 消息,并将其设置为 NFC 的负载数据,实现了在不同的 NFC 状态下启动不同的应用程序。
定义一个静态 数组,用于存储 Android APP包名
//app哔哩哔哩
static const uint8_t android_pkg_bilbil[] = {'t', 'v', '.', 'd', 'a', 'n', 'm', 'a', 'k', 'u', '.', 'b', 'i', 'l', 'i' };
//app饿了么
static const uint8_t android_pkg_eleme[] = {'m','e','.','e','l','e' };
定义一个静态变量flag_state,用于记录NFC状态(开或关)。
static uint8_t flag_state = 1;
nfc_callback,用于处理 NFC 事件的回调函数,根据事件类型(event)执行相应的操作.
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:
//将flag_state变量取反
flag_state = 1 - flag_state;
//点亮一个LED灯
dk_set_led_on(NFC_FIELD_LED);
//延迟200毫秒,防止卡死
k_sleep(K_MSEC(200));
break;
case NFC_T2T_EVENT_FIELD_OFF:
//熄灭LED灯
dk_set_led_off(NFC_FIELD_LED);
break;
default:
break;
}
}
将callback函数传递给nfc_t2t_setup函数,在NFC被读取和关闭时将调用nfc_callback。
nfc_t2t_setup(nfc_callback, NULL);
nfc_launchapp_msg_encode,用于编码一个NDEF消息。该函数需要传入六个参数:安卓应用程序包名、包名长度、通用链接、链接长度、NDEF消息缓冲区和消息长度指针。如果该函数返回错误代码,那么打印一条错误信息,并跳转到标签fail
nfc_launchapp_msg_encode(android_pkg_bilbil,
sizeof(android_pkg_bilbil),
universal_link,
sizeof(universal_link),
ndef_msg_buf,
&len);
nfc_t2t_payload_set,用于设置新的消息负载。
//这里将 nfc_launchapp_msg_encode的ndef_msg_buf负载到控制器
nfc_t2t_payload_set(ndef_msg_buf, len);
main函数添加死循环跟分支判断。要想顺利切换NFC功能,必须先停止NFC,否则后续的编码和加载就出故障了。而且呢,我给分支判断后加了个变化检测,让程序只会在flag_case出现变动后才刷新功能。简单方便。
while (1)
{
//判断flag_state状态
if(flag_state == 1)
{
//停止NFC T2T模拟
err = nfc_t2t_emulation_stop();
if (err) {
printk("Cannot stop emulation!\n");
goto fail;
}
//nfc_launchapp_msg_encode,用于编码一个新的NDEF消息
err = nfc_launchapp_msg_encode(android_pkg_bilbil,
sizeof(android_pkg_bilbil),
universal_link,
sizeof(universal_link),
ndef_msg_buf,
&len);
if (err) {
printk("Cannot encode message!\n");
goto fail;
}
//用于设置新的有效负载
err = nfc_t2t_payload_set(ndef_msg_buf, len);
if (err) {
printk("Cannot set payload!\n");
goto fail;
}
//重新开始NFC T2T模拟
err = nfc_t2t_emulation_start();
if (err) {
printk("Cannot start emulation!\n");
goto fail;
}
//打印一条信息,表示NFC配置完成
printk("NFC configuration done\n");
//设置一个循环,只要flag_state变量的值还是1(nfc未变化,就不会跳出)
while(flag_state == 1)
{printk("A>>app\n");}
}else
{
//停止NFC T2T模拟
err = nfc_t2t_emulation_stop();
if (err) {
printk("Cannot stop emulation!\n");
goto fail;
}
//设置启动另一个app
err = nfc_launchapp_msg_encode(android_pkg_eleme,
sizeof(android_pkg_eleme),
universal_link,
sizeof(universal_link),
ndef_msg_buf,
&len);
if (err) {
printk("Cannot encode message!\n");
goto fail;
}
//设置新的有效负载
err = nfc_t2t_payload_set(ndef_msg_buf, len);
if (err) {
printk("Cannot set payload!\n");
goto fail;
}
//重新开始NFC T2T模拟
err = nfc_t2t_emulation_start();
if (err) {
printk("Cannot start emulation!\n");
goto fail;
}
printk("NFC configuration done\n");
while(flag_state == 0)
{printk("b>>app\n");}}
//每隔2000毫秒延迟一次,不然可能因为变化过快会卡死
k_sleep(K_MSEC(2000));
}
最后上电,nfc手机读取卡片即可
代码解析:m_url填入自己的B站主页URL,以便NFC扫描展示up主页信息。在 nfc_ndef_uri_msg_encode会将URI 消息编码为 NFC NDEF 格式,然后调用ndef_file_update ,更新flash文件。这样手机NFC扫描NFC卡片就会自动打开网页,并跳转到B站up主信息展示页面。
七.遇到的问题及总结:
(1)Flash写入错误,报错信息如下:
报错重点:
(2)在如何跳转url中遇到了困难,因为总是自动添加头部,排查发现是NFC_URI_HTTPS_WWW的问题修改掉就好了。
(3)运行程序时页面无法显示或显示为乱码,经检测发现是网站服务器判断问题。将主页替换自动判断设备即可。
八、对活动的心得体会:
十分感谢硬禾学堂和Digi-Key,通过参与Funpack2-6这个项目,不仅让我对nRF7002-DK有了更深入的了解。通过使用它的NFC进行展示信息的功能,而且还锻炼了我的编程能力和解决困难的毅力,并对嵌入式开发有了新的认识。这次经历让我受益匪浅。
未来,我希望能再次参加类似的活动,以便了解和学习更多的知识,掌握更多的技能。我希望能够开拓电子芯片在生活中的应用视野,改变我的思维模式,并在专业领域中找到自己的发展方向。