基于ESP8266-12F+MFRC522的可Web管理的门禁系统

准备工作

  1. 硬件准备(基于ESP8266-12F的开发板、MFRC522读卡器模块)
  2. ProtoThreads多线程库(ProtoThreads库ProtoThreads使用教程

MFRC522的使用

在程序中对于卡片的识别仅仅限于Uid的读取,并没有使用卡片的其他扇区

下面是Arduino的MFRC522的示例程序,这里我之所以把代码贴出来的原因是因为接线的问题。

博主用的是WeMos D1 的开发板,本段下述描述基于WeMos D1,在程序端口号上和板子标注不一致(其实是芯片的GPIO号)

下面是部分端口对照表(全部的会在之后更新此博客)

程序端口号0245615
板子端口号D8D9D4D3D2D10
* -----------------------------------------------------------------------------------------
 *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
 *             Reader/PCD   Uno/101       Mega      Nano v3    Leonardo/Micro   Pro Micro
 * Signal      Pin          Pin           Pin       Pin        Pin              Pin
 * -----------------------------------------------------------------------------------------
 * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
 * SPI SS      SDA(SS)      10            53        D10        10               10
 * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
 * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
 * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
 */

#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN         9          // Configurable, see typical pin layout above
#define SS_PIN          10         // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);  // Create MFRC522 instance

void setup() {
	Serial.begin(9600);		// Initialize serial communications with the PC
	while (!Serial);		// Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
	SPI.begin();			// Init SPI bus
	mfrc522.PCD_Init();		// Init MFRC522
	mfrc522.PCD_DumpVersionToSerial();	// Show details of PCD - MFRC522 Card Reader details
	Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}

void loop() {
	// Look for new cards
	if ( ! mfrc522.PICC_IsNewCardPresent()) {
		return;
	}

	// Select one of the cards
	if ( ! mfrc522.PICC_ReadCardSerial()) {
		return;
	}

	// Dump debug info about the card; PICC_HaltA() is automatically called
	mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}

关于MFRC522的接线:SPI相关(MOSI,MISO,SCK),是从芯片上引出标注的所以对号入座没问题,RST_PIN,SS_PIN,按照前述表格的对应方式选取合适的使用即可。

EEPROM的使用

门禁由于可以Web管理,即使用Web添加,删除,查询允许用户。自然需要在不改写程序的情况下,可以识别不同卡号。

便需要EEPROM的断电存储。

下面例子摘自门禁程序,每次重启都会自动从EEPROM中加载卡号。

#include <EEPROM.h>
char cardNum = 0;
char cards[6][4];
void ReadEEPROM()
{
    int addr = 0;
    cardNum = EEPROM.read(addr++);
    for(int i=0;i<cardNum;i++)
    {
        for(int j=0;j<4;j++)
        cards[i][j] = EEPROM.read(addr++);
    }
}
void setup() {
    EEPROM.begin(1024);
    ReadEEPROM(); 
}

HttpServer的搭建

与其说搭建不如说模拟(因为ESP8266并不能实现Web服务器的很多功能)

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
const char* ssid     = "***";
const char* password = "***";

ESP8266WebServer server(80);
void handleNotFound();
void handleInterFace();
void handleRoot();

void setup() {
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
        delay(500);
    server.on("/", handleRoot);
    server.on("/InterFace",handleInterFace);
    server.onNotFound(handleNotFound);
    //here the list of headers to be recorded
    const char * headerkeys[] = {"User-Agent","Cookie"} ;
    size_t headerkeyssize = sizeof(headerkeys)/sizeof(char*);
    //ask server to track these headers
    server.collectHeaders(headerkeys, headerkeyssize );
    server.begin();
}

void loop() {
    // put your main code here, to run repeatedly:
    server.handleClient();
}
void handleInterFace()
{
    Serial.println("Enter Interface");
    String content;
    char count = 0;
    content = "<?xml version='1.0' encoding='ISO-8859-1'?><cards>";
    if(server.hasArg("cmd"))
    {
        if(server.arg("cmd")=="getUidPer")
        {
          Serial.println("getUidPer");
            for(int i=0;i<cardNum;i++)
            {
                content += "<card>";
                for(int j=0;j<4;j++)
                {
                    content +="<";
                    content += (char)(j+65);
                    content +=">";
                    content +=(int)(cards[i][j]);
                    content +="</";
                    content += (char)(j+65);
                    content +=">";
                }
                content += "</card>";
            } 
        }
        if(server.arg("cmd")=="readUid")
        {
          Serial.println("readUid");
            //延时5s等待读取卡片
            while(!mfrc522.PICC_IsNewCardPresent()&&count < 5)
            {
                delay(500);
                count++;
            }
            if ( ! mfrc522.PICC_ReadCardSerial())
            {
                content += "<card>";
                for(int j = 0;j<4;j++)
                {
                    content +="<";
                    content += (char)(j+65);
                    content +=">";
                    content +=(int)(-1);
                    content +="</";
                    content += (char)(j+65);
                    content +=">";
                }
                content += "</card>";
            }
            else
            {
                Serial.println(mfrc522.uid.uidByte[0]);
                Serial.println(mfrc522.uid.uidByte[1]);
                Serial.println(mfrc522.uid.uidByte[2]);
                Serial.println(mfrc522.uid.uidByte[3]);
                content += "<card>";
                for(int j = 0;j<4;j++)
                {
                  content +="<";
                  content += (char)(j+65);
                  content +=">";
                  content +=(int)(mfrc522.uid.uidByte[j]);
                  content +="</";
                  content += (char)(j+65);
                  content +=">";
                }
                content += "</card>";
            }
        }
        {
            
            if(server.arg("cmd")=="deleteUid")
            {
              Serial.println("deleteuID");
                char key[4];
                char i=0,j=0;
                key[0] = server.arg("A").toInt();
                key[1] = server.arg("B").toInt();
                key[2] = server.arg("C").toInt();
                key[3] = server.arg("D").toInt();
                for(i=0;i<cardNum;i++)
                {
                    for(j=0;j<4;j++)
                    {
                        if(cards[i][j]!=key[j])
                            break;
                    }
                    if(j==4)
                        break;
                }
                if(j==4)
                {
                    EEPROM.write(0,cardNum-1);
                    for(int k=i;k<cardNum-1;k++)
                    {
                        EEPROM.write(k*4+1,EEPROM.read(4*k+5));
                        EEPROM.write(k*4+2,EEPROM.read(4*k+6));
                        EEPROM.write(k*4+3,EEPROM.read(4*k+7));
                        EEPROM.write(k*4+4,EEPROM.read(4*k+8));
                    }
                    EEPROM.commit();
                    ReadEEPROM();
                    content += "<card><A>1</A></card>";
                }
                else
                    content += "<card><A>2</A></card>";
            }
        }
        {
            
            if(server.arg("cmd")=="addUid")
            {
              Serial.println("addUid");
                char key[4];
                char i=0,j=0;
                key[0] = server.arg("A").toInt();
                key[1] = server.arg("B").toInt();
                key[2] = server.arg("C").toInt();
                key[3] = server.arg("D").toInt();
                for(i=0;i<cardNum;i++)
                {
                    for(j=0;j<4;j++)
                    {
                        if(cards[i][j]!=key[j])
                            break;
                    }
                    if(j==4)
                        break;
                }
                if(j==4)
                {
                    content += "<card><A>2</A></card>";
                }
                else
                {
                    EEPROM.write(0,cardNum+1);
                    for(int k=0;k<4;k++)
                        EEPROM.write(cardNum*4+k+1,key[k]);
                    EEPROM.commit();
                    ReadEEPROM();
                    content += "<card><A>1</A></card>";
                    
                }
            }
        }
        content+="</cards>";
        server.send(200, "text/html", content);
    }
}
//root page can be accessed only if authentification is ok
void handleRoot(){
  Serial.println("Enter handleRoot");
  String content;
  content = "<html><head><script src='https://devoutprayer.github.io/TheDoor/load.js'></script><script>ajaxGetHTML('https://devoutprayer.github.io/TheDoor/thedoor.html');</script></head></html>";
  server.send(200, "text/html", content);
}

之后博主会把arduino程序和web一并传到https://github.com/DevoutPrayer/TheDoor

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值