NFC近场通讯模块的简易教程和评测
大家好,我是Bill,事隔好久的第二次发文 。这次评测的是NFC近场通讯模块(DFR0231)https://www.dfrobot.com.cn/goods-762.html 。其实上上个月就已经把NFC的库很早之前就写好了,只不过忘记写个教程了 。。。趁着自己还没忘记,写个总结吧,顺便把库文件也共享下。程序暂时实现了Mifare 1卡使用初始默认密码进行读写操作,像修改密码、控制区块这种容易写废卡的操作暂时没包括。不过里面预留有接口,有兴趣的可以啊根据PN532和Mifare 1卡的用户手册,自行填写。
第一部分:NFC的介绍
NFC是英文Near Field Communication的缩写,又称近距离无线通信,是一种短距离的高频无线通信技术,允许电子设备之间进行非接触式点对点数据传输,在十厘米(3.9英寸)内交换数据。目前在很多场合都有所应用,比如说门禁系统、银行卡、交通卡、身份证以及身份证 。现在很多手机也支持NFC卡标签的读写(http://en.wikipedia.org/wiki/List_of_NFC-enabled_mobile_devices )。通过读写NFC便签,能够实现快速启动程序、信息交互等功能。
接下来介绍下DFRobot的NFC近场通讯模块。DFRobot采用的是NXP的PN532模块支持6种不同的工作模式:读写器模式,支持ISO/IEC 14443A / MIFARE机制;读写器模式,支持 FeliCa机制;读写器模式,支持ISO/IEC 14443B机制;卡操作模式,支持ISO 14443A / MIFARE机制;卡操作模式,FeliCa机制;ISO/IEC18092,ECM340点对点。
第二部分 连接方式
这里使用软串口进行连接,不过因为软串口在115200频率下工作不稳定,程序会花费半秒左右尝试自动降频到57600。当然使用NFC模块的TX口连设备的RX口,RX口连设备的TX口,直接使用串口也可,不过注意烧录程序需拔下NFC的电源连接线
第三部分 代码介绍
这里是写好的库,主要根据adafruit的NFC库进行了适当的修改。保留了大部分功能并增加了简易读写NFC便签数据的功能。下面介绍下主要新增的几个函数。
int write(unsigned int byteAddr, uint8_t byteData);
实现了对指定位置字符的写操作,其中第一个参数为字符地址,第二个为要写入的数据。
返回值:1 操作成功
0 未定义
-1 如果位置越
-2 如果无法找到合适M1卡或者NFC未连接
-3 如果验证失败
-4 如果读取数据所在区块失败
-5 如果写入数据失败
int writeBytes(uint8_t* buff, unsigned int byteAddrStart, unsigned int length);
实现了对指定位置字符串的写操作,其中第一个参数为写入的字符串的头地址,第二个为NFC的起始写入位置,第三个为写入字符串的长度
返回值:1 操作成功
0 未定义
-1 如果位置越
-2 如果无法找到合适M1卡或者NFC未连接
-3 如果验证失败
-4 如果读取数据所在区块失败
-5 如果写入数据失败
int read(unsigned int byteAddr);
实现了对指定位置数据的读操作,其中第一个参数为数据地址。
返回值:>=0 操作成功
-1 如果位置越界
-2 如果无法找到合适M1卡或者NFC未连接
-3 如果验证失败
-4 如果读取数据所在区块失败
int readBytes(uint8_t* buff, unsigned int byteAddrStart, unsigned int length);
实现了对指定位置字符串的读操作,其中第一个参数为保存读取字符串的头地址,第二个为NFC的起始读取位置,第三个为要读取字符串的长度
返回值:1 操作成功
-1 如果位置越界
-2 如果无法找到合适M1卡或者NFC未连接
-3 如果验证失败
-4 如果读取数据所在区块失败
以下是一段总的测试代码,给的库里还有4个write、read、writeBytes和readBytes里分别的样例代码。代码水平有限,如果有什么问题,欢迎提出。
/***************************************************
NFC Module for Arduino (SKU:DFR0231)
<https://wiki.dfrobot.com/NFC_Module_for_Arduino__SKU_DFR0231_>
***************************************************
This example reads characters in the Mifare Classic of the
data blocks (address 0 to address 751) using default keyB {0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF} and prints it to the computer.
Created 2015-4-28
By Bill Hong
GNU Lesser General Public License.
See <http://www.gnu.org/licenses/> for details.
All above must be included in any redistribution
****************************************************/
/***********Notice and Trouble shooting***************
1.The address is from 0 to 751, 752 Bytes in the data blocks.
2.This code is tested on Arduino Uno.
****************************************************/
/***************************************************
NFC Module for Arduino (SKU:DFR0231)
<https://wiki.dfrobot.com/NFC_Module_for_Arduino__SKU_DFR0231_>
***************************************************
This example reads characters in the Mifare Classic of the
data blocks (address 0 to address 751) using default keyB {0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF} and prints it to the computer.
Created 2015-4-28
By Bill Hong
GNU Lesser General Public License.
See <http://www.gnu.org/licenses/> for details.
All above must be included in any redistribution
****************************************************/
/***********Notice and Trouble shooting***************
1.The address is from 0 to 751, 752 Bytes in the data blocks.
2.This code is tested on Arduino Uno.
****************************************************/
#include "Arduino.h"
#include "DFRNFC.h"
#include "SoftwareSerial.h"
DFRNFC nfc;
SoftwareSerial mySerial(6, 7); // RX, TX
void setup(void)
{
//initialize nfc module
Serial.begin(115200);
mySerial.begin(115200); //PN532 default SerialBaudRate is 115200
nfc.begin(mySerial);
Serial.println("Looking for PN532...");
}
void loop()
{
uint8_t data[752];
int success = 0;
int startAddress = 0;
int dataLength = 752; //maximum length is 752 byte
for(int i=0;i<dataLength;i++)
{
data[i] = i;
}
Serial.println("writing");
for(int i=0;i<dataLength-1;i+=16)
{
//writing data
success = nfc.writeBytes(data+i,i,16);
if(success!=1)
{
Serial.println();
Serial.print("writing error ");
}
else
{
Serial.print("#");
}
}
Serial.println();
Serial.println("writing end");
Serial.println("reading");
// read byte all bytes of the Mifare Classic Card to data;
success = nfc.readBytes(data,startAddress,dataLength);
//returned information
switch(success)
{
case -1:
Serial.println("address is without range");
break;
case -2:
Serial.println("failed to find a Mifare classic card");
break;
case -3:
Serial.println("faild to authenticate, the device will try to find a new card");
break;
case -4:
Serial.println("faild to read");
break;
default:
Serial.println();
Serial.println("start printing the data");
nfc.setDebugSerial(Serial);
for(int i=0;i<752;i++)
{
if (data[i] <= 0xF)
{
Serial.print("0");
}
Serial.print(data[i],HEX); //print data,16 bytes per line
Serial.print(" ");
if((i+1)%16 == 0)
{
Serial.println();
}
}
break;
}
while(1);
}
复制代码