Arduino与Proteus仿真实例-密码门禁控制仿真

密码门禁控制仿真

1、应用介绍

本文将演示如何实现密码门禁控制逻辑仿真。

此次仿真主要涉及如下内容:

  • 密码输入、更新、验证
  • 门禁控制逻辑

此次仿真将使用继电器和直流电机作为电子门禁元件仿真器件。

在前面的文章中,对密码输入、更新、验证、储存,做了详细的仿真,请参考:

在前面的文章中,对继电器控制仿真,请参考:

2、仿真电路原理图

此次仿真电路原理图如下:

在这里插入图片描述

仿真电路分如下模块:

  • LCD驱动电路:按四线SPI驱动连接
  • 键盘驱动电路:由PCF8574驱动4x4矩阵键盘
  • 继电+直流电机驱动电路

3、仿真代码实现

在本次实例中,主要使用到如下开源库:

1)导入依赖头文件

1
2
3
4
5
6
#include <LiquidCrystal.h>
#include <Keypad\_I2C.h>
#include <Keypad.h>
#include <Wire.h>
#include <EEPROM.h>

2)创建LCD1602对象和定义继电器引脚

1
2
3
4
// LCD1602
LiquidCrystal lcd(12, 11,5, 4, 3, 2);// RS、RW,D0~D7
#define LOCK\_RELAY\_PIN 7

3)定义矩阵键盘对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define KEYPAD\_I2CADDR 0x20
// I2C键盘
const byte ROWS = 4; // 4行
const byte COLS = 4; // 4列
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'\*','0','#','D'}
};
// PCF8574IO映射
byte rowPins[ROWS] = {0, 1, 2, 3}; // 连接矩阵键盘行引脚
byte colPins[COLS] = {4, 5, 6, 7}; // 连接矩阵键盘列引脚

TwoWire \*jwire = &Wire; // I2C总线
Keypad_I2C kpd( makeKeymap(keys), rowPins, colPins, ROWS, COLS, KEYPAD_I2CADDR, PCF8574, jwire );


4)定义密码储存变量

1
2
3
4
5
6
7
8
9
10
11
12
#define PASSWORD\_ADDR 0x10 // 密码储存地址
#define PASSWORD\_INIT\_ADDR 0x01 // 密码状态地址
#define PASSWORD\_LEN 0x06 // 密码长度
#define PASSWORD\_UPDATE "\*#01#\*" // 密码更新
#define PASSWORD\_CMD\_COMPARE 0x01 // 密码验证
#define PASSWORD\_CMD\_UPDATE 0x02 // 密码更新

const char inited_password[PASSWORD_LEN] = {'1','2','3','4','5','6'}; // 默认密码
char saved_password[PASSWORD_LEN] = {0}; // EEPROM储存的密码
char current_password[PASSWORD_LEN] = {0}; // 当前输入密码
char password_cmd = PASSWORD_CMD_COMPARE; // 密码操作命令

5)密码初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 初始化密码
void init\_password(){
int isInited = 0;
isInited = EEPROM.read(PASSWORD_INIT_ADDR);
if(isInited != 1){ // 密码未初始化
int addr = PASSWORD_ADDR;
for(unsigned char i = 0;i < PASSWORD_LEN;i++){
EEPROM.write(addr,inited_password[i]); // 写入默认密码
addr++;
}
EEPROM.write(PASSWORD_INIT_ADDR,1); // 更新密码标志
Serial.println("initialized password");
}
}


6)密码读取

1
2
3
4
5
6
7
8
9
// 读取密码
void read\_password(){
int addr = PASSWORD_ADDR;
for(unsigned char i = 0;i < PASSWORD_LEN;i++){
saved_password[i] = (char)EEPROM.read(addr);
addr++;
}
}

7)密码比较

1
2
3
4
5
6
7
8
9
// 读取密码
void read\_password(){
int addr = PASSWORD_ADDR;
for(unsigned char i = 0;i < PASSWORD_LEN;i++){
saved_password[i] = (char)EEPROM.read(addr);
addr++;
}
}

8)密码更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 更新密码
void update\_password(char\* pass){
int addr = PASSWORD_ADDR;
for(unsigned char i = 0;i < PASSWORD_LEN;i++){
EEPROM.write(addr,inited_password[i]);
addr++;
}
Serial.println("password updated");
}

bool is\_update\_password(char\* pass){
return(pass[0] == '\*' && pass[1] == '#' && pass[2] == '0' && pass[3] == '1' && pass[4] == '#' && pass[5] == '\*');
}


9)门禁控制

1
2
3
4
5
6
7
8
9
10
11
12
// 开锁
void unlock\_door(){
digitalWrite(LOCK_RELAY_PIN,LOW);
delay(3000);
digitalWrite(LOCK_RELAY_PIN,HIGH);
}
// 关锁
void lock\_door(){
digitalWrite(LOCK_RELAY_PIN,HIGH);
}


10)设备初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void setup()
{
Serial.begin(9600);
init\_password();
read\_password();
pinMode(LOCK_RELAY_PIN,OUTPUT);
digitalWrite(LOCK_RELAY_PIN,HIGH);
Serial.print("inited password:");
for(unsigned char i = 0;i < PASSWORD_LEN;i++){
Serial.print((char)saved_password[i]);
}
Serial.println();
lcd.begin(16, 2); // 设置LCD的行和列
// 键盘初始化
jwire->begin();
kpd.begin();
}

11)门锁控制逻辑实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
unsigned char index = 0; // 当前密码输入索引 
bool is_updating_password = false; // 当前页面是否正在更新密码
void loop()
{
char key = kpd.getKey();
if(key){
if(password_cmd == PASSWORD_CMD_COMPARE){
current_password[index] = key;
if(index == 0){
lcd.clear();
}
lcd.setCursor(index, 0);
lcd.print('\*');
}else{
if(index == 0){
is_updating_password = true;
}
saved_password[index] = key;
current_password[index] = key;
lcd.setCursor(index, 2);
lcd.print((char)key);
}
Serial.print("index:");
Serial.print(index);
Serial.print(",key=");
Serial.println(key);
index++;
}
if(index == 6){
lcd.clear();
lcd.setCursor(0,0);
if(is\_update\_password(current_password)){
password_cmd = PASSWORD_CMD_UPDATE;
}
if(password_cmd == PASSWORD_CMD_UPDATE){
if(!is_updating_password){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Update Password:");
}else{
is\_update\_password(current_password);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Password Updated");
password_cmd = PASSWORD_CMD_COMPARE;
is_updating_password = false;
}
}else{
password_cmd = PASSWORD_CMD_COMPARE;
if(compare\_password(current_password)){
lcd.print("Lock opened");
unlock\_door();
}else{
lcd.print("Password Failed");
lock\_door();
}
}
index = 0;
}
}

仿真结果:

在这里插入图片描述

文章来源: https://iotsmart.blog.csdn.net/article/details/127918456