|
好久没发帖了,来电小干货~~
昨天心血来潮帮一位同学做了一个关于密码锁的课设
要求如下:
1、在输入密码正确的状态下可以修改密码
2、连续输入三次错误密码锁定键盘,锁定状态下检测到有按键按下重新计时
这里涉及到4*4键盘和1602的使用,做的过程发现还是需要动动脑的
先上照片
开机输入密码~~
输入中密码用‘*’号显示
输入错误
连续三次错误锁定键盘等待30秒
锁定期间有按键输入重新计时
实现过程:
其实还是蛮简单的
使用到的硬件有LCD1602、4*4键盘、和promini(UNO、nano也可)
本次使用到的库有Keypad.h和LiquidCrystal.h
没有用IIC转接板,如果用IIC转接的用对应的1602的IIC库就可以啦,也是蛮简单的
先附上1602引脚图
1602接线(偷懒复制注释里的,3号脚接电阻调节对比度,我这里偷懒直接接地了,所以有些模糊)
LCD RS pin to digital pin 12
LCD Enable pin to digital pin 11
LCD D4 pin to digital pin 5
LCD D5 pin to digital pin 4
LCD D6 pin to digital pin 3
LCD D7 pin to digital pin 2
LCD R/W pin to ground
LCD VSS pin to ground
LCD VCC pin to 5V
键盘四横四纵,我接了三横四纵
具体接线看程序中
代如下:
[mw_shl_code=cpp,true]/*
The circuit:
LCD RS pin to digital pin 12
LCD Enable pin to digital pin 11
LCD D4 pin to digital pin 5
LCD D5 pin to digital pin 4
LCD D6 pin to digital pin 3
LCD D7 pin to digital pin 2
LCD R/W pin to ground
LCD VSS pin to ground
LCD VCC pin to 5V
10K resistor:
ends to +5V and ground
wiper to LCD VO pin (pin 3)
lcd.begin(16, 2);
lcd.print("hello, world!");
lcd.setCursor(0, 1);
*/
#include <LiquidCrystal.h>//1602库
#include <Keypad.h>//键盘库
#include <EEPROM.h>//EEPROM库用来保存修改过的密码,掉电后不遗失
const byte ROWS = 3; //3行
const byte COLS = 4; //4列
//键盘位置
char hexaKeys[ROWS][COLS] = {
{'1', '2', '3', '4'},
{'5', '6', '7', '8'},
{'9', '0', '*', '#'}
};
byte rowPins[ROWS] = {15, 14, 10}; //定义接键盘横排引脚
byte colPins[COLS] = {9, 8, 7, 6}; //竖排引脚定义
//新的键盘对象
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
// 1602引脚,接法参照最上方注释
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);//lcd连接引脚
String oldPassword = "";//保存老密码
String newPassword = "";//保存输入的修改密码
int addNum = 0;//错误计数
String inPut = "";//保存输入字符串
String n = "";//字符串转整型用的变量
int beep = 13;//蜂鸣器和板载led
unsigned long now;//现在时间用于计时
unsigned long before;//参考时间用于计时
unsigned long delayTime = 30000;//锁定时间
void setup() {
pinMode(beep, OUTPUT);//蜂鸣器引脚
Serial.begin(9600);//初始化串口
// 定义LCD两行16列
lcd.begin(16, 2);
//开机从EEPROM中读取密码,四位密码保存在EEPROM0-3地址当中
for (int i = 0; i < 4; i++)
{
oldPassword += EEPROM.read(i);
}
//串口打印测试信息
Serial.print("Old Password is : ");
Serial.println(oldPassword);
delay(2000);
lcd.setCursor(0, 0);//1602输出位置,格式列、行
lcd.print("Please input :");//1602输出
}
int i = 6;//'*'号开始位置
void loop() {
char customKey = customKeypad.getKey();//获取按键
if (customKey)//有按键按下
{
inPut += customKey;//保存输入
lcd.setCursor(i, 1);//在指定位置输出*号
lcd.print('*');
//串口打印测试信息
Serial.println("inPut is : ");
Serial.println(inPut);
Serial.println("onece");
i++;//后移1602输出*号位置
if (i > 9)//超过输出位置回归
{
i = 6;
}
}
//比较密码
if (inPut == oldPassword) //密码正确
{
addNum = 0;//错误次数清零
Serial.println("Bingo!");//串口打印测试信息
lcd.clear();//清屏
lcd.setCursor(4, 0);//输出位置
lcd.print("Bingo!");//输出bingo
delay(2000);//延时2秒
lcd.clear();//清屏
delay(500);
lcd.setCursor(0, 0); //1列1行
lcd.print("Change Password?");//lcd输出是否修改密码
Serial.println("change password?");//串口打印测试信息
lcd.setCursor(0, 1);
lcd.print("1.YES 2.NO");//lcd输出1yes2no
int a = 1;
while (a)//等待按键按下
{
customKey = customKeypad.getKey();
Serial.println("while");
if (customKey == '1') //选择1则修改密码
{
a = 0;//跳出while循环
Serial.println("select 1");//串口打印测试信息
inPut = "";//输入字符串清空
lcd.clear();//LCD清屏
lcd.setCursor(0, 0);//位置
lcd.print("Input the new:");//输出
for (int b = 0; b < 4;)//输入新密码
{
customKey = customKeypad.getKey();
if (customKey)
{
lcd.setCursor(b + 4, 1);
lcd.print(customKey);
newPassword += customKey;
n = customKey;
int num = n.toInt();//将输入的字符转换为整型用toInt()函数
n = "";
//EEPROM保存新密码
EEPROM.write(b, num );
Serial.print("EEPROM ");
Serial.print(b);
Serial.print(" is : ");
Serial.println(EEPROM.read(b));
Serial.print("new password is ");
Serial.println(newPassword);
b++;
if (b == 4 )//满足4位
{ newPassword = "";
lcd.clear();
lcd.setCursor(0, 0);//格式列、行
lcd.print("Save the new !");//lcd输出保存新密码
delay(2000);//延时两秒
oldPassword = "";//清空重置
//读取新密码并设置为当前密码
for (int i = 0; i < 4; i++) {
oldPassword += EEPROM.read(i);
}
lcd.clear();
lcd.setCursor(0, 0);//格式列、行
lcd.print("Please input :");
}
}
}
}
else if (customKey == '2') //选择2什么都不干返回主页
{
a = 0;
inPut = "";//清空输入
lcd.clear();
lcd.setCursor(0, 0);//格式列、行
lcd.print("Please input :");
Serial.println("back to home");
}
}
}
else if (inPut.length() == 4 && inPut != oldPassword)//密码错误
{
Serial.println("ERROR");//串口打印测试信息
//LCD组合操作清屏,位置,输出信息
lcd.clear();
lcd.setCursor(5, 0);
lcd.print("ERROR!");
inPut = "";//清空输入
addNum++;//错误计数+1
//串口打印测试信息
Serial.print("addNum is : ");
Serial.println(addNum);
delay(1500);
lcd.clear();
lcd.setCursor(0, 0);//格式列、行
lcd.print("Please input :");
}
if (addNum > 2)//当错到第三次
{
//LCD组合操作
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Wait for 30s");
//蜂鸣器报警一秒
digitalWrite(beep, HIGH);
delay(1000);
//计时
before = millis();//参考时间
now = millis();//当前时间
//串口输出测试信息
Serial.print("before is : ");
Serial.println(before);
Serial.print("now is : ");
Serial.println(now);
//锁定键盘等待30秒锁定
while (now - before < delayTime)//当前时间减参考时间小于设定锁定时间
{
lcd.setCursor(0, 0);
lcd.print("Wait for s");
lcd.setCursor(9, 0);
lcd.print((30000 - (now - before)) / 1000);//LCD输出剩余秒数
now = millis();
Serial.print("n-b= ");
Serial.println(now - before);
char key = customKeypad.getKey();
if (key)//如果有按键按下重置时间
{
before = millis();
now = millis();
//串口输出测试信息
Serial.print("key~~~before is ");
Serial.println(now - before);
}
}
addNum = 0;//锁定时间到,错误次数清零
lcd.clear();
lcd.setCursor(0, 0);//格式列、行
lcd.print("Please input :");
}
}
[/mw_shl_code]
最后增加一点:
由于程序开头是直接读取EEPROM中保存的数据,所以在烧录上面的程序前请先对EEPROM进行写入默认密码操作,代码如下(先烧这个程序,再烧上面的代码)
[mw_shl_code=cpp,true]#include <EEPROM.h>
void setup() {
for(int i = 0;i<4;i++)
{
EEPROM.write(i,1);//将EEPROM中0-3地址写入1,初始默认密码四个一
}
}
void loop() {}[/mw_shl_code]
操作视频:
使用到的Keypad库,LiquidCrystal库IDE自带
Keypad.zip
(9.58 KB, 下载次数: 405)
|
|