我们出版了一本使用arduino的数字密码锁几周前。这个有点不同。早期版本是基于定义的密码,用户无法更改它。而且没有液晶显示器与项目接口输出锁定状态。这个项目是同一个数字密码锁的一个很大的改进版本用户定义的密码和液晶显示器。系统将提示用户设置一个密码在安装时。在安装时输入的此密码将继续用于锁,直到它被更改。用户只需按一次键即可更改当前密码。该程序将检查当前密码,并且仅当当前密码输入正确时,才允许用户更改密码。

使用arduino的代码锁

所需的知识

在尝试本项目之前,您应该学习两个重要的设备接口概念。首先是接口十六进制键盘与Arduino. 第二个是界面液晶与Arduino.一旦你理解了接口LCD模块和接口十六进制键盘背后的概念,它只是一个问题,添加几行代码来构建数字密码锁。我建议大家阅读简单的数字密码锁使用arduino也可以深入了解密码锁的基本原理。

注意:-在这个程序中,我重用了为将十六进制键盘与arduino接口而开发的代码。接口教程中有两个版本的程序。我使用了版本2。

关于节目

我将只解释节目的重点。如前所述,你应该知道接口十六进制键盘和lcd模块的代码。

使用的设备

安装-你会被要求输入5.数字作为密码在初始引导/重置设备的安全性。安装时输入的前5位数字将保存为设置密码。设置“密码”后,设备进入“锁定”状态。

关键A-用于解锁设备。输入正确的密码和密码按A解锁。

B键-可以随时锁定。只是按B您将看到LOCKED消息。

键C-修改密码。请输入正确的密码按C.您将看到消息要求输入新口令.进来5.数字作为密码。您输入的前5位数字将被保存为新密码。

例外情况-您不能在密码组合中使用密钥' A ', ' B '和' C '。这3个键是设备的控制键,具有特定的功能。程序检查这些按键(在密码设置时间-你可以看到SetPassword()函数和查看条件,以检查无效的键按)并将其标识为无效的键.你必须输入5个新数字在按下无效键后作为密码。

重要变量和数组

通过[6]-是用来保存和保存用户定义的密码的数组。

检查[6]–是用于收集和保存用户输入的数组。此用户输入数据(在检查[]数组)与通过[]验证密码的数组。

条目-是用来标识程序初始入口点的变量。用户被要求设置一个5位密码安装锁。因此我们需要一个变量识别条目循环5次收集5.并将其保存到通过[]数组。以后使用同一变量更改密码。当按下更改密码键(此处为“C”)时,此变量仅被分配一个零值(变量的初始状态)。这迫使程序控件重新进入程序的密码设置循环。

密钥id–是用于识别按键并在程序中执行某些操作的变量(仅在按键时发生)。默认情况下,设置此变量初始值。每当在键盘上按下一个键时,此变量将被分配一个值= 1。你可以查一下密钥扫描()函数来查看这个。这个简单的技巧有助于识别一个按键,并在该按键上执行各种操作(基于按键的值)。这个变量为零在程序的不同点(以防止值1密钥id变量被标识为假按键)。你也可以检查一下。

注意:-彩色扫描是激活a的实际变量按下键(因此有助于识别按下键)。但是这个变量实际上是键盘接口程序(版本2)的一部分。

计数-用于迭代的索引的变量检查(计数)(用户输入数组)。Count变量初始化为1。每个用户输入都将被保存到检查[]按计数变量的增量顺序排列的数组。

temp_press -是一个临时变量,用于保持键按下的值。属性的返回结果将key press的值赋给temp_press变量键盘按键()作用keypress()是定义用于标识按键值的函数。

lcd_count -是一个简单的计数器变量,用于迭代LCD模块的列位置。此变量有助于在LCD模块的第2行中连续显示用户输入数据。

i、 j,旗子–只是程序中使用的伪变量。i,j用作for循环中的计数器变量。国旗是用来保持地位的吗检查密码()子例程(用于比较用户输入数据和SET密码的函数)。决策是基于flag变量中的值做出的。

程序中使用的子程序

向SetPassword ()-是用于设置用户自定义密码的子例程。这个子程序非常依赖于密码设置循环写在主程序里面。这个密码设置循环将在设备安装时(即设备启动或重置时)进行迭代5个按键.这头5个按键将用于设置密码。这些按键将被保存到通过[]数组中。正如前面所提到的,条目是用于迭代循环的变量5.时代。密钥id是用于识别按键的变量。

注意:-同样的“密码设置循环,也用于修改密码。当关键“C”按下时,将检查当前密码。如果输入的密码与当前SET密码匹配,则条目变量将被分配给价值这将简单地转移程序的控制,以再次进入密码设置循环。

密钥扫描()–是扫描键盘按键的子程序。该子程序与arduino接口十六进制键盘的第2版代码基本相同。我已经为这个代码锁添加了一些代码行。除此之外,该子程序中的代码行与接口键盘中的代码行相同。keyscan()子例程扫描按键(当从主程序或其他子例程(如SetPassword())调用函数时),并标识按键的行和列。如果关键‘1’按下时,键扫描识别该键在第1行第1列按下。类似地,如果按下键“6”,则keyscan会在第2行和第3列标识按下的键。每次按下一个键时,另一个名为键盘按键()在keyscan()例程中调用。这个keypress()程序用于识别按键的值(比如' 1 ',' 2 ',' 3 '或' A ', ' C '或' D '等)

键盘按键()–如上所述,是识别按键值的子程序密钥扫描()程序识别键盘的哪一行和哪一列被按下。这行和列Number作为参数传递给keypress()例程(使用I和j的变量值)。

检查密码()-是检查用户输入密码与SET用户定义密码的子程序。用户输入数据(密码要交叉检查)收集在检查[]数组中。这与里面的SET Password进行比较通过[]大堆for循环用于比较。如果数组中的每个数字都匹配,则标志变量将保持为零。如果出现任何不匹配,该标志将设置为1,循环将中断。

这就是你们需要知道的关于这个程序的所有内容。阅读下面的程序,如果你有任何疑问,请留言。

程序

# include < LiquidCrystal.h > LiquidCrystal液晶(7、6、5、4、3、2);int row[]={A1,A0,8,9};//定义连接到Arduino引脚的小键盘的行引脚int col[]={10,11,12,13};//定义连接到Arduino的小键盘的列引脚int i,j,lcd_count,count=1,key_id=0,flag,entry=0;//变量保持键值按char检查[6],传递[6];// See About the Program void setup() {lcd.begin(16,2);(我= 0;< = 3,我+ +){pinMode(行[我],输出);pinMode (col[我],输入);digitalWrite (col[我],高);}液晶。print("SET 5 Digit PASS");} /*主程序开始*/ void loop() {while(entry<=4)//密码设置循环开始{SetPassword(); } // Password Setting Loop Ends key_id=0; keyscan(); // Scan for a Key Press /* Actions on Key Press begins */ if(key_id==1) // Condition to Check Key is Pressed { check[count]=temp_press; count++; /* Condition to Unlock Begins*/ if(temp_press=='A') { checkPassword(); if(flag==0) { lcd.setCursor(0,0); lcd.print("UNLOCKED"); }else{ lcd.setCursor(0,0); lcd.print("WRONG PASSWORD"); delay(200); lcd.clear(); lcd.print("LOCKED"); } count=1; // Resetting the counter variable } /* Condition to Unlock Ends*/ /* Condition to Change Password Begins */ else if(temp_press=='C') { checkPassword(); if(flag==0) { lcd.setCursor(0,0); lcd.print("ENTER NEW PASS"); key_id=0; entry=0; }else{ lcd.setCursor(0,0); lcd.print("WRONG PASSWORD"); } count=1; // Resetting the counter variable } /* Condition to Change Password Ends */ /* Condition to LOCK Begins*/ else if(temp_press=='B') { lcd.setCursor(0,0); lcd.print("LOCKED"); count=1; // Resetting the counter variable } /* Condition to LOCK Ends*/ } /* Actions on Key Press Ends*/ } /* Main Program Ends */ void SetPassword() // Subroutine to SET User Defined Password { keyscan(); if(key_id==1) { if(temp_press=='A'||temp_press=='C'||temp_press=='B') // Condition to Check for an Invalid Keypress { lcd.setCursor(0,0); lcd.print("INVALID KEYS"); entry=0; } else { pass[entry]=temp_press; } } key_id=0; if(entry==5) { lcd.clear(); lcd.setCursor(0,0); lcd.print("PASSWORD SET & LOCKED"); }} // Subroutine to SET Password ENDS char keyscan()// Subroutine to Scan Keypad for a Keypress { for(i=0; i<=3; i++) { digitalWrite(row[0],HIGH); digitalWrite(row[1],HIGH); digitalWrite(row[2],HIGH); digitalWrite(row[3],HIGH); digitalWrite(row[i],LOW); for(j=0; j<=3; j++) { col_scan=digitalRead(col[j]); if(col_scan==LOW) { key_id=1; entry++; temp_press=keypress(i,j); lcd.setCursor(lcd_count++,1); lcd.print(temp_press); if(temp_press=='A'||temp_press=='C'||temp_press=='B') { lcd_count=0; lcd.clear(); } delay(300); break; }} }}// Subroutine to Scan Keypress Ends char keypress(int i, int j) // Subroutine to Identify the value of Key pressed { if(i==0&&j==0) { return('1'); } if(i==0&&j==1) { return('2'); } if(i==0&&j==2) { return('3'); } if(i==0&&j==3) { return('A'); } if(i==1&&j==0) { return('4'); } if(i==1&&j==1) { return('5'); } if(i==1&&j==2) { return('6'); } if(i==1&&j==3) { return('B'); } if(i==2&&j==0) { return('7'); } if(i==2&&j==1) { return('8'); } if(i==2&&j==2) { return('9'); } if(i==2&&j==3) { return('C'); } if(i==3&&j==0) { return('*'); } if(i==3&&j==1) { return('0'); } if(i==3&&j==2) { return('#'); } if(i==3&&j==3) { return('D'); } } // Subroutine to identify Keypress Ends void checkPassword() // Subroutine to Check User Input Data with SET Password { flag=0; for(i=1;i<=5&&flag==0;i++) { if(check[i]==pass[i]) { flag=0; } else {flag=1; }}} // Subroutine to check password ends

请随意发表评论。

著者

44评论

  1. Okedi deogratius

    但是如果停电了,程序又开始了,会不会再次要求设置的密码!!这在现实世界的应用中是不可取的。

  2. nusrathmol

    海先生,

    我尝试这个代码使用arduino Uno。,我对密码有疑问。这就是我第一次输入密码的方式。

  3. 山杰杜尔·哈桑

    你好,我是评论很多次前,请给我的代码与eeprom。什么将要求设置密码第一次。然后程序将检查并从eeprom获得密码,不再要求设置密码。我尝试了这个代码,但是它不工作....
    代码是 ...................................
    #包括
    #包括
    #包括

    伺服伺服伺服;
    LiquidCrystal液晶(7、6、5、4、3、2);
    int row[]={13, 12,A5,A4};//定义连接到Arduino引脚的键盘的行引脚
    int col[]={A0,A1,A2,A3};//定义连接到Arduino键盘的列引脚
    int i,j,lcd_count,count=1,key_id=0,flag,entry=0;//参见About the Program
    int col_scan;//标识按键的变量
    char temp_press;//保存按键值的变量
    char[6],通过[6];//参见About the Program
    #定义红8
    int-bajaw=0;
    int蜂鸣器=11;

    无效的设置()
    {
    Serial.begin(9600);

    ser.attach (9);
    ser.write(90);
    pinMode(蜂鸣器、输出);
    lcd.begin (20, 4);
    pinMode(红、输出);

    对于(i=0;i<=3;i++)
    {
    pinMode(第[i]行,输出);
    pinMode (col[我],输入);
    digitalWrite (col[我],高);
    }
    lcd.clear ();
    lcd.setCursor (0,0);
    液晶打印(“智能家居”);
    lcd.setCursor (2, 1);
    液晶显示器。打印(“锁系统”);
    lcd.setCursor(4、6);
    液晶显示器。打印(“PU”);
    延迟(3000);
    lcd.clear ();
    如果(EEPROM.read (1) = = NULL) {
    液晶显示器。print("SET 5 Digit PASS");
    }否则{
    液晶显示器。打印(“给密码…”);
    }
    }

    /*主程序开始*/

    void循环()
    {
    如果(EEPROM.read (1) = = NULL) {
    while(entry<=4)//密码设置循环开始
    {
    向SetPassword ();
    }
    //密码设置循环结束
    }

    key_id = 0;
    keyscan ();//扫描一个按键

    /*操作键开始*/

    if(key_id==1) //检查键被按下的条件
    {
    检查[数]= temp_press;
    计数++;

    /*解锁条件开始*/

    如果(临时压力=='A')
    {
    检查密码();
    如果(标志= = 0)
    {
    lcd.setCursor (0,0);
    数字写入(红色,低电平);
    延迟(100);
    lcd.print(“解锁”);

    其他}{
    lcd.setCursor (0,0);
    液晶显示器。打印(“错误密码”);
    bajaw++;
    digitalWrite(蜂鸣器、高);
    延迟(2000年);
    如果(bajaw < 3) {
    数字写入(蜂鸣器,低电平);
    }
    lcd.clear ();
    lcd.打印(“锁定”);
    digitalWrite(红、高);
    }
    数= 1;//重置计数器变量
    }

    /*解除末端锁定的条件*/

    /*更改密码的条件开始*/

    否则,如果(临时压力=='C')
    {
    检查密码();
    如果(标志= = 0)
    {
    lcd.setCursor (0,0);
    液晶显示器。打印(“输入新通”);
    key_id = 0;
    条目=0;
    其他}{
    lcd.setCursor (0,0);
    液晶显示器。打印(“错误密码”);
    bajaw=bajaw+1;
    digitalWrite(蜂鸣器、高);
    延迟(1000);
    如果(bajaw < 3) {
    数字写入(蜂鸣器,低电平);
    }
    }
    数= 1;//重置计数器变量
    }

    /*更改密码的条件结束*/

    /*锁定条件开始*/

    否则,如果(临时压力=='B')
    {
    lcd.setCursor (0,0);
    lcd.打印(“锁定”);
    digitalWrite(红、高);
    数= 1;//重置计数器变量
    }
    /*锁定条件*/
    }

    /*按键结束时的动作*/
    }

    /*主程序结束*/

    void SetPassword() //设置用户自定义密码的子例程
    {
    keyscan ();
    如果(key_id = = 1)
    {
    if(temp_press=='A'| | temp_press=='C'| | temp_press=='B')//检查无效按键的条件
    {
    lcd.setCursor (0,0);
    lcd.打印(“无效键”);
    digitalWrite(蜂鸣器、高);
    延迟(500);
    数字写入(蜂鸣器,低电平);
    条目=0;
    }
    其他的
    {
    通过[输入]= temp_press;
    int entryy=条目+1;

    EEPROM写入(入口、温度压力);
    }
    }
    key_id = 0;
    如果(条目==5)
    {
    lcd.clear ();
    lcd.setCursor (0,0);
    lcd.打印(“密码设置和锁定”);
    digitalWrite(红、高);
    延迟(100);
    }
    }//设置密码结束的子例程

    char keyscan()//为一个按键扫描键盘的子程序
    {
    (我= 0;< = 3;我+ +)
    {
    数字写入(第[0]行,高);
    数字写入(第[1]行,高);
    数字写入(第[2]行,高);
    数字写入(第[3]行,高);
    digitalWrite(行[我],低);
    (j = 0;j < = 3;j + +)
    {
    col_scan=数字读取(col[j]);
    如果(列扫描==低)
    {
    key_id = 1;
    entry++;
    temp_press =键盘按键(i, j);
    lcd.setCursor (lcd_count + + 1);
    lcd.print (temp_press);
    如果(临时压力=='A'| |临时压力=='C'| |临时压力=='B')
    {
    lcd_计数=0;
    lcd.clear ();
    }
    延迟(300);
    打破
    }}
    }}//扫描按键结束的子程序

    char keypress(int i, int j) //识别按下键值的子例程
    {
    如果(i==0&&j==0)
    {
    返回(1);
    }
    如果(我= = 0 j = = 1)
    {
    返回(2);
    }
    如果(我= = 0 j = = 2)
    {
    回报(“3”);
    }
    如果(我= = 0 j = = 3)
    {
    报税表(“A”);
    }
    如果(i==1&&j==0)
    {
    返回(“4”);
    }
    如果(我= = 1 j = = 1)
    {
    返回(“5”);
    }
    如果(我= = 1 j = = 2)
    {
    返回(6);
    }
    如果(i==1&&j==3)
    {
    返回(B);
    }
    如果(我= = 2 j = = 0)
    {
    返回(' 7 ');
    }
    如果(我= = 2 j = = 1)
    {
    返回(“8”);
    }
    如果(我= = 2 j = = 2)
    {
    返回(' 9 ');
    }
    如果(我= = 2 j = = 3)
    {
    回报(“C”);
    }
    如果(我= = 3 j = = 0)
    {
    返回('*');
    }
    如果(i==3&&j==1)
    {
    返回(“0”);
    }
    如果(i==3&&j==2){
    返回(“#”);}
    如果(i==3&&j==3){
    返回(' D ');}
    }//用于标识按键结束的子例程

    void checkPassword()//使用设置的密码检查用户输入数据的子例程
    {
    国旗= 0;
    对于(i=1;i<=5&&flag==0;i++){
    串行打印(EEPROM.read(i),DEC);
    如果(检查[我]= =通过[我]| |检查[我]= = EEPROM.read(我)){
    国旗= 0;}
    else{flag=1;}
    }
    } //检查密码结束的子程序

  4. 张宇人

    嗨,我对你的代码有问题。我使用了6位密码。我设定的通行证是123456。LCD打印PW设置并锁定。我按了6位以上,系统不接受我的通行证(123456)。我怎样才能修好它。谢谢…。

    • 乔乔

      @汤米——这是你代码中的一个小故障。试着重新修改它!

  5. suhail

    你怎么没有回复一些评论。我有几个问题:-

    在你的草图中没有继电器模块控制程序。

    2-有一个很大的漏洞来破解安全系统。由于断电,当出现电源故障时,系统会提示设置初始化密码,因此,您是一个制造商,请仔细考虑。有一个eeprom的想法,但我尝试了,但没有工作
    我想你可以
    请重播,我等待你的答复。

  6. Sheikhuu

    我们做了这个项目。是的,它起作用了

  7. suhail

    先生,我实际上是一个初学者,我需要这个。项目。你能把访问eeprom的代码写出来吗。不仅仅是我,我想每个人。我们想你会为你的追随者做的。我们不知道如何编码……请

    • jhonex2

      是的,我也在尝试,请给我们使用EEPROM的代码

  8. Babulal甘地

    嗨,先生
    我不熟悉电子电路
    我试图在Arduino Mega 2560 + LCD 1602 +伺服电机+ 4×4键盘上做这个项目
    请你制作Youtube教程以便更好地理解。这样每个人都可以从你的数字锁系统中学习。
    您能解释一下继电器连接吗
    伺服电机连接在哪里
    或者请给我们一些你的项目图片的链接

    谢谢和问候
    Babulal甘地

    • rupa

      你完成这个项目了吗?
      我需要一些帮助,所以请回复

  9. Babulal甘地

    你好先生。

    很好的教程。虽然我搜索了整个互联网Arduino密码锁
    Arduino Uno或Mega+液态水晶+键盘和伺服电机组合。

    没有比你的草图解释更好的了。
    虽然我理解图表有问题,你能澄清一下吗
    1.+9v Going To继电器,
    2. +9伏至外部电源插座。
    如何给+9v继电器(RL1 9v SPDT继电器。

    先生,请您把这个项目的组件细节和线路细节制作成视频,并上传到Youtube上

    感谢和问候
    Babulal甘地

  10. 凯莫省

    它工作,但我连接了一个继电器5v线圈似乎不工作

  11. 杰里米

    我使用adruino mega和一个4×3的小键盘尝试了这段代码,结果发现小键盘的第一行无法按下(1 2 3),并且它不会显示在我的lcd上。你知道为什么吗?

  12. 贾尼斯黑门山

    很好的一天。。谢谢你的这个项目,这对我的论文很有帮助。。但是我有一个小问题。。我想增加一个gsm模块,使它更方便。。我怎样才能做到这一点?我已尝试将gsm的基本发送代码添加到此代码中,但设置密码后,无法再扫描密钥..请帮助。。谢谢

  13. 山杰杜尔·哈桑

    您好…谢谢您的教程。它工作正常。请帮助我将用户定义的密码设置为永久密码。我尝试了很多次。但都做不到。请帮助我…当用户可以设置密码时,它会出现一次。设置后,用户可以按此处给出的方式更改密码。请帮助我…

    • 乔乔

      @Shanjedul–您必须使用内存(EEPROM)来存储永久密码

  14. 国王

    我有一个小问题,我找不到在“系统”解锁时控制继电器的代码,你能提供类似的东西吗?
    我有arduino的继电器模块。

    谢谢你!

  15. 约翰

    您好,先生,工作正常,谢谢,但输出是通过9V继电器进行的,对吗?…我无法正确连接
    所以我的结果是好的,直到显示,但我的锁不工作,请帮助我如何操作我的锁从这个信号…再次感谢…

    • 乔乔

      你用的是9V继电器吗?你必须使用继电器驱动器(晶体管2N2222)连接继电器。如果没有9V继电器,你也可以使用12V继电器连接(确保你有一个单独的12V电源给继电器供电)

  16. Neeraj

    它能在arduino uno R3中工作吗?请清除这个DBT

  17. EFURHIEME

    请在什么版本的ARDUINO可以验证这个代码。我尝试了我的版本,它给了我一个错误代码403,SPI没有声明,请帮助。

    • 乔乔

      @ fuurhieme -我们在Arduino Uno上测试了这个。此代码是版本独立的。

  18. 蒂亚戈mendonca


    我一直在尝试这样做,但当我打开时,显示屏会自动插入*147。
    可能是哪个问题?
    英语不好,不好意思

    • 乔乔

      @Tiago–请重新检查您的代码。

      • 蒂亚戈mendonca

        代码就是上面的程序

  19. 嗨,普拉文

    谢谢您的代码,但我想知道为什么要将“count”变量设置为1?这是否意味着当你将temp_press的值传递给check[count]时,第二个数字将被初始化,而check的第一个数字为空?

    • 乔乔

      @cheng–check[]数组从1开始,一直到2,3,4,5。没有支票[0]。只有检查[1],检查[2]。。检查[5]

      明白了吗?

  20. 嗨,普拉文

    谢谢您的代码,但我想知道为什么要将“count”变量设置为1?这是否意味着当你将temp_press的值传递给check[count]时,第二个数字将被初始化,而check的第一个数字空?????

  21. mpesa

    只是好奇,密码重置选项是否会清除密码数据,使其可破解?

    • 乔乔

      @mpesa -不,不会的!密码重置选项要求输入当前密码并进行验证!

  22. R@ge

    嗨,普拉文,

    漂亮的代码。我一直在寻找可以更改密码的密码。不幸的是,只有在停电的时候才会出现问题,当前的密码已经不在了。如果它能被保存,我会很好。

    • 乔乔

      @R@ge -您可以通过访问Arduino的EEPROM内存来保存密码

  23. 马丹

    请结合实例详细介绍该电路的应用

  24. 斯瓦蒂

    请告诉我这个项目的申请。

  25. Bhupinder辛格

    感谢项目与完整的细节.....电子专业人士的最佳网站

Baidu