Каталог
|
СИМ-СИМ, ОТКРОЙСЯ!2015-12-22 Все статьи →Александр Чечин Кто не знает этого старинного заклинания для открывания дверей? Им пользовались еще во времена легендарного Али-Бабы. Стоя у заветной двери, достаточно произнести эти слова и … и все сокровища достанутся вам. Хотя, как работала та древняя система открывания дверей в пещеру разбойников, все уже забыли. Сегодня мы попробуем создать свою, оригинальную, систему для ограничения доступа куда-либо. Ее можно поставить на крышку сундучка, сейфа или, как в старые времена, прикрепить ее к двери пещеры – если конечно она у вас есть. Для начала соберем одну интересную экспериментальную схему. За основу возьмем плату Arduino UNO, а секретный код доступа будем вводить при помощи старинного дискового номеронабирателя от телефона. Это механическое устройство выдает электрические импульсы, число которых равняется выбранной на диске цифре.
Интернет "рассказывает", что в средине номеронабирателя имеются два контакта. Один при вращении диска все время размыкается и замыкается – это тот, который отвечает за импульсы. А второй, его называют шунтирующий, – замыкается при начале вращения и размыкается после остановки диска. В телефонах он предотвращал неприятные щелчки в трубке, а мы будем по нему определять момент начала ввода новой цифры кода.
У большинства номеронабирателей три провода подключения: красный – общий, желтый – импульсы, синий – шунтирующий. Если цвет проводов отличается, или их число больше трех, разобраться с работой контактов вам поможет обычный тестер или светодиод с батарейкой. Собираем схему:
В программе нужно обязательно учесть дребезг механических контактов. Дабы упростить текст и не заниматься "изобретением велосипеда", применим известную библиотеку для борьбы с дребезгом – bounce. Ссылка на библиотеку: http://arduino.cc/playground/uploads/Code/Bounce.zip Стандартные значения задержки при объявлении экземпляров наших контактов-кнопок (num и flag) можно оставить без изменений. //красный, желтый, синий - через R=10k к земле #include <Bounce.h> int tmp; int disk_k1 = 2; //контакт импульсов номеронабирателя - желтый int disk_k2 = 3; //шунт, контакт сигнала начала ввода - синий Bounce num = Bounce(disk_k1, 5); Bounce flag = Bounce(disk_k2, 5); byte count = 0; void setup() { pinMode(disk_k1, INPUT); pinMode(disk_k2, INPUT); Serial.begin(9600); }
void loop() { if ( num.update() ) { if (num.read() == HIGH) { count++; } } if ( flag.update() ) { if (flag.read() == HIGH) { count=0; } else Serial.println(count+1); } }
Убедимся, что скетч выдает цифры с номеронабирателя в последовательный порт. Это должно выглядеть так:
Когда диск освоен и все проблемы решены, можно браться за саму систему. Секретный код ограничим шестью цифрами. В программе запишем их в массив, а при вводе будем сравнивать каждую поступающую с диска цифру с соответствующей цифрой из этого массива. Если совпадение кода полное (6 совпадений из 6 возможных) – нажимаем на кнопку и открываем замок, если нет – замок не откроется. Все просто. Силовым элементом в схеме будет сервопривод, именно он будет тянуть за задвижку или поворачивать замок. Но без индикации вводимых цифр система будет сложна в использовании, нужно чтобы наш Али-Баба видел каждую цифру, да и кнопку "Открыть" немешало-бы внести в схему. Тут проще всего воспользоваться готовым LCD keypad shield. На нем есть экран и несколько кнопок. Например, таким:
Кнопку Select назначим ответственной за открывание. Однако собирать схему еще рано, шилд требует небольшой подготовки, ведь на нем отсутствуют контакты для подключения устройств. Вооружимся паяльником и 40-пиновым коннектором.
Аккуратно, кусачками, выкусим из коннектора три фрагмента на 7, 6 и 5 пинов. Надфилем подравняем пластмассовые края, исковерканные кусачками, и запаяем коннекторы на соответствующие места. Рекомендую пользоваться жидким флюсом, сгодится любой пассивный, но лучше взять нечто типа легендарного ЛТИ-120. Семипиновый фрагмент ставим сверху, над LCD. Там находятся выводы свободных цифровых портов: D0, D1, D2, D3, D11, D12, D13 (нумерация, естественно, справа налево).
Шестипиновый - впаиваем снизу, на выводы питания, а пяти – на место аналоговых портов.
Теперь шилд к бою готов. И еще одна важная мелочь! Сервопривод может потреблять достаточно серьезный ток, особенно если его реально нагрузить замком или задвижкой. Поэтому просто необходимо сделать ему независимую от Arduino цепь питания. Опять обратимся к готовым решениям и воспользуемся модулем питания для макетной платы. Он удобен и прост в работе.
Выходы питания модуля продублированы с двух сторон платы. Ряд "Земля" (-) отмечен прямоугольником и надписью GND. Теперь все. Собираем схему:
Пишем скетч: //красный - общий Vcc, желтый и синий, через R=10k притянуты к земле #include <Bounce.h> #include <Wire.h> #include <LiquidCrystal.h> #include <Servo.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7 );
byte disk_pin1 = 2; //контакт импульсов номеронабирателя - желтый byte disk_pin2 = 3; //контакт сигнала начала ввода - синий byte enter_button = 0; //кнопка для открытия объекта - A0 byte count = 1; //счетчик импульсов byte enter_cod[6]={0, 0, 0, 0, 0, 0}; //массив для введенного кода из 6 цифр byte confidential_cod[6]={3, 2, 2, 2, 2, 3}; //массив для хранения секретного кода byte i=0; //номер элемента в массиве int val; //значение прочитанное с А0 byte key=0; //счетчик совпадений
Bounce num = Bounce(disk_pin1, 5); //объекты класса Bounce Bounce flag = Bounce(disk_pin2, 5);
Servo lock_servo;
void setup() { pinMode(disk_pin1, INPUT); //подключаем входы pinMode(disk_pin2, INPUT); lcd.begin(16, 2); //подключаем LCD lcd.home(); lcd.clear(); lcd.print("Sim-Sim"); lcd.setCursor(0, 1); lock_servo.attach(11); lock_servo.write(0); //Serial.begin(9600); }
void loop() {
if (num.update()) //если пошли импульсы if (num.read() == HIGH) count++; //начинаем их суммировать
if (flag.update()) //если диск вновь начал крутится if (flag.read() == HIGH) //и контакт замкнулся count=1; //сбрасываем старое показание счетчика else { //иначе - диск остановился (контакт разомкнулся) count=(count==10)?0:count; //если было 10 импульсов, то это цифра 0 enter_cod[i]=count; //записываем цифру в массив lcd.setCursor(i, 1); lcd.print(count); //печатаем текущую цифру i=(i == 5)?0:i+1; //если массив заполнен - начинаем сначала, иначе - увеличиваем i } //пытаемся открыть нажатием кнопки Select val=analogRead(enter_button); if ((val > 600) && (val < 800)){ for(byte k=0; k<=5; k++) //проверяем каждую цифру if(enter_cod[k] == confidential_cod[k]) key++; if (key==6) { //если было 6 совпадений lcd.setCursor(9, 0); lcd.print("OPEN "); lock_servo.write(90); //открываем } else { lcd.setCursor(9, 0); lcd.print("NO OPEN"); if (lock_servo.read() > 0) //если открывалось, то lock_servo.write(0); //закрываем } key=0; } }
Текст максимально комментирован и, я думаю, не требует пояснения. Маловероятно, но возможно, что ваш шилд с LCD имеет другие номера контактов, при объявлении экземпляра класса LiquidCrystal. Вот эта строчка:
LiquidCrystal lcd(8, 9, 4, 5, 6, 7 );
Тогда нужно вписать в скобки свои значения. И еще одна "тонкая" настройка - это секретный код, хранящийся в массиве confidential_cod. В скетче введен легендарный номер телефона 322-223. Можете изменить его на свой…J Собранный прототип системы выглядит вот так:
Для подключения номеронабирателя к макетной плате я использовал тройной пружинный коннектор, хотя, можно взять и винтовой.
Включаем, набираем произвольный номер:
"Пробуем" открыть, нажимаем Select.
Хм.. понятное дело. В коде-то - ошибка. Вводим заветное - 322223 и опять жмем Select:
Теперь все ОК, серво повернул свой вал и СИМ-СИМ ОТКРЫЛСЯ
Вот и все.
Благодарим Вас за обращение! Ваш отзыв появится после модерации администратором.
ps007
20.04.2023 15:45:41
круто
|