创客小制作(含源代码)《RFID控制器》,用于智能门禁、物流追踪、控制开关等,基于Arduino

创客小制作(含源代码)《RFID控制器》,用于智能门禁、物流追踪、控制物品等,基于Arduino

准备

RFID简介

射频识别即RFID(Radio Frequency IDentification)技术,又称无线射频识别,是一种通信技术,可通过无线电讯号识别特定目标并读写相关数据,而无需建立机械或光学接触。有低频(125k~134.2K)、高频(13.56Mhz)、超高频,微波等技术。RFID读写器也分移动式的和固定式的,目前RFID技术应用很广,如:图书馆,门禁系统,食品安全溯源等。

RFID的工作原理:标签进入磁场后,接收解读器发出的射频信号,凭借感应电流所获得的能量发送出存储在芯片中的产品信息(Passive Tag,无源标签或被动标签),或者由标签主动发送某一频率的信号(Active Tag,有源标签或主动标签),解读器读取信息并解码后,送至中央信息系统进行有关数据处理。

舵机介绍

舵机是一种位置伺服的驱动器,其工作原理是由接收机或者单片机发出信号给舵机,其内部有一个基准电路,产生周期为20ms,宽度为1.5ms 的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。经由电路板上的IC 判断转动方向,再驱动无核心马达开始转动,透过减速齿轮将动力传至摆臂,同时由位置检测器送回信号,判断是否已经到达定位。适用于那些需要角度不断变化并可以保持的控制系统。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。一般舵机旋转的角度范围是0 度到180 度。

思路

智能门禁

基于arduino与RFID,可通过RFID技术识别读入IC卡的序号并与设定的序号比较符合则使用舵机打开门禁,由于不同门禁的需要可选择不同的控制器代替舵机,如电磁开关、继电器,红外线发射装置。

物流追踪
关于物流跟踪,使用RFID技术识别读入IC卡的序号并报告给系统即可,其他内容本篇文章暂时讨论

控制物品
思路与智能门禁类似,可通过RFID技术识别读入IC卡的序号根据设定执行相关操作,如流水线上的两种产品贴上两种不同的无线射频标签,RFID技术识别后执行两种不同的操作(如放入不同流水线中),通过电磁开关、继电器,红外线发射等实现。

制作

材料

  1. Arduino
  2. RFID
  3. IC卡
  4. 舵机
  5. 杜邦线

可选材料

  1. LCD1002(显示)
  2. 继电器
  3. 电磁开关
  4. 红外线发射模块

接线

RFID对应Arduino UNO

RFID模块Arduino UNO
VCC3.3V
RST5V
GNDGND
MISO12
MOSI11
SCK13
NSS10
IRQ(不接)
舵机
所有的舵机都有外接三根线,分别用棕、红、橙三种颜色进行区分,由于舵机品牌不同,颜色也会有所差异,棕色为接地线,红色为电源正极线,橙色为信号线

感谢阅读

持续更新arduino 树莓派 python linux c语言等等
接到有帮助的话 求点赞👍 求关注❤️ 求分享👥
有问题可以评论
点关注,不迷路
如果有任何错误,如何建议,请批评指教,不胜感激 !

源代码(三个版本)

对代码有疑问可评论

智能门禁

这里以控制舵机为例子,如有需要显示可加上lcd1602详细可前往我的另一篇博客

Arduino实践(二)lcd1602使用说明,源码

/*
RFID模块  Arduino UNO
VCC      3.3V
RST    5V
GND   GND
MISO    12
MOSI   11
SCK   13
NSS   10
IRQ   (不接)
舵机
黄色   信号线
红色   5v
棕色   地级

 */


/*舵机*/
#include <Servo.h>
#include <SPI.h>
#include <MFRC522.h>
 
#define SS_PIN 10
#define RST_PIN 9
 
MFRC522 rfid(SS_PIN, RST_PIN); //实例化类
int relayPin = 6; //继电器引脚
int key = 7;//按键引脚
int incomedate = 0;//设置变量
String refid1="";

// 初始化数组用于存储读取到的NUID 
byte nuidPICC[4];


Servo myservo;  //创建一个舵机控制对象
                          // 使用Servo类最多可以控制8个舵机
int pos = 90;    // 该变量用与存储舵机角度位置
void setup() { 
   myservo.attach(8);  // 该舵机由arduino第九脚控制
  pinMode(key,INPUT_PULLUP);//按键为上拉输入
   pinMode(relayPin, OUTPUT);
  Serial.begin(9600);
  SPI.begin(); // 初始化SPI总线
  rfid.PCD_Init(); // 初始化 MFRC522 
}
 
void loop() {
  myservo.write(0);
   
  if (digitalRead(key)==LOW) 
   {delay(100);
   if (digitalRead(key)==LOW) incomedate = !incomedate;}
  
    if ((incomedate == 0))
    {
      digitalWrite(relayPin, HIGH);
     
    } 
    else if ((incomedate == 1))
    {
      digitalWrite(relayPin, LOW);
    
    }
 
  // 找卡
  if ( ! rfid.PICC_IsNewCardPresent())
   {    delay(500);
        if ( ! rfid.PICC_IsNewCardPresent())
           {incomedate = 1;
            return;}
    }
 
  // 验证NUID是否可读
  if ( ! rfid.PICC_ReadCardSerial())
    return;
 
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
 
  // 检查是否MIFARE卡类型
  if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&  
    piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
    piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
    Serial.println("不支持读取此卡类型");
    return;
  }
  
  // 将NUID保存到nuidPICC数组
  for (byte i = 0; i < 4; i++) {
    nuidPICC[i] = rfid.uid.uidByte[i];
  }   
  Serial.print("十六进制UID:");
  printHex(rfid.uid.uidByte, rfid.uid.size);
  Serial.println();
  
  Serial.print("十进制UID:");
  printDec(rfid.uid.uidByte, rfid.uid.size);
  Serial.println();
  if((refid1=="1214519892")||(refid1=="73217151153"))    
    {   
      incomedate = 0;
    //判断为真,执行需要的程序。
    Serial.println("已验证");
    myservo.write(pos);        // 指定舵机转向的角度
    delay(3000);                       // 等待15ms让舵机到达指定位置
    myservo.write(0);
      }
    else
    {
      //判断为假,执行需要的程序。
      Serial.println("验证失败");
      }


  
  // 使放置在读卡区的IC卡进入休眠状态,不再重复读卡
/ rfid.PICC_HaltA();
 
  // 停止读卡模块编码
/  rfid.PCD_StopCrypto1();
  refid1="";
  /* if (rfid.uid.uidByte, rfid.uid.size==183624630) 
   { incomedate = !incomedate;}
   */
    
   if ((incomedate == 0))
    {
      digitalWrite(relayPin, HIGH);
    
    } 
    else if ((incomedate == 1))
    {
      digitalWrite(relayPin, LOW);
    
    }
}
  void printHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : "");
    Serial.print(buffer[i], HEX);
    refid1+=nuidPICC[i];
  }
}
  void printDec(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : "");
    Serial.print(buffer[i], DEC);
    
  }
  
}

物流追踪

/*RFID模块*/
/*


RFID模块  Arduino UNO
VCC      3.3V
RST    5V
GND   GND
MISO    12
MOSI   11
SCK   13
NSS   10
IRQ   (不接)

 
 */

#include <SPI.h>
#include <MFRC522.h>
 
#define SS_PIN 10
#define RST_PIN 9
 
MFRC522 rfid(SS_PIN, RST_PIN); //实例化类
 
// 初始化数组用于存储读取到的NUID 
byte nuidPICC[4];
 
void setup() { 
  Serial.begin(9600);
  SPI.begin(); // 初始化SPI总线
  rfid.PCD_Init(); // 初始化 MFRC522 
}
 
void loop() {
 
  // 找卡
  if ( ! rfid.PICC_IsNewCardPresent())
    return;
 
  // 验证NUID是否可读
  if ( ! rfid.PICC_ReadCardSerial())
    return;
 
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
 
  // 检查是否MIFARE卡类型
  if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&  
    piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
    piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
    Serial.println("不支持读取此卡类型");
    return;
  }
  
  // 将NUID保存到nuidPICC数组
  for (byte i = 0; i < 4; i++) {
    nuidPICC[i] = rfid.uid.uidByte[i];
  }   
  Serial.print("十六进制UID:");
  printHex(rfid.uid.uidByte, rfid.uid.size);
  Serial.println();
  
  Serial.print("十进制UID:");
  printDec(rfid.uid.uidByte, rfid.uid.size);
  Serial.println();
  
  // 使放置在读卡区的IC卡进入休眠状态,不再重复读卡
  rfid.PICC_HaltA();
 
  // 停止读卡模块编码
  rfid.PCD_StopCrypto1();
}
 
void printHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : "");
    Serial.print(buffer[i], HEX);
  }
}
 
void printDec(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : "");
    Serial.print(buffer[i], DEC);
  }
}

控制继电器

/*


RFID模块  Arduino UNO
VCC      3.3V
RST    5V
GND   GND
MISO    12
MOSI   11
SCK   13
NSS   10
IRQ   (不接)

 
 */



#include <SPI.h>
#include <MFRC522.h>
 
#define SS_PIN 10
#define RST_PIN 9
 
MFRC522 rfid(SS_PIN, RST_PIN); //实例化类
int relayPin = 6; //继电器引脚
int key = 7;//按键引脚
int incomedate = 0;//设置变量
String refid1="";
 
// 初始化数组用于存储读取到的NUID 
byte nuidPICC[4];
 
void setup() { 
  pinMode(key,INPUT_PULLUP);//按键为上拉输入
   pinMode(relayPin, OUTPUT);
  Serial.begin(9600);
  SPI.begin(); // 初始化SPI总线
  rfid.PCD_Init(); // 初始化 MFRC522 
}
 
void loop() {
   
  if (digitalRead(key)==LOW) 
   {delay(100);
   if (digitalRead(key)==LOW) incomedate = !incomedate;}
  
    if ((incomedate == 0))
    {
      digitalWrite(relayPin, HIGH);
     
    } 
    else if ((incomedate == 1))
    {
      digitalWrite(relayPin, LOW);
    
    }
 
  // 找卡
  if ( ! rfid.PICC_IsNewCardPresent())
   {    delay(500);
        if ( ! rfid.PICC_IsNewCardPresent())
           {incomedate = 1;
            return;}
    }
 
  // 验证NUID是否可读
  if ( ! rfid.PICC_ReadCardSerial())
    return;
 
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
 
  // 检查是否MIFARE卡类型
  if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&  
    piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
    piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
    Serial.println("不支持读取此卡类型");
    return;
  }
  
  // 将NUID保存到nuidPICC数组
  for (byte i = 0; i < 4; i++) {
    nuidPICC[i] = rfid.uid.uidByte[i];
  }   
  Serial.print("十六进制UID:");
  printHex(rfid.uid.uidByte, rfid.uid.size);
  Serial.println();
  
  Serial.print("十进制UID:");
  printDec(rfid.uid.uidByte, rfid.uid.size);
  Serial.println();
  if((refid1=="1214519892")||(refid1=="73217151153"))    
    {   
      incomedate = 0;
    //判断为真,执行需要的程序。
    Serial.println("已验证");
      }
    else
    {
      //判断为假,执行需要的程序。
      Serial.println("验证失败");
      }


  
  // 使放置在读卡区的IC卡进入休眠状态,不再重复读卡
/ rfid.PICC_HaltA();
 
  // 停止读卡模块编码
/  rfid.PCD_StopCrypto1();
  refid1="";
  /* if (rfid.uid.uidByte, rfid.uid.size==183624630) 
   { incomedate = !incomedate;}
   */
    
   if ((incomedate == 0))
    {
      digitalWrite(relayPin, HIGH);
    
    } 
    else if ((incomedate == 1))
    {
      digitalWrite(relayPin, LOW);
    
    }
}
  void printHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : "");
    Serial.print(buffer[i], HEX);
    refid1+=nuidPICC[i];
  }
}
  void printDec(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : "");
    Serial.print(buffer[i], DEC);
    
  }
  
}

其他相关博客

Arduino小白入门全解,学习笔记

Arduino实践(二)lcd1602使用说明,源码

  • 4
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
RFID读卡模块原理图是ORCAD的,有PDF预览,PCB是PADS的,还有BOM烧写说明,标注图等。其中UART输出是量产过的 韦根输出的只是看示波器波形是对的,没有实际应用;里面有源代码,编写前提是是CODE小于1K RAM小于64字节。 原理图原理就是CD4060产生125KHZ的方波,经过推挽电路进行功率放大,高频电流进入LC串联谐振电路,345uH和4.7NF的谐振频率正好是125KHZ,这时电容两端电压会到十几伏,如果用CBB电容,会到二十多伏,这时读卡距离会到10CM以上。当有卡接近线圈时,线圈两端会有曼彻斯特编码的调幅波。通过二极管以及电容的检波和滤波,产生的小信号送入LM358进行放大和整形,变成单片机可以读取的曼彻斯特编码信号。 关于硬件电路设计上,CD4060在3.3V时 4M以下的晶振都可以起振,但2M的晶振体积很大,所以用了4M。实验发现ATTINY13的频率随着工作电压的变化会有很大的变化,所以不能用RC校准了,正好CD4060会输出4M,所以用来当系统时钟,保证时序的精确性。这样模块在3.3V 5V都能工作。 ATTINY13接不了无缘晶振 只能接有源的~ 它只有一个CLKIN脚~有源晶振价格就贵了。 另外ATTINY13只有5个IO口 1个用于中断 1个用于UART输出 1个用于CLKIN 1个用于上电波特率配置 1个用于曼彻斯特编码输入 正好用完了 RFID读卡模块 模块正反面 串口收到5个字节 前4个字节就是卡号 程序中,根据曼彻斯特原理,找到长电平和短电平,根据跳变沿分析出0数据还是1数据。然后寻找消息头,后面的数据进行 行 列奇偶校验,从而分析出卡号。 程序上电时,通过ADC引脚读取外部电阻的分压配置,从而初始化出4中波特率。然后进行读卡操作。实际应用中,要保证读卡的稳定,当卡靠近线圈时,要只发一次数据。要很好的去抖。代码不能超过1K。现在代码正好1024个字节。关于奇偶校验算法,异或和要比对2取余简洁,但我测试时发现异或和代码长度大于对2取余,所以用了对2取余。 RFID读卡模块原理图+PCB+代码+调试至附件下载

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GuanFuXinCSDN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值