Arduino - 改造楼道门禁,使用密码开门

楼道门禁系统为用户端可远程开门的那种。

拆开看线路板:

这里写图片描述

针对这四根线进行改造。

参考网友提供的方案:
http://www.arduino.cn/thread-4907-1-1.html

方案介绍:

通过按下楼道门上的房间按钮,连续按三次,根据每次不同的按键时间,判断其长短顺序是否符合要求,如果符合要求,则开门。
为简单起见,只需按三次即可,共有8种不同的排列方式:
短短短,短短长,短长短,短长长,长短短,长短长,长长短,长长长。
★ 按键次数多了太麻烦,次数少了太简单,容易被人试出来 ^-^,不过先这样吧。

关键点:

1、通过检测响铃时间,判断是否满足开门条件。
注意:响铃时的电压波动变化较大(1.5V-2.7V不等),不能维持在一个固定的高低电平或电压值,所以需要变通处理。
A、一种方法是通过中断口检测电平的每秒变化次数,来判断是否持续按下了响铃按钮。
B、一种是通过快速频繁取模拟电压值,检测每秒超过1V的电压次数,来判断是否持续按下了响铃按钮。
我选择了方案A,也是采纳了网友提供的方案,觉得这种方案比较简单、准确。

2、通过EEPRom保存按键密码的长短顺序,以保证掉电不丢失。密码可以通过设置按钮随时进行更改,每按一次设置按钮,密码变动一次。密码改动后,喇叭鸣叫进行提醒。

3、通过继电器控制开门,开门时喇叭鸣叫进行提醒。

焊接好后效果:

这里写图片描述

塑料外壳:

这里写图片描述

代码如下:

#include <EEPROM.h>
byte value_setup;//存储的密码。默认为0,即三短。
int aa,bb,cc;//存储的密码的三个分解值,0为短,1为长。
int pin_xinhao=2;//响铃信号
int pin_setup=3;//设置按钮
int pin_led_aa=6,pin_led_bb=5,pin_led_cc=4;//三个密码长短设置指示灯。
int pin_open=7;//开门继电器
int pin_laba=8;//喇叭,开门时鸣叫
int a,b,c,i,n;//三次按下的次数、当前按下的次数
int wuren,cishu;//设置没人按铃的时间,连续按铃的次数。

void setup()
{
//Serial.begin(9600);
pinMode(pin_xinhao,INPUT_PULLUP);
pinMode(pin_setup,INPUT_PULLUP);
pinMode(pin_led_aa,OUTPUT);
pinMode(pin_led_bb,OUTPUT);
pinMode(pin_led_cc,OUTPUT);
pinMode(pin_open,OUTPUT);
digitalWrite(pin_open,HIGH);//继电器初始值为HIGH,低电平触发。
pinMode(pin_laba,OUTPUT);
chushihua(); //初始化存储的密码
attachInterrupt(0, ring, CHANGE);
}

void chushihua()
{
value_setup=EEPROM.read(0);//读取设置
if ((value_setup&1)==1){aa=HIGH;}else{aa=LOW;} //分解值1
if ((value_setup&2)==2){bb=HIGH;}else{bb=LOW;} //分解值2
if ((value_setup&4)==4){cc=HIGH;}else{cc=LOW;} //分解值3
digitalWrite(pin_led_aa,aa); //亮灯1
digitalWrite(pin_led_bb,bb); //亮灯2
digitalWrite(pin_led_cc,cc); //亮灯3
digitalWrite(pin_laba,HIGH); //喇叭鸣叫
delay(100);
digitalWrite(pin_laba,LOW); //喇叭停止
delay(1000);
digitalWrite(pin_led_aa,LOW); //灭灯1
digitalWrite(pin_led_bb,LOW); //灭灯2
digitalWrite(pin_led_cc,LOW); //灭灯3
}

void ring(){ n++; }

void loop() {
//如果按下设置按钮,则进行密码长短设置处理
i = digitalRead(pin_setup);
if (i==LOW)
{
  value_setup++;
  if (value_setup>7){value_setup=0;}
  EEPROM.write(0,value_setup);
  chushihua();
  delay(500);//设置后延时500毫秒,避免频繁设置。
}
//进行正常信号检测
i=n;//对当前次数进行暂存
n=0;//清空当前次数,让信号触发事件可以立即进入下一循环。
//Serial.println(i);
if (i>100)
//如果有信号进入
{
  wuren=0;//清空无人按门铃的时间,避免自动清空数据。
  cishu++;//按下次数+1,1次200毫秒
}
else
//如果无信号进入
{ wuren++;
  if (wuren>20){a=0;b=0;c=0;wuren=0;cishu=0;}//如果没人按门铃的时间超过20次,约5秒,则全部置0
  if (cishu>0){a=b;b=c;c=cishu;cishu=0;}//如果按下次数>0,则当做密码进行记录
  if (a>0 && b>0 && c>0){
   
   //如果按了三次密码,则进行验证
      int aa1,bb1,cc1;//验证三个密码,0为短,1为长。
      if (a<4){aa1=LOW;}else{aa1=HIGH;}
      if (b<4){bb1=LOW;}else{bb1=HIGH;}
      if (c<4){cc1=LOW;}else{cc1=HIGH;}
      if (aa==aa1 && bb==bb1 && cc==cc1)
      {
          digitalWrite(pin_open,LOW);//触发继电器,开门
          delay(200);
          digitalWrite(pin_open,HIGH);
          digitalWrite(pin_laba,HIGH);//触发喇叭,进行提醒
          delay(200);
          digitalWrite(pin_laba,LOW);
       }
      a=0;b=0;c=0;//按下三次后,强制重新开始。
   }       
}
delay(200);
}

猜你喜欢

转载自blog.csdn.net/sdlgq/article/details/52035428
今日推荐