ESP8266 CH340创建NFC+网络服务器智能门禁

ESP8266 CH340创建NFC+网络服务器智能门禁

硬件部分

ESP8266串口wifi模块 CH340
RFID-RC522射频IC卡感应模块读卡器
MG995金属标准舵机 360度
辅件(电脑,杜邦线,能传输数据的microUSB,IC卡或ID卡)

设备接口描述

  • ESP8266

    在这里插入图片描述
  • RFID-RC522

在这里插入图片描述

  • MG995金属标准舵机

在这里插入图片描述

准备

驱动下载

esp8266 CH340驱动下载链接
https://sparks.gogo.co.nz/ch340.html

无脑安装

  1. 检查插入的USB线是否有接收到?
  2. 检查是否检测到端口?

答:

  1. USB插入是否有提示设备被插入(最直接的判断:听到叮咚声)
  2. 若安装好驱动,打开设备管理器,查看COM口号。记住COM口号(没有显示就是没有安装好,确定装完驱动后,没有显示就试试重启电脑并插拔一下数据线或者换根数据线)

环境

下载Mixly(米思齐)、arduino
采用Mixly(米思齐)辅助编程。arduino作为主编译器。(本来想用vs code来写的,PlatformIO这个插件的环境给我配烂了)
arduino环境参照 http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/nodemcu-arduino-ide/

添加开发板管理网址
http://arduino.esp8266.com/stable/package_esp8266com_index.json

接线

RFID-RC522与ESP8266接线

在这里插入图片描述

MG995金属标准舵机 360度与ESP8266接线

就三根线,
GND------GND
3V---------3V
PWM-----D8(GPIO15)

  • 3V和GND找到ESP8266的对应引脚插上,怎么接线方便怎么来

开发

ℹ️ 小测试 ESP8266 + RFID-RC522

首先,利用RC522检测我们手中的ID/IC卡,获取卡号,以便后续需要通过记录的卡控制。
请添加图片描述
从米思齐得知,SDA和RST能使用的引脚有10个,而其他的SCK、MOSI、MISO似乎只能用固定的14端口、13端口、12端口
在这里插入图片描述
分析代码
引入了#include <SPI.h> #include <MFRC522.h>两个库
然后MFRC522 rfid(16, 2);对应的就是SDA和RST
剩下的就是一些逻辑代码,注册和检测是否为新卡,后面直接CV
接着输出卡号
在这里插入图片描述
至此,上传,使用串口监视器查看获取的卡号,复制保存起来。如遇到卡号有存在空格也需要将它一并选上复制。

这个小测试的目的是:获取IC/ID卡号,同时测试RFID-RC522能否正常工作

ℹ️ 小测试 ESP8266 + MG995金属标准舵机 360度

  • ℹ️ 小小测试_1 直接上传控制MG995金属标准舵机
    在这里插入图片描述
    首先是用到了#include <Servo.h>
    使用.write(180);来控制舵机转的角度
    开始时用的这个180度的舵机控制,后知后觉的我才发现我买的是360度的呀,怎么只有180度?
    而且还转个不停,控制不住呀
    经过查阅资料发现,需要使用脉冲时长来控制.writeMicroseconds(1500);
    于是改了一下代码

     #include <Servo.h>
    
    Servo servo_15;
    
    void setup(){
      servo_15.attach(15);
      servo_15.writeMicroseconds(1500);
      delay(2000);
    }
    
    void loop(){
    
    }
    

    能够控制,但是无法调节角度,通过配合delay()控制时间的变化于是不断实验,得出以下结果
    在这里插入图片描述

    • 补充一下,这里没写如何转动90度,设置舵机为2000脉冲,delay时间延迟设置500ms-800ms,由于我舵机的问题,每次都会转到90度后会过去一点,也就是92°或者93°或者94°,不太准

    了解好舵机的转动功能后,开始一点点的加强一下

  • ℹ️ 小小测试_2 使用网络服务器控制MG995金属标准舵机

思路:网络服务器 - -> 开?关? --> MG995金属标准舵机

请添加图片描述
类似上图效果
首先是开启一个网络服务器,参照太极创客 http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-server/pin-control/*
里面写的很详细,主要用到两个库#include <ESP8266WiFi.h> #include <ESP8266WebServer.h>
也参照了大佬的博客https://blog.csdn.net/Zy_1213/article/details/124221032?spm=1001.2014.3001.5506
学会搭建好网络服务器后,就是逻辑思路了。

我自己是设计了两个页面,一个是CLOSE.html,一个是OPEN.html
根目录就是CLOSE.html,当点击后就会变成OPEN.html,再点击就是CLOSE.html;如此循环…
因为对web前端熟练,所以改html代码轻而易举

  • 我自己写的那份与nfc的合并在一起了,下面会展示完整代码

ℹ️ 完整项目ESP8266 + RFID-RC522 + MG995金属标准舵机 360度

#include <ESP8266WiFi.h>        // 本程序使用ESP8266WiFi库
#include <ESP8266WebServer.h>
#include <Servo.h>
#include <MFRC522.h>
#include <SPI.h>
 
// 基础变量、常量
const char* ssid     = "WIFI_NAME";      // 连接WiFi名(此处使用taichi-maker为示例)
                                            // 请将您需要连接的WiFi名填入引号中
const char* password = "PASSWORD";          // 连接WiFi密码(此处使用12345678为示例)
                                            // 请将您需要连接的WiFi密码填入引号中
const char *APssid = "AP_WIFI_NAME";
const char *APpassword = "AP_PASSWORD"; 

ESP8266WebServer esp8266_server(80);

Servo servo_15;

String mylist[]={"253df900","136ca29f"};
String RC;
MFRC522 rfid(16, 2);
bool s = false;

// ----------------NFC业务服务------------
String MFRC522_ReadCardUID(MFRC522 *_name){
  String _CardUID = "";
  for (byte _i = 0; _i < _name->uid.size; _i++){
    if(_name->uid.uidByte[_i] < 0x10)
      _CardUID += "0";
    _CardUID += String(_name->uid.uidByte[_i], HEX);
  }
  return _CardUID;
}

boolean MFRC522_IsNewCard(MFRC522 *_name){
  if(!_name->PICC_IsNewCardPresent())
    return false;
  if(!_name->PICC_ReadCardSerial())
    return false;
  return true;
}
// -------------网络服务基础业务-----------
// 开 页面代码
const char* open_html = "\
<!DOCTYPE html>\r\n\
<html lang='en'>\r\n\
<head>\r\n\
  <meta charset='UTF-8'>\r\n\
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>\r\n\
  <title>Switch</title>\r\n\
  <style>\r\n\
    body {\r\n\
      background-color: rgb(255, 250, 240);\r\n\
    }\r\n\
    .box {\r\n\
      width: 200px;\r\n\
      height: 110px;\r\n\
      background-color: rgb(144, 238, 156);\r\n\
      opacity:1;\r\n\
      border: 4px solid gray;\r\n\
      position: absolute;\r\n\
      left: 50%;\r\n\
      top: 50%;\r\n\
      margin-top: -55px;\r\n\
      margin-left: -100px;\r\n\
      border-radius: 10px;\r\n\
      font-size: 70px;\r\n\
      font-weight: 500;\r\n\
      color: white;\r\n\
      outline: none;\r\n\
    }\r\n\
  </style>\r\n\
</head>\r\n\
<body>\r\n\
  <form name='input' action='/CLOSE' method='POST' >\r\n\
    <input type='submit' value='Open' class='box'><br>\r\n\
  </form>\r\n\
</body>\r\n\
</html>\r\n\
";
// 关 页面代码
const char* close_html = "\
<!DOCTYPE html>\r\n\
<html lang='en'>\r\n\
<head>\r\n\
  <meta charset='UTF-8'>\r\n\
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>\r\n\
  <title>Switch</title>\r\n\
  <style>\r\n\
    body {\r\n\
      background-color: rgb(255, 250, 240);\r\n\
    }\r\n\
    .box {\r\n\
      width: 200px;\r\n\
      height: 110px;\r\n\
      background-color: rgb(156, 156, 156);\r\n\
      opacity:1;\r\n\
      border: 4px solid gray;\r\n\
      position: absolute;\r\n\
      left: 50%;\r\n\
      top: 50%;\r\n\
      margin-top: -55px;\r\n\
      margin-left: -100px;\r\n\
      border-radius: 10px;\r\n\
      font-size: 70px;\r\n\
      font-weight: 500;\r\n\
      color: white;\r\n\
      outline: none;\r\n\
    }\r\n\
  </style>\r\n\
</head>\r\n\
<body>\r\n\
  <form name='input' action='/OPEN' method='POST' >\r\n\
    <input type='submit' value='Open' class='box'><br>\r\n\
  </form>\r\n\
</body>\r\n\
</html>\r\n\
";
// 根目录
void handleRoot(){
  esp8266_server.send(200,"text/html",close_html);
}
// handleRootOPEN 触发开启功能
void handleRootOPEN(){
  esp8266_server.send(200,"text/html",open_html);
  esp8266_server.send(303);
  Serial.println("已开启");
  servoService(true);
}
// handleRootCLOSE 触发关闭功能
void handleRootCLOSE(){
  esp8266_server.send(200,"text/html",close_html);
  esp8266_server.send(303);
  Serial.println("已关闭");
  servoService(false);
}
// 404页面
void handleNotFound(){
  esp8266_server.send(200,"text/plain","404:Not Found找不到页面");
}
// -------------舵机配置-----------------
void initservo_15(){
  servo_15.attach(15,500,2500);
}
void servoService(bool b){
  
  // servo_15.write(90);
  // delay(2000);
  // servo_15.write(0);
  
  if(b){
    servo_15.writeMicroseconds(2000);
    delay(1000);
    servo_15.writeMicroseconds(1500);
  }else{
    servo_15.writeMicroseconds(1500);
  }
  
}
// ------------初始化------------------
void setup() {
  Serial.begin(9600);         // 启动串口通讯
  bool STAswitch = true;
  bool APswitch = false;
  RC = "";
  SPI.begin();
  rfid.PCD_Init();
  
  
  if(STAswitch){
    Serial.println("------------------STA配置 状态:开启---------------------------------");
    WiFi.begin(ssid, password);                  // 启动网络连接
    Serial.print("Connecting to ");              // 串口监视器输出网络连接信息
    Serial.print(ssid); Serial.println(" ...");  // 告知用户NodeMCU正在尝试WiFi连接
    
    int i = 0;                                   // 这一段程序语句用于检查WiFi是否连接成功
    while (WiFi.status() != WL_CONNECTED) {      // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。 
      delay(1000);                               // 如果WiFi连接成功则返回值为WL_CONNECTED                       
      Serial.print(i++); Serial.print(' ');      // 此处通过While循环让NodeMCU每隔一秒钟检查一次WiFi.status()函数返回值
    }                                            // 同时NodeMCU将通过串口监视器输出连接时长读秒。
                                                 // 这个读秒是通过变量i每隔一秒自加1来实现的。
    Serial.println("");                          // WiFi连接成功后
    Serial.println("Connection established!");   // NodeMCU将通过串口监视器输出"连接成功"信息。
    Serial.print("IP address:    ");             // 同时还将输出NodeMCU的IP地址。这一功能是通过调用
    Serial.println(WiFi.localIP());              // WiFi.localIP()函数来实现的。该函数的返回值即NodeMCU的IP地址。
  }else{
    Serial.println("STA状态:关闭");
  }
  
  if(APswitch){
    Serial.println("------------------AP配置 状态:开启---------------------------------");
    WiFi.softAP(APssid, APpassword); 
    Serial.print("Access Point: ");    // 通过串口监视器输出信息
    Serial.println(ssid);              // 告知用户NodeMCU所建立的WiFi名
    Serial.print("IP address: ");      // 以及NodeMCU的IP地址
    if(!STAswitch){
      Serial.println(WiFi.softAPIP());   // 通过调用WiFi.softAPIP()可以得到NodeMCU的IP地址
    }
  }else{
    Serial.println("AP状态:关闭");
  }
  

  Serial.println("------------------网络服务---------------------------------");
  esp8266_server.begin();
  esp8266_server.on("/",HTTP_GET,handleRoot);
  esp8266_server.on("/OPEN",HTTP_POST,handleRootOPEN);
  esp8266_server.on("/CLOSE",HTTP_POST,handleRootCLOSE);
  esp8266_server.onNotFound(handleNotFound);
  Serial.println("初始化舵机");
  initservo_15();
  Serial.println("进行中...");
  
  
}
 
void loop() { 
  int num = WiFi.softAPgetStationNum();
  if(WiFi.softAPgetStationNum() != num){
    num = WiFi.softAPgetStationNum();
    Serial.printf("Stations connected to soft-AP = %d\n",num);//显示连入esp8266的设备数量
    delay(3000);
  }
  esp8266_server.handleClient();
  // NFC
  if(MFRC522_IsNewCard(&rfid)){
    RC = MFRC522_ReadCardUID(&rfid);
    for (int i = (0); i <= (sizeof(mylist)/sizeof(mylist[0])); i = i + (1)) {
      // Serial.println("-----------------------------------");
      Serial.println(1);
      Serial.println(RC);
      Serial.println(mylist[i]);
      if (RC == mylist[i]) {
        Serial.println("匹配到登记卡");
        servoService(true);
      }else{
        servoService(false);
      }
      
    }
    rfid.PICC_HaltA();
    rfid.PCD_StopCrypto1();
  }
}

最后

这个项目后面可以增加一个锂电池,然后依据自己的条件设计符合门禁的装配。
初学物联网,有错的地方还得大佬们指点。

  • 8
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值