之前就一直在想如何用Arduino制作一个门锁,简单廉价,又可以很方便的开门,最后想了一个办法,就是使用一个声音传感器,制作一个“声纹锁”,以后没带钥匙,根据设定好的节拍敲门,门就开了,是不是很方便?
名称 | 数量 |
---|---|
Arduino UNO | 一个 |
声音传感模块 | 一个 |
舵机或继电器 | 一个 |
面包版 | 一个 |
跳线 | 数根 |
当声音传感器检测到一次振动后开始计时,接着第二次振动时算出间隔时间,如果间隔时间满足预先设定好的节拍,并且连续正确到节拍结束,就控制继电器或者舵机打开门。
经过我的测试,节拍长度最好大于10个,另外密码容错最好低于400,声音传感器的灵敏度调低点,就非常安全。再这样的情况,就算是你长时间的随机尝试密码,也不会撞对的。并且,市面上基本没人卖声纹锁,别人做梦也想不到开门的方式是敲门敲对节拍的。
#include //声明调用Servo.h库
#define THRESHOLD 200//密码容错范围
unsigned long t = 0;//基准时间
int key[5][9] = {
{400, 991, 313, 304, 343, 274, 271, 272, 663},
{329, 1108, 293, 272, 283, 254, 254, 278, 721},
{341, 1141, 295, 298, 343, 244, 272, 310, 741},
{352, 922, 284, 290, 314, 258, 256, 321, 588},
{559, 1240, 415, 421, 411, 401, 331, 419, 938}
};//声纹密码,义勇军进行曲前10个词的间隔,除去开始的第一个,含有5个节拍是为了适应不同的情况,让识别率更高
int i = 0;//输入的密码位数
Servo servo;//创建一个舵机对象
void setup()
{
servo.attach(9);//将引脚9上的舵机与声明的舵机对象连接起来
t = millis();
}
void loop()
{
int dt = millis() - t;
if (dt > 2000) {//如果长时间无响应
t = millis();//时间复位
i = 0;//密码复位
servo.write(0);//舵机复位
return;
}
if (analogRead(A0) < 200 && dt > 200) {//检测到声音并且间隔大于200毫秒
t = millis();
bool b = false;
for (int a = 0; a < sizeof(key) / sizeof(key[0]); a++) {
b = (key[a][i - 1] - THRESHOLD < dt && dt < key[a][i - 1] + THRESHOLD);
if (b) break;
}
if (i == 0 || b) {//判断声音间隔是否落在密码区间
if (++i > sizeof(key[0]) / sizeof(key[0][0])) {//如果密码输入完成
i = 0;//密码复位
servo.write(180);//舵机旋转180度
}
return;
}
i = 0;//密码复位
}
}
使用声音做密钥确实是不错的选择,当然你也可以提高密钥的级别,加以判断响度,音调,节奏等等方面,这样的话,才是真正的声纹锁,绝对是非常安全的。