一、项目介绍
大家好我是长草的小破号,在参加硬禾学堂和得捷电子联合举办的funpack第二季第六期活动;本次活动设置三个题目,题目1是蓝牙键鼠,题目2是wifi远程控制。题目3是自定义NFC卡片。本次我选择的题目是题目三。
二、硬件介绍
本次活动使用的开发板是nordic的NRF7002-DK开发板。
这款开发板上有三颗mcu,两颗NRF5340,其中一颗用做jlink调试下载,另一颗为蓝牙主控芯片。一颗nrf7002,支持WIFI 6开发。本项目围绕nrf5340芯片展开,以下介绍以5340为主。
nRF5340是一颗双核cortex-M33内核无线SOC. 具有1M闪存和512K ram。支持蓝牙5.2 ,蓝牙低功耗音频,定位寻向等。
开发板板载2.4G蓝牙天线。外带一条NFC天线。这里的NFC天线使用FPC制作,是可拆卸的。调试的时候插上,调试完可以收起来,很是方便。nordic蓝牙芯片因其优秀的低功耗性能,多用于可穿戴设备,无线键鼠,智能家居,医疗器械等领域。
三、实现过程
开发环境搭建:
这里使用官方推荐的NRF connect for desktop.
这个工具包里包含很多小工具,其中安装工具链会花些时间和精力,SDK版本我使用的是2.4.2,具体的安装教程,网上有很多前辈做过,这里不再赘述。在调试过程中可能遇到芯片保护无法下载代码的问题。需要使用命令解除保护,可能是我环境变量的问题,west命令无法执行。最后使用programmer进行全擦除才搞定。
VScode的编译环境做的很全面,各种配置都很方便,debug和调试起来很方便。整体感觉nodic官方推荐的工具用起来还是很顺手的。
NFC相关原理:
环境搭建好就可以开始着手项目实现了。要想自定义一个NFC卡片,就需要了解手机在扫描NFC标签时发生了什么。当手机靠近NFC标签时,手机的NFC芯片会驱动13.6MHz天线,将信号传递到NFC标签天线,从而与NFC标签建立通信。NFC标签中包含了一些事先存储的信息,比如URL链接、应用程序启动命令等。手机的NFC芯片会读取这些信息,并根据标签中的指令执行相应的操作。
功能需求:
本次项目想要实现一个NFC标签既能打开APP又能打开视频链接的功能。
任务分解:
要想实现上述功能,大概需要两步:
1.需要先将相关信息写入NFC标签中,本项目共记录两条数据,一条为哔哩哔哩视频链接,另一条是手机浏览器via app 启动指令。指令获取流程如下:打开NFC_TOOLS_PRO,切换到”写“任务栏,点击”添加记录“找到”应用程序“,最后点击android图标,上下滑动选择自己手机的应用程序。选好后APP相关信息会显示再左边的文本输入框里。
2.NFC信息切换可以定义一个循环变量,记录扫描次数,扫描动作计满2次切换一次NFC标签内容。
四、软件相关
软件流程如下,程序开始进入初始化,
代码需要使用到uri_msg.h头文件,添加头文件时注意需要在两个地方同时添加才有效,一个是在主程序开始添加:
另一处是要在prj.conf 文件中添加,如下图:
主要代码如下:
APP名称
static const uint8_t android_via_app[] = { //存储via浏览器名称
'm', 'a', 'r', 'k', '.', 'v', 'i', 'a' };
B站视频链接:
static const uint8_t bilibili_link[] = { //硬禾学堂B站视频
'h', 't', 't', 'p', 's', ':', '/', '/', 'w', 'w', 'w', '.', 'b', 'i', 'l', 'i', 'b', 'i', 'l', 'i', '.', 'c', 'o', 'm', '/', 'v', 'i', 'd', 'e', 'o', '/', 'B', 'V', '1', 'D', 'k', '4', 'y', '1', 'T', '7', 'N', 't'
};
NFC事件回调函数:回调函数操作了两个变量,一个是 SCAN_state,用来记录扫描状态,当手机靠近时置1,表示允许程序切换NFC内数据。第二个变量是NFC_count,这个变量用来累计扫描次数,判断到达设定次数后执行NFC数据更新代码。
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); 指示灯注释掉 常亮太刺眼了
SCAN_state=1; //扫描状态改变
k_msleep(100); //延时避免重复触发?
break;
case NFC_T2T_EVENT_FIELD_OFF:
// dk_set_led_off(NFC_FIELD_LED); 指示灯注释掉 常亮太刺眼了
NFC_count++; //只有当手机抬起时 NFC扫描次数才进入累加;
break;
default:
break;
}
}
主程序部分首先将写入via APP 启动指令写入NFC标签。然后在while 1 里循环判断两个变量状态,当满足条件时将NFC停下来,写入哔哩哔哩 视频链接 ,再重启NFC。 此处注意在重新编辑NFC信息后要清掉标志位,这样就不会出现一遍一遍执行 NFC写入命令。
int main(void)
{
int err;
size_t len = sizeof(ndef_msg_buf);
printk("Starting NFC Launch app example\n");
/* Configure LED-pins as outputs */
err = dk_leds_init(); //led初始化
/* Set up NFC */
err = nfc_t2t_setup(nfc_callback, NULL);
/* Encode launch app data */
err = nfc_launchapp_msg_encode(android_via_app, //写入APP信息
sizeof(android_via_app),
bilibili_link,
sizeof(bilibili_link),
ndef_msg_buf,
&len);
/* Set created message as the NFC payload */
err = nfc_t2t_payload_set(ndef_msg_buf, len); //装载数据
/* Start sensing NFC field */
err = nfc_t2t_emulation_start(); //启动NFC
while(1) //定义while 1 循环,根据扫描状态 和NFC扫描次数判断是否重新编辑NFC内容
{
/*指示灯闪烁表示程序正常运行*/
dk_set_led_on(NFC_FIELD_LED); //让指示灯熄灭
dk_set_led_on(NFC_WRITE_LED);
k_msleep(2000);
dk_set_led_off(NFC_FIELD_LED); //让指示灯点亮
k_msleep(10);
if((NFC_count>1)&&(NFC_count<3)&&(SCAN_state==1))
{
SCAN_state=0; //在开始重新编辑nfc内容时先把标志位清除,避免重复编辑NFC内容
err=nfc_t2t_emulation_stop(); //停止nfc
ndef_msg_buf_clear(ndef_msg_buf); //清除缓存数据
err=nfc_ndef_uri_msg_encode( //将bili bili 链接写入缓存
0x00,
bilibili_link,
sizeof(bilibili_link),
ndef_msg_buf,
&len);
k_msleep(10); //插入一段延时
err=nfc_t2t_payload_set(ndef_msg_buf, len); //装载数据
k_msleep(10);
err=nfc_t2t_emulation_start(); //开启NFC功能 自此bilibili 链接写入成功
}
if(NFC_count>4)
{
goto fail; //程序进入重启 回到开始重新写入via app 信息
return err;
}
k_msleep(100);
}
return 0; //放到while 1 后面
fail:
#if CONFIG_REBOOT
sys_reboot(SYS_REBOOT_COLD);
#endif /* CONFIG_REBOOT */
return err;
}
超出扫描次数软件重启,重新写入APP数据
if(NFC_count>4)
{
goto fail; //进入重启
return err;
}
最后有一个函数很关键,缓存数组清除函数,在重新编辑NFC信息前需打扫战场,使一切变量恢复如初才不会出错。
void ndef_msg_buf_clear(const uint8_t *payload) //这是一段清除缓存内容的代码
{
uint8_t count;
for(count=0;count<255;count++)
{
ndef_msg_buf[count]=0x00;
}
}
四、功能展示
使用nrf5340模拟了一个NFC tag,用手机扫一扫可以打开手机上的浏览器,然后在第三次扫描时,NFC信息会自动切换为硬禾学堂对本期活动的介绍视频。
五、心得体会
本次活动开发环境的搭建不算顺利,来来回回折腾了好几遍;好在大家都有问必答,遇到的问题都能完美解决;
参加这次活动的初衷是为了学习蓝牙开发。现在NFC开发走顺了,接下来搞蓝牙项目应该会顺利些;
最后感谢主办方推出的funpack系列活动,期待下一期。