0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

用搭积木的方式自制一个NFC读卡器

瑞科慧联(RAK) 2022-07-28 14:17 次阅读

地铁刷卡、上下班门禁打卡、高铁进站刷身份证、Apple Pay 购物……这些日常使用场景,都使用了 NFC 非接触式识别和互联技术,极大地方便了人们的生活。

不过,目前市面上常见的NFC无线读卡器都使用 WIFI或蓝牙进行数据传输,功耗较高、且传输距离有限。而如果采用 LoRaWAN®传输,则可以解决上述问题。事实上,基于 LoRaWAN®的 NFC 读卡器优点突出:

1、LoRaWAN®的传输距离远、接收灵敏度高、且功耗低

2、采用LoRaWAN®无线传输的读卡器安装部署方便

3、能使用电池供电、可持续使用半年以上。

本文将通过瑞科慧联的模块化开发套件 WisBlock 教大家快速搭建一个支持LoRaWAN®的无线读卡器,让这个读卡器读到电子标签数据时,可以自动将数据上传到 LoRaWAN®服务器上。WisBlock 其实是一个物联网解决方案设计生态系统,由可拼接的模块和易于使用的软件工具组成,可加快物联网产品生产周期、缩短上市时间。

搭建 LoRaWAN®NFC 读卡器概述

本次搭建使用的硬件是瑞科慧联(RAK)的 WisBlock 套件,MCU 选择的是RAK4631WisBlock Core 模块,该模块采用强大的 Nordic nRF52840 MCU,可以支持蓝牙 5.0(蓝牙低能耗),以及 Semtech最新的 LoRa®收发器 SX1262,支持 LoRa®和蓝牙两种通信模式。

该 NFC 还选择了 WisBlock 套件的 RAK13600 NFC 读卡器模组,它使用的是 PN532芯片,可以支持 ISO/ICE 14443A/B 卡类型的读写,而且还搭配了一个蜂鸣器模组 RAK18001,当 NFC 刷卡有效时,蜂鸣器会发出响声提醒。

对了,该 NFC 读卡器的搭建还会使用到瑞科慧联(RAK)的低代码开发平台 RUI3,它为 WisBlock 提供包含传感器驱动接口、无线发送接口等丰富的 API接口函数,这样我们只需要写少量的应用代码就可以完成此产品搭建了。

硬件电路搭建

硬件准备

首先我们需要准备 RAK4631 模块、RAK5005-O 底板、RAK13600 NFC 读卡器、RAK18001 蜂鸣器、两张 ISO 14443B 卡、一根 LoRa®天线、一根 NFC天线、一个 Unify 外壳、一根蓝牙天线(安装在外壳内)。

RAK4631 模块、RAK19007 底板、RAK13600 NFC 读卡器等硬件准备RAK4631 模块、RAK19007 底板、RAK13600 NFC 读卡器等硬件准备

硬件组装

把 RAK4631 模块扣在 CPU SLOT 的位置,RAK13600 扣在 IO SLOT 的位置,RAK18001 扣在 SLOT A(或者SLOT B),并且使用螺丝把模组固定。

连接NFC天线、LoRa®天线、蓝牙天线,并安装至外壳中。硬件组装完成之后就可以进行软件设置。

软件环境搭建

Arduino IDE中添加 RAK4631-R 开发板

打开 Arduino IDE,进入“文件 > 首选项”

打开 Arduino IDE打开 Arduino IDE

单击图中图标,修改“附加开发板管理器网址”选项,将 RAK4631-R WisBlock Core 添加中 Arduino 开发板管理器中。

在 Arduino IDE上修改“附加开发板管理器网址”在 Arduino IDE上修改“附加开发板管理器网址”

现在复制这个 URL https://raw.githubusercontent.com/RAKWireless/RAKwireless-Arduino-BSP-Index/main/package_rakwireless.com_rui_index.json 并粘贴至下图所示区域。如果已存在其他链接,将上述链接粘贴至新的一行。完成后,单击“好”。

在Arduino IDE上粘贴复制好的URL在Arduino IDE上粘贴复制好的URL

重启 Arduino IDE。 进入“工具 > 开发板:“RAK4631” > 开发板管理器”。

重启Arduino IDE并执行操作重启Arduino IDE并执行操作

在搜索框中输入“RAK”,窗口会自动出现可用的RAKwireless WisBlock Core Boards,选择“RAKwireless RUI nRF Boards”并安装。

选择并安装 RAKwireless RUI nRF Boards选择并安装 RAKwireless RUI nRF Boards

BSP 安装完成后,根据图中路径选择 RAKwireless WisBlock Core模块。

选择 RAKwireless WisBlock Core 模块选择 RAKwireless WisBlock Core 模块

安装使用到的库

现在安装 RAK13600-PN532 库和 Adafruit bus 库:

安装 RAK13600-PN532 库安装 RAK13600-PN532 库

安装 Adafruit bus 库安装 Adafruit bus 库

代码开发

LoRaWAN®部分的初始化,此函数可以初始化协议栈的所有参数,入网方式是OTAA,用户需要根据自己的频段,入网参数修改此宏定义,代码中使用的频段是 AS923。

/************************************* LoRaWAN band setting: RAK_REGION_EU433 RAK_REGION_CN470 RAK_REGION_RU864 RAK_REGION_IN865 RAK_REGION_EU868 RAK_REGION_US915 RAK_REGION_AU915 RAK_REGION_KR920 RAK_REGION_AS923 *************************************/ #define OTAA_BAND (RAK_REGION_AS923) #define OTAA_DEVEUI {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88} #define OTAA_APPEUI {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88} #define OTAA_APPKEY {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88} void lora_init()

蜂鸣器采用的是 PWM 控制,所以要记住在未使用蜂鸣器时,记得关闭输出。

pinMode(BUZZER_CONTROL,OUTPUT); noTone(BUZZER_CONTROL);

NFC 芯片初始化代码,采用 IIC 通信协议,初始化结束后,就可以使用 NFC的刷卡功能了。

nfc.begin(); uint32_t versiondata = nfc.getFirmwareVersion(); if (! versiondata) { Serial.print("Didn't find PN53x board"); while (1); // halt } // Got ok data, print it out! Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX); Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC); Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC); // Set the max number of retry attempts to read from a card // This prevents us from waiting forever for a card, which is // the default behaviour of the PN532. nfc.setPassiveActivationRetries(0xFF); //configure board to read RFID tags nfc.SAMConfig(); Serial.println("Waiting for an ISO14443A card");

每间隔 1 秒循环读取是否有 NFC 卡存在,如果读取 ID 成功,蜂鸣器会响 150 毫秒左右,然后发送卡 ID 到 LoRaWAN®服务器上。

void loop(void) { boolean success; uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID uint8_t uidLength; // Length of the UID (4 or 7 bytes dep ending on ISO14443A card type) // Wait for an ISO14443B type cards (Mifare, etc.). When one is found // 'uid' will be populated with the UID, and uidLength will indicate // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight) success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength); if (success) { tone(BUZZER_CONTROL,4000); delay(150); noTone(BUZZER_CONTROL); Serial.println("Found a card!"); Serial.print("UID Length: "); Serial.print(uidLength, DEC); Serial.println(" byte s"); Serial.print("UID Value: "); for (uint8_t i = 0; i < uidLength; i++) { Serial.print(" 0x"); Serial.print(uid[i], HEX); } Serial.println(""); digitalWrite(ledPin1, HIGH); // LED turn on when input pin value is HIGH delay(150); digitalWrite(ledPin1, LOW); // /** Send the data package */ if (api.lorawan.send(uidLength, (uint8_t *) & uid, 2, true, 1)) { Serial.println("Sending is requested"); } else { Serial.println("Sending failed"); } // Wait 1 second before continuing delay(1000); } else { // PN532 probably timed out waiting for a card Serial.println("Timed out waiting for a card"); } }

数据日志

本地串口日志的信息如下所示:

RAK7268内置LoRaWAN®服务器日志:

备注:全部源代码如下所示

/** @file iso14443a_uid.ino @author rakwireless.com @brief This example will attempt to connect to an ISO14443A card and read card UID @version 0.1 @date 2021-10-14 @copyright Copyright (c) 2021 **/ /**************************************************************************/ #include #include #include // Click here to get the library: http://librarymanager/All#RAK13600-PN532 /************************************* LoRaWAN band setting: RAK_REGION_EU433 RAK_REGION_CN470 RAK_REGION_RU864 RAK_REGION_IN865 RAK_REGION_EU868 RAK_REGION_US915 RAK_REGION_AU915 RAK_REGION_KR920 RAK_REGION_AS923 *************************************/ #define OTAA_BAND (RAK_REGION_AS923) #define OTAA_DEVEUI {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88} #define OTAA_APPEUI {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88} #define OTAA_APPKEY {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88} // If using the breakout or shield with I2C, define just the pins connected #define PN532_IRQ (WB_IO6) #define PN532_RESET (WB_IO5) // Not connected by default on the NFC Shield #define BUZZER_CONTROL WB_IO1 uint8_t ledPin1 = LED_GREEN; uint8_t ledPin2 = LED_BLUE; // Or use this line for a breakout or shield with an I2C connection: NFC_PN532 nfc(PN532_IRQ, PN532_RESET); void lora_init(); void setup(void) { Serial.begin(115200); pinMode(WB_IO2, OUTPUT); digitalWrite(WB_IO2, HIGH); pinMode(BUZZER_CONTROL,OUTPUT); noTone(BUZZER_CONTROL); // initialize the LED pin as an output pinMode(ledPin1, OUTPUT); pinMode(ledPin2, OUTPUT); lora_init(); delay(300); while (!Serial) delay(10); Serial.println("Hello!"); nfc.begin(); uint32_t versiondata = nfc.getFirmwareVersion(); if (! versiondata) { Serial.print("Didn't find PN53x board"); while (1); // halt } // Got ok data, print it out! Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX); Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC); Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC); // Set the max number of retry attempts to read from a card // This prevents us from waiting forever for a card, which is // the default behaviour of the PN532. nfc.setPassiveActivationRetries(0xFF); //configure board to read RFID tags nfc.SAMConfig(); Serial.println("Waiting for an ISO14443A card"); } void loop(void) { boolean success; uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type) // Wait for an ISO14443B type cards (Mifare, etc.). When one is found // 'uid' will be populated with the UID, and uidLength will indicate // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight) success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength); if (success) { tone(BUZZER_CONTROL,4000); delay(150); noTone(BUZZER_CONTROL); Serial.println("Found a card!"); Serial.print("UID Length: "); Serial.print(uidLength, DEC); Serial.println(" bytes"); Serial.print("UID Value: "); for (uint8_t i = 0; i < uidLength; i++) { Serial.print(" 0x"); Serial.print(uid[i], HEX); } Serial.println(""); digitalWrite(ledPin1, HIGH); // LED turn on when input pin value is HIGH delay(150); digitalWrite(ledPin1, LOW); // /** Send the data package */ if (api.lorawan.send(uidLength, (uint8_t *) & uid, 2, true, 1)) { Serial.println("Sending is requested"); } else { Serial.println("Sending failed"); } // Wait 1 second before continuing delay(1000); } else { // PN532 probably timed out waiting for a card Serial.println("Timed out waiting for a card"); } } void lora_init() { // OTAA Device EUI MSB first uint8_t node_device_eui[8] = OTAA_DEVEUI; // OTAA Application EUI MSB first uint8_t node_app_eui[8] = OTAA_APPEUI; // OTAA Application Key MSB first uint8_t node_app_key[16] = OTAA_APPKEY; if (!api.lorawan.appeui.set(node_app_eui, 8)) { Serial.printf("LoRaWan OTAA - set application EUI is incorrect! \r\n"); return; } if (!api.lorawan.appkey.set(node_app_key, 16)) { Serial.printf("LoRaWan OTAA - set application key is incorrect! \r\n"); return; } if (!api.lorawan.deui.set(node_device_eui, 8)) { Serial.printf("LoRaWan OTAA - set device EUI is incorrect! \r\n"); return; } if (!api.lorawan.band.set(OTAA_BAND)) { Serial.printf("LoRaWan OTAA - set band is incorrect! \r\n"); return; } if (!api.lorawan.deviceClass.set(RAK_LORA_CLASS_A)) { Serial.printf("LoRaWan OTAA - set device class is incorrect! \r\n"); return; } if (!api.lorawan.njm.set(RAK_LORA_OTAA)) // Set the network join mode to OTAA { Serial. printf("LoRaWan OTAA - set network join mode is incorrect! \r\n"); return; } if (!api.lorawan.join()) // Join to Gateway { Serial.printf("LoRaWan OTAA - join fail! \r\n"); return; } /** Wait for Join success */ while (api.lorawan.njs.get() == 0) { Serial.print("Wait for LoRaWAN join..."); api.lorawan.join(); delay(10000); } if (!api.lorawan.adr.set(true)) { Serial.printf ("LoRaWan OTAA - set adaptive data rate is incorrect! \r\n"); return; } if (!api.lorawan.rety.set(1)) { Serial.printf("LoRaWan OTAA - set retry times is incorrect! \r\n"); return; } if (!api.lorawan.cfm.set(1)) { Serial.printf("LoRaWan OTAA - set confirm mode is incorrect! \r\n"); return; } /** Check LoRaWan Status*/ Serial.printf("Duty cycle is %s\r\n", api.lorawan.dcs.get()? "ON" : "OFF"); // Check Duty Cycle status Serial.printf("Packet is %s\r\n", api.lorawan.cfm.get()? "CONFIRMED" : "UNCONFIRMED"); // Check Confirm status uint8_t assigned_dev_addr[4] = { 0 }; api.lorawan.daddr.get(assigned_dev_addr, 4); Serial.printf("Device Address is %02X%02X%02X%02X\r\n", assigned_dev_addr[0], assigned_dev_addr[1], assigned_dev_addr[2], assigned_dev_addr[3]); // Check Device Address Serial.println(""); }

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • nfc
    nfc
    +关注

    关注

    55

    文章

    1542

    浏览量

    178759
  • RAK
    RAK
    +关注

    关注

    0

    文章

    48

    浏览量

    2007
收藏 人收藏

    评论

    相关推荐

    请问X-NUCLEO-NFC08A1 NFC读卡器可以CUBE-MX-NFC6或CUBE-MX-NFC7的扩展包吗?

    未找到X-NUCLEO-NFC08A1 NFC读卡器对应的CUBE-MX-NFC8拓展包,可以CUBE-MX-
    发表于 03-18 08:05

    ST95HF NFC读卡器实际上板测试遇到的两疑问求解答

    你好。我的ST95HF NFC读卡器。电路图我参考的官网推荐的结构,如下图。天线和匹配参数的理论值都已经计算好了。现在我要实际上板测试,有2问题需要请教: 1、我现在是将网络分析仪
    发表于 03-11 07:37

    NFC读卡器天线设计与测量

    NFC读卡天线设计时与线圈圈数有关,一般在2-6匝,如果面积较大可以为1匝.
    的头像 发表于 09-14 16:08 5038次阅读
    <b class='flag-5'>NFC</b><b class='flag-5'>读卡器</b>天线设计与测量

    ST25R NFC读卡器开发流程与设计资源简介

    第 1 步. 定义 NFC 设备参数 • 目标产品 :POS 机(95HF 系列不适 EMVCo 认证应用),通用 NFC 读卡器等 • 合理的近场通信距离需求 (通常<10cm
    发表于 09-13 06:24

    ST25R3916B/17B NFC读卡器介绍

    ST25R3916B/17B NFC/RFID HF读卡器具有独特的功能,增强了稳健性和性能,可在不影响设计自由度的情况下运行于嘈杂的环境。可顺利通过EMV®非接触式和NFC Forum的认证。从
    发表于 09-08 06:46

    ST25R3920B汽车NFC读卡器:用于CCC数字密钥和中控台应用

    和卡模拟模式下的手机,使Qi充电器的NFC卡保护更上层楼。ST25R3920B的稳定性可轻松通过汽车OEM最高级别的抗噪测试。这款NFC读卡器搭载意法半导体
    发表于 09-07 08:26

    适用于支付、消费和工业应用的NFC读卡器

    ST25R3916B和ST25R3917B 是 高性能NFC通用设备,它支持NFC发起设备、NFC卡片、NFC读卡器
    发表于 09-07 06:48

    用于CCC数字钥匙和汽车中控台的汽车级NFC读卡器

    ST25R3920B 是汽车级高性能 NFC通用 设备,它支持NFC发起设备、NFC目标、NFC读卡器
    发表于 09-07 06:19

    如何使用NUC200的SPI 0启动读卡器PN512

    应用程序:示例代码是 NUC200 通过 I2C 接口控制卡读卡器 PN512 。 BSP 版本: NUC200系列 BSP CMSIS v3.00.004.004 硬件
    发表于 09-01 06:16

    使用NUC200的SPI 0启动读卡器PN512

    应用程序:示例代码是 NUC200 通过 I2C 接口控制卡读卡器 PN512 。 BSP 版本: NUC200系列 BSP CMSIS v3.00.004.004 硬件
    发表于 08-23 06:53

    蓝牙无线读卡器方案

    蓝牙无线读卡器是一种利用无线通信技术,可以读取各类卡信息的设备。 与传统的有线读卡器相比,蓝牙无线读卡器无需连接电脑或其他设备,可以通过蓝牙、WiFi、NFC等无线通讯技术直接传输数据
    发表于 08-19 15:36 0次下载

    求助,X-NUCLEO-NFC08A1 NFC读卡器可以CUBE-MX-NFC6或CUBE-MX-NFC7的扩展包吗?

    未找到X-NUCLEO-NFC08A1 NFC读卡器对应的CUBE-MX-NFC8拓展包,可以CUBE-MX-
    发表于 08-07 09:20

    ST25R3920B汽车NFC读卡器介绍

    电子发烧友网站提供《ST25R3920B汽车NFC读卡器介绍.pdf》资料免费下载
    发表于 08-01 14:41 2次下载
    ST25R3920B汽车<b class='flag-5'>NFC</b><b class='flag-5'>读卡器</b>介绍

    ST25R3916B/17B NFC读卡器介绍

    电子发烧友网站提供《ST25R3916B/17B NFC读卡器介绍.pdf》资料免费下载
    发表于 08-01 14:40 0次下载
    ST25R3916B/17B <b class='flag-5'>NFC</b><b class='flag-5'>读卡器</b>介绍

    蓝牙无线读卡器方案

    蓝牙无线读卡器是一种利用无线通信技术,可以读取各类卡信息的设备。 与传统的有线读卡器相比,蓝牙无线读卡器无需连接电脑或其他设备,可以通过蓝牙、WiFi、NFC等无线通讯技术直接传输数据
    的头像 发表于 07-26 15:17 1104次阅读
    蓝牙无线<b class='flag-5'>读卡器</b>方案