开启左侧

密码锁自动开关防盗门——李桃

[复制链接]
发表于 2017-8-23 21:22:31 | 显示全部楼层 |阅读模式
本帖最后由 李桃 于 2017-8-23 21:28 编辑

作品简介: 该作品主要通过Arduino UNO ,i 创学学院扩展板,一个舵机,1602液晶自主设计的模型门,4*4按键等。实现对防盗门的密码判断,自动开关,和时钟显示等功能,可以用于家庭防盗门,密码柜等装置。本作品用舵机和连动装置实现门的转动,1602LCD显示实时日期,时间。按#输入密码(预设是1234)隨时按下A键退出,3次密码错误后,液晶屏幕提示。

作品图片:

IMG_6907.JPG
IMG_6906.JPG
IMG_6905.JPG
IMG_6902.JPG

程序源代码:
  1. #include <Servo.h>  // 舵机库
  2. #include <Keypad.h>  //加载库
  3. #include <LiquidCrystal.h>
  4. LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
  5. const int beep=9;
  6. const int serPin = 8;   //定义舵机信号引脚
  7. const int angleStep = 5;  //设定舵机转动的基本步幅
  8. int angle = 90;  //舵机的位置角度,初始值为90
  9. int motorStatus = 0; //状态变量0: close  1:open ?
  10. Servo myServo;   //定义一个舵机对象
  11. int flag = 0;

  12. unsigned long seconds;
  13. int  s = 0, m = 0, h = 0, d = 0, mon = 0, y = 0;   //时间进位
  14. int  second = 0, minute = 0, hour = 0, day = 0, month = 0, year = 0;  //当前时间
  15. int  SECOND = 0, MINUTE = 0, HOUR = 0, DAY = 0, MONTH = 0, YEAR = 0;  //初始时间


  16. char mima[4] = {0};
  17. char k = -2;
  18. char key = 0, key2 = 0;
  19. int t = 0, kk = 0;
  20. char thousand = 0; //读取千位
  21. char hundred = 0; //读取百位
  22. char ten = 0; //读取十位
  23. char one = 0; //读取个位

  24. const byte ROWS = 4;
  25. const byte COLS = 4;
  26. char keys[ROWS][COLS] = {
  27.   {'1', '2', '3', 'A'},
  28.   {'4', '5', '6', 'B'},
  29.   {'7', '8', '9', 'C'},
  30.   {'*', '0', '#', 'D'}
  31. };//建立二维数组,用于设置按键的输出字符
  32. byte rowPins[ROWS] = {14, 15, 16, 17}; //定义行引脚
  33. byte colPins[COLS] = {18, 19, 6, 7}; //定义列引脚

  34. Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );//实例化Keypad 对象
  35. void setup() {
  36.   myServo.attach(serPin);  //初始化舵机数据引脚
  37.   myServo.write(angle);  //定位舵机到90度
  38.   lcd.begin(16, 2);
  39.   lcd.noCursor();
  40.   Serial.begin(9600);

  41. }
  42. void loop() {
  43.   key = keypad.getKey(); //新建一个key 变量 用于获取键盘当前的值

  44.   if(flag>2){
  45.     digitalWrite(beep,HIGH);
  46.      clear_lcd_liney(0);
  47.      clear_lcd_linex(0);
  48.     lcd.print("Wrong 3 times!");
  49.   }
  50.   if (t == 0) {
  51.     lcd.setCursor(2, 1);   lcd.print(":");
  52.     lcd.setCursor(5, 1);   lcd.print(":");
  53.     lcd.setCursor(4, 0);   lcd.print('-');
  54.     lcd.setCursor(7, 0);   lcd.print('-');
  55.     set(2017, 8, 23, 17, 30, 00); //设置初始时间
  56.     seconds = millis() / 1000;
  57.     Display();
  58.   }

  59.   if (key != NO_KEY) {

  60.     if (key == '#') {
  61.       t = 1;
  62.       clear_lcd_liney(0);
  63.       clear_lcd_linex(0);
  64.       kk = 1;
  65.       lcd.print(key);
  66.     }
  67.     if (key == 'A') t = 0;
  68.     if (kk == 1) {
  69.       k = k + 1;
  70.       if (k < 4 && k >= 0) {
  71.         mima[k] = key;
  72.         lcd.print(key);
  73.       }
  74.       if (k == 3) {
  75.         if ('1' == mima[0] && '2' == mima[1] && '3' == mima[2] && '4' == mima[3]) {
  76.           clear_lcd_linex(0);
  77.           lcd.print("yes   welcome!");
  78.        digitalWrite(beep,LOW);
  79.           flag=0;
  80.           k = -2;
  81.           kk = 0;
  82.           duoji();
  83.         }
  84.         //如果密码不正确
  85.         else {
  86.           clear_lcd_linex(0);
  87.           lcd.print("password  error");
  88.           k = -2;
  89.           kk = 0;
  90.           flag=flag+1;
  91.         }
  92.       }
  93.     }
  94.   }
  95. }

  96. void clear_lcd_linex(byte x) {
  97.   x = x - 1;
  98.   lcd.setCursor(x, 0);
  99.   lcd.print("                ");
  100.   lcd.setCursor(0, 0);
  101. }
  102. void clear_lcd_liney(byte y) {
  103.   y = y - 1;
  104.   lcd.setCursor(0, y);
  105.   lcd.print("                ");
  106.   lcd.setCursor(0, y);
  107. }

  108. void duqu() {
  109.   int n;
  110.   for (n = 0; n < k; n++) {
  111.     Serial.println(mima[n] );
  112.   }
  113. }
  114. void duoji() {
  115.   for (char a = 0; a > -99; a--) {
  116.     myServo.write(a);
  117.     delay(9);
  118.   }
  119.   delay(2000);
  120.   for (char b = -99; b<90; b++) {
  121.     myServo.write(b);
  122.     delay(5);
  123.   }

  124. }
  125. void FormatDisplay(int col, int row, int num)  //格式化输出
  126. {
  127.   lcd.setCursor(col, row);
  128.   if (num < 10)   lcd.print("0");
  129.   lcd.print(num);
  130. }
  131. void time()   //计算时间
  132. {
  133.   second = ( SECOND + seconds ) % 60;   //计算秒
  134.   m = ( SECOND + seconds ) / 60;        //分钟进位
  135.   FormatDisplay(6, 1, second);

  136.   minute = ( MINUTE + m ) % 60;  //计算分钟
  137.   h = ( MINUTE + m ) / 60;       //小时进位
  138.   FormatDisplay(3, 1, minute);

  139.   hour = ( HOUR + h ) % 24;   //计算小时
  140.   d = ( HOUR + h ) / 24;      //天数进位
  141.   FormatDisplay(0, 1, hour);
  142. }

  143. int Days(int year, int month)   //根据年月计算当月天数
  144. {
  145.   int days = 0;
  146.   if (month != 2)
  147.   {
  148.     switch (month)
  149.     {
  150.       case 1: case 3: case 5: case 7: case 8: case 10: case 12: days = 31;  break;
  151.       case 4: case 6: case 9: case 11:  days = 30;  break;
  152.     }
  153.   }
  154.   else //闰年
  155.   {
  156.     if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)    days = 29;
  157.     else    days = 28;
  158.   }
  159.   return days;
  160. }

  161. void Day()   //计算当月天数
  162. {
  163.   int days = Days(year, month);
  164.   int days_up;
  165.   if ( month == 1 )   days_up = Days( year - 1, 12 );
  166.   else  days_up = Days( year, month - 1 );
  167.   day = ( DAY + d ) % days;
  168.   if ( day == 0 )   day = days;
  169.   if ( ( DAY + d ) == days + 1 )
  170.   {
  171.     DAY -= days;
  172.     mon++;
  173.   }
  174.   if (( DAY + d ) == 0)
  175.   {
  176.     DAY += days_up;
  177.     mon--;
  178.   }
  179.   FormatDisplay(8, 0, day);
  180. }

  181. void Month()    //计算月份
  182. {
  183.   month = ( MONTH + mon ) % 12;
  184.   if ( month == 0 )  month = 12;
  185.   y = ( MONTH + mon - 1) / 12;
  186.   FormatDisplay(5, 0, month);
  187. }

  188. void Year()    //计算年份
  189. {
  190.   year = ( YEAR + y ) % 9999;
  191.   if ( year == 0 ) year = 9999;
  192.   lcd.setCursor(0, 0);
  193.   if (year < 1000)  {
  194.     lcd.print("0");
  195.   }
  196.   if (year < 100)   {
  197.     lcd.print("0");
  198.   }
  199.   if (year < 10)    {
  200.     lcd.print("0");
  201.   }
  202.   lcd.print(year);
  203. }

  204. void Week(int y, int m, int d) //根据年月日计算星期几
  205. {
  206.   if (m == 1) m = 13;
  207.   if (m == 2) m = 14;
  208.   int week = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7 + 1;
  209.   String weekstr = "";
  210.   switch (week)
  211.   {
  212.     case 1: weekstr = "Mon. ";   break;
  213.     case 2: weekstr = "Tues. ";  break;
  214.     case 3: weekstr = "Wed. ";   break;
  215.     case 4: weekstr = "Thur. ";  break;
  216.     case 5: weekstr = "Fri. ";   break;
  217.     case 6: weekstr = "Sat. ";   break;
  218.     case 7: weekstr = "Sun. ";   break;
  219.   }
  220.   lcd.setCursor(11, 0);
  221.   lcd.print(weekstr);
  222. }

  223. void set(int y, int mon, int d, int h, int m, int s)
  224. {
  225.   YEAR = y;
  226.   MONTH = mon;
  227.   DAY = d;
  228.   HOUR = h;
  229.   MINUTE = m;
  230.   SECOND = s;
  231. }

  232. void Display()  //显示时间、日期、星期
  233. {
  234.   time();
  235.   Day();
  236.   Month();
  237.   Year();
  238.   Week(year, month, day);
  239. }
复制代码



shizhong.ino

5.87 KB, 下载次数: 0

密码锁源代码

IMG_6912_Compress.MP4

12.46 MB, 下载次数: 38

作品视频

回复

使用道具 举报

发表于 2017-8-23 21:37:41 | 显示全部楼层
作品很不错!
回复 支持 反对

使用道具 举报

发表于 2017-8-25 15:51:32 | 显示全部楼层
赞一个!
回复

使用道具 举报

发表于 2017-8-27 10:32:17 | 显示全部楼层
不错。用个时钟模块的话断电也能保存时间了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

精彩课程推荐

关于我们

帮助中心

商务合作

点击这里给我发消息

关注微信公众号

Copyright © 2016-2017 i创学院 - 上海享渔教育科技有限公司 Powered by Discuz!     ( 沪ICP备16033954号-1 )