带RFID的ESP32访问控制
步骤1:操作
RFID系统基本上由带有解码器的收发器,天线和应答器组成。以及它如何运作?这些卡中有一个卷轴。当您从阅读器接近它们时,它们会通过连接到阅读器的天线发出无线电信号。带电标签(即卡)对存储在其内存中的信息进行调制,然后将该数据发送到读取器。然后,该卡进入读取区域并从读取器接收电源以执行操作。 RFID阅读器接收标签发送的信息,将数据解码并将其发送到服务器应用程序。
步骤2:内存
《如前所述,这种芯片内部有1k的内存。并且,EEPROM存储器的组织方式如下:4个块的16个扇区。每个块包含16个字节。请记住,在源代码中,您仅引用块号。
步骤3:电路
在此图中,带有RFID芯片的钥匙扣,除了组装件,我们还有传统的卡。以及该电路如何工作?嗯,在互联网上,您会发现RFID-RC522模块非常适合Arduino使用,但问题是该Arduino(无论是Mega,Nano),无论型号如何,都无法通信,例如WiFi网络,以太网,彼此之间。所以我们在这里使用ESP32。它已经具有蓝牙,RF,即易于通信。那么我在这里指出,几乎所有与Arduino兼容的东西都可以在ESP32上使用。
返回电路,当在对卡或芯片进行分析时,绿色LED亮起时,这意味着标识已完成,访问被释放。红色LED点亮时,表明数据尚未通过验证。
步骤4:WiFi NodeMCU-32S ESP-WROOM-32
步骤5:RFID-RC522
在这里,我们获得了卡和钥匙圈以及RFID天线的图像。一个重要的细节是它的接口是SPI。
第6步:组装
在我们的组装中,我们的ESP32由USB,并以Arduino IDE的串行连接,有两个LED指示读取是否成功,还有RFID读取器RC522。我们有带芯片和卡的钥匙圈。
将钥匙圈放在播放器上会显示0表示读取数据,1表示记录数据。我们以一个示例为例,该示例显示读取芯片或卡后,如果绿色指示灯点亮,则读取器会识别出该数字。如果指示灯为红色,则表示发生了某种类型的错误,并且未执行身份验证。
在示例中,我仍然展示了如何将数据写入标签,下面将对此进行说明。
第7步:库
添加以下库“ MFRC522”。
只需访问“草图” 》》包括库》》管理库。..”
步骤8:源代码
我们的程序将按以下方式工作:启动后,程序将等待卡或标签被识别。之后,将出现一个菜单,供用户在阅读或记录内容之间进行选择。然后将执行该操作。
步骤9:设置
在这一部分中,我们处理库的包含并定义缓冲区和块数据大小。我们创建对象并初始化引脚,以及串行,SPI通信,LED和天线服务。我已经开始在串行监视器上包含消息了。
#include //library responsible for communicating with the module RFID-RC522
#include //library responsible for communicating of SPI bus
#define SS_PIN 21
#define RST_PIN 22
#define SIZE_BUFFER 18
#define MAX_SIZE_BLOCK 16
#define greenPin 12
#define redPin 32
//used in authentication
MFRC522::MIFARE_Key key;
//authentication return status code
MFRC522::StatusCode status;
// Defined pins to module RC522
MFRC522 mfrc522(SS_PIN, RST_PIN);
void setup()
{
Serial.begin(9600);
SPI.begin(); // Init SPI bus
pinMode(greenPin, OUTPUT);
pinMode(redPin, OUTPUT);
// Init MFRC522
mfrc522.PCD_Init();
Serial.println(“Approach your reader card.。.”);
Serial.println();
步骤10:循环
在循环中,我们等待卡方法并选择相同的方法。在菜单中,我们提供了读取或写入数据的选项。当设备应从活动状态变为停止状态时,我们对此部分进行了指示。我们必须使用这种方法来启用新的读数。
void loop()
{
// Aguarda a aproximacao do cartao
//waiting the card approach
if ( ! mfrc522.PICC_IsNewCardPresent())
{
return;
}
// Select a card
if ( ! mfrc522.PICC_ReadCardSerial())
{
return;
}
// Dump debug info about the card; PICC_HaltA() is automatically called
// mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
//call menu function and retrieve the desired option
int op = menu();
if(op == 0)
readingData();
else if(op == 1)
writingData();
else {
Serial.println(F(“Incorrect Option!”));
return;
}
//instructs the PICC when in the ACTIVE state to go to a “STOP” state
mfrc522.PICC_HaltA();
// “stop” the encryption of the PCD, it must be called after communication with authentication, otherwise new communications can not be initiated
mfrc522.PCD_StopCrypto1();
}
步骤11:阅读
在这一部分中,我们将阅读卡/标签的数据。我们必须准备所有键,处理缓冲区的大小,并对要操作的块进行身份验证。最后,我们设置读取数据的打印方式。
//reads data from card/tag
void readingData()
{
//prints the technical details of the card/tag
mfrc522.PICC_DumpDetailsToSerial(&(mfrc522.uid));
//prepare the key - all keys are set to FFFFFFFFFFFFh
for (byte i = 0; i 《 6; i++) key.keyByte[i] = 0xFF;
//buffer for read data
byte buffer[SIZE_BUFFER] = {0};
//the block to operate
byte block = 1;
byte size = SIZE_BUFFER;
//authenticates the block to operate
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid)); //line 834 of MFRC522.cpp file
if (status != MFRC522::STATUS_OK) {
Serial.print(F(“Authentication failed: ”));
Serial.println(mfrc522.GetStatusCodeName(status));
digitalWrite(redPin, HIGH);
delay(1000);
digitalWrite(redPin, LOW);
return;
}
//read data from block
status = mfrc522.MIFARE_Read(block, buffer, &size);
if (status != MFRC522::STATUS_OK) {
Serial.print(F(“Reading failed: ”));
Serial.println(mfrc522.GetStatusCodeName(status));
digitalWrite(redPin, HIGH);
delay(1000);
digitalWrite(redPin, LOW);
return;
}
else{
digitalWrite(greenPin, HIGH);
delay(1000);
digitalWrite(greenPin, LOW);
}
Serial.print(F(“ Data from block [”));
Serial.print(block);Serial.print(F(“]: ”));
//prints read data
for (uint8_t i = 0; i 《 MAX_SIZE_BLOCK; i++)
{
Serial.write(buffer[i]);
}
Serial.println(“ ”);
}
步骤12:记录
要将数据写入卡/标签,我们必须遵循一些步骤。从选择记录选项的那一刻起,我们有30秒的时间通过串行进行数据输入。用“#”字符输入要写入的数据并准备密钥。您将需要清除缓冲区并写入块1,因为在块0中,我们已经保存了卡号,该卡号已经在工厂中了。因此,我们不会触摸块0。
我们处理数据的大小,并插入一个用于身份验证的命令并启用安全通信。如果未认证的数据,我们还会将错误消息与读数的一部分相等,以进行显示。我们将数据记录在适当的块中。
//prints thecnical details from of the card/tag
mfrc522.PICC_DumpDetailsToSerial(&(mfrc522.uid));
// waits 30 seconds dor data entry via Serial
Serial.setTimeout(30000L) ;
Serial.println(F(“Enter the data to be written with the ‘#’ character at the end [maximum of 16 characters]:”));
//prepare the key - all keys are set to FFFFFFFFFFFFh
for (byte i = 0; i 《 6; i++) key.keyByte[i] = 0xFF;
//buffer para armazenamento dos dados que iremos gravar
//buffer for storing data to write
byte buffer[MAX_SIZE_BLOCK] = “”;
byte block; //the block to operate
byte dataSize; //size of data (bytes)
//recover on buffer the data from Serial
//all characters before chacactere ‘#’
dataSize = Serial.readBytesUntil(‘#’, (char*)buffer, MAX_SIZE_BLOCK);
//void positions that are left in the buffer will be filled with whitespace
for(byte i=dataSize; i 《 MAX_SIZE_BLOCK; i++)
{
buffer[i] = ‘ ’;
}
block = 1; //the block to operate
String str = (char*)buffer; //transforms the buffer data in String
Serial.println(str);
//authenticates the block to operate
//Authenticate is a command to hability a secure communication
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A,
block, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F(“PCD_Authenticate() failed: ”));
Serial.println(mfrc522.GetStatusCodeName(status));
digitalWrite(redPin, HIGH);
delay(1000);
digitalWrite(redPin, LOW);
return;
}
//else Serial.println(F(“PCD_Authenticate() success: ”));
//Writes in the block
status = mfrc522.MIFARE_Write(block, buffer, MAX_SIZE_BLOCK);
if (status != MFRC522::STATUS_OK) {
Serial.print(F(“MIFARE_Write() failed: ”));
Serial.println(mfrc522.GetStatusCodeName(status));
digitalWrite(redPin, HIGH);
delay(1000);
digitalWrite(redPin, LOW);
return;
}
else{
Serial.println(F(“MIFARE_Write() success: ”));
digitalWrite(greenPin, HIGH);
delay(1000);
digitalWrite(greenPin, LOW);
}
}
步骤13:菜单
在这里编写菜单。监视器显示所有选项,并等待发送数据。选择一个选项后,它将从读取的值中删除48,该值在Ascii表中为0。该表是旧的,不在PC上使用,但是在Arduino和微控制器上,您将不得不处理它。如果您不知道,请在互联网上搜索一下它是什么。
//menu to operation choice
int menu()
{
Serial.println(F(“ Choose an option:”));
Serial.println(F(“0 - Reading data”));
Serial.println(F(“1 - Writing data ”));
//waits while the user does not start data
while(!Serial.available()){};
//retrieves the chosen option
int op = (int)Serial.read();
//remove all characters after option (as per example)
while(Serial.available()) {
if(Serial.read() == ‘ ’) break;
Serial.read();
}
return (op-48);//subtract 48 from read value, 48 is the zero from ascii table
}