Необычный кодовый замок на Arduino

Ардуино — идеальная платформа для быстрого прототипирования. Много дурацких, но интересных идей без неё явно не реализовались бы. Вот давно зрела у меня идея какого-нибудь хитрого кодового замка — например, где кодом было бы время удерживания кнопки. Суть в том, что такой замок трудно вскрыть, даже зная в точности пароль — те, кто им успешно пользуются, выдерживаю интервалы, используя мышечную память, которой у злоумышленника явно не будет. Ну это в теории, конечно.

Я уже даже был готов взять генератор прямоугольных импульсов, 3 десятеричных счётчика и ещё ворох какой-то логики, чтобы это всё собрать… Но даже в smd это выглядело бы слишком громоздко и неудобно для практического использования. Но идея вертелась в голове и зрела… Избавиться от неё удалось, лишь написав прогу под Ардуино, превращающую её в кодовый замок, в котором одом является не номер нажатой кнопки (как в обычных), а сочетание кнопок, нажатых одновременно. Нигде раньше не встречал такого решения, если встретите — сообщите 🙂

Схема проста до безобразия. (код, впрочем, тоже )

Не очень хорошо видно, но кнопки подключаются к: а) земле и D3 (третий цифровой пин), b) D5 и D7 c) D9 и D11.

Кстати, fritzing оказалась удобной программой для создания таких рисунков — очень быстро, просто и наглядно. Не зря все уроки по ардуине с его помощью проиллюстрированы.

Вот и код:

const int ina = 3;
const int inb = 5;
const int inc = 9;
const int ledPin = 13;
int i = 1000;
byte a = 0;
byte b = 0;
byte c = 0;
byte d = 0;
unsigned long time = 0; //не забывайте всё, что принимает значение millis()
unsigned long temp = 0; //хранить в unsigned long
byte keya[] = { 0, 0, 0, 0, 0, 0, 0, 0}; //коды собственно
byte keyb[] = { 1, 1, 1, 1, 0, 1, 0, 0};
byte keyc[] = { 1, 0, 1, 0, 1, 1, 1, 0};
byte k = 0;

void setup() {
pinMode(ina, INPUT_PULLUP); //3 входа, подключаемые к кнопкам
pinMode(inb, INPUT_PULLUP);
pinMode(inc, INPUT_PULLUP);
pinMode(ledPin, OUTPUT); //встроенный светодиод на 13-ом пине
pinMode(7, OUTPUT);
pinMode(11, OUTPUT);
digitalWrite(7, LOW); //заменяют землю
digitalWrite(11, LOW);
time = millis(); //нужно для отсчёта времени
}

void blinktwice() { //двойное мигание светодиодом
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
delay(100);
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
delay(200);
}

void loop() {
if(k==0) {
blinktwice(); //приглашение ввести код
}
if (k == 8) {
digitalWrite(ledPin, HIGH);
delay(3000);
k = 0;
}
a = digitalRead(ina); //считываются уровни сигналов с кнопок — нажата/не нажата
b = digitalRead(inb);
c = digitalRead(inc);
delay(100); //следующий if — защита против ложных срабатываний, можно не использовать
if((digitalRead(ina) == a)&&(digitalRead(inb) ==b)&&(digitalRead(inc)==c)) {
if (a == keya[k]) {
if (b == keyb[k]) {
if (c == keyc[k]) {

k++;
}
}
}
}
if (k==1) {
if (d ==0) {
time = millis ();
d++;
}
}
temp = millis();
temp = temp — time;
if (temp > 10000) {
k= 0;
d=0;
time = millis ();
}
}

И раз уж на то пошло, объясню всё так, чтобы ни у кого не осталось вопросов. В setup() стандартно — назначение портов и установка низкого уровня на тех, кому предстоит заменять землю. INPUT_PULLUP — это значит что пин подтянут к +5В внутренним резистором (10 кОм, вроде). Это позволяет избежать «плавающего» сигнала на нём и не коротнуть чего лишнего при замыкании кнопкой на землю. blinktwice выделен в отдельную функцию ради удобства — никогда не упускайте возможности попрактиковаться в использовании функций! Далее считываются уровни сигнала на портах (они будут LOW, т.е 0, когда кнопка нажата, и 1, когда не нажата), и сравниваются с записанными в массивах значениями — например нулевые значения 0,1,1 означают, что первая кнопка должна быть нажата, а две других обязательно отжаты. Если условие выполняется, происходит переход к следующим значениям. Когда все 7 последовательных условий выполнились, выполняется условие k==8 и светодиод загорается на 3 секунды, сигнализируя о правильности введённого кода. В этот кусок кода надо вписывать то, что и должно происходить при этом — открытие двери, звуковой сигнал и т.д.

Оставшийся кусок кода сбрасывает счётчик, если с момента первого введения комбинации (при этом гаснет светодиод) прошло больше 10 секунд. Без этого было бы в принципе возможно перебрать все последовательности нажатых кнопок, хотя их число составляет (2^3)^7 = 2^21, что больше 2-х миллионов. Очень полезно помнить при этом, что в году всего лишь 31 миллион секунд. А время введения правильного кода — 5 секунд после небольшой тренировки, так что можно ещё зажать по времени. Мне пока не на ком тестировать систему, но если кому система понравится наслишь, чтобы воплотить её в жизнь — пожалуйста, напишите о результатах!

Прикрепленные файлы:

Добавить комментарий

Ваш адрес email не будет опубликован.