
Створіть власний секретний замок Arduino за допомогою п’єзоелемента та сервомотора! У цій частині ми навчимося використовувати вібраційний сенсор для розпізнавання ударів і відкривати замок тільки при введенні правильного коду.
Створіть власний секретний механізм замикання, щоб уберегти свій простір від небажаних гостей!
П’єзоелемент, який ви використовували для відтворення звуків у проєктах із терменвоксом та клавіатурою, також можна використовувати як вхідний пристрій. Підключений до 5В, цей сенсор здатний вловлювати вібрації, які Arduino може зчитувати через аналогові входи. Щоб пристрій працював коректно, необхідно підключити резистор великого номіналу (наприклад, 1 МОм) як еталонний до землі.
Якщо п’єзоелемент щільно притиснути до твердої поверхні, здатної вібрувати (наприклад, дерев’яного столу), Arduino зможе визначати силу удару. Використовуючи ці дані, можна перевіряти, чи входить кількість ударів у допустимий діапазон. У коді можна відстежувати кількість ударів і перевіряти, чи відповідають вони заданим параметрам.
Кнопка дозволить заблокувати мотор у певному положенні. Додатково світлодіоди показуватимуть статус замка:
Червоний – коробка замкнена.
Зелений – коробка відкрита.
Жовтий – отримано правильний удар.
Також вам доведеться написати власну функцію, яка визначатиме, чи є удар занадто тихим або занадто гучним. Використання функцій допомагає економити час на програмуванні, дозволяючи повторно використовувати код замість написання одних і тих самих команд. У цьому випадку ви передаватимете функції значення гучності удару. Якщо воно знаходиться у потрібному діапазоні, змінна буде збільшуватись.
Схему можна зібрати окремо, але набагато цікавіше використовувати цей пристрій для захисту речей. Якщо у вас є дерев’яна або картонна коробка, в якій можна вирізати отвори, ви можете встановити сервомотор, який керуватиме засувкою, запобігаючи доступу до ваших речей.
На платі є багато з’єднань, обов’язково слідкуйте за тим, як все підключено.
Підключіть живлення та землю до обох сторін макетної плати. Встановіть кнопку на макетну плату та підключіть один її контакт до 5В. Другий контакт з’єднайте з землею через резистор 10 кОм. Також підключіть цей контакт до цифрового входу D2 на Arduino.
Приєднайте дроти від п’єзоелемента до макетної плати. Один дріт підключіть до живлення. Якщо на п’єзо є червоний дріт або позначка «+», підключіть його до 5В. Якщо п’єзоелемент не має позначеної полярності, його можна підключати будь-яким способом. Інший дріт підключіть до аналогового входу A0 на Arduino. Помістіть резистор 1 МОм між землею та цим дротом. Менші значення резистора зроблять п’єзо менш чутливим до вібрацій.
Підключіть світлодіоди, з’єднавши їх катоди (коротку ніжку) із землею та підключивши аноди через резистор 220 Ом. Підключіть жовтий світлодіод до цифрового виводу D3 на Arduino, зелений до D4, а червоний до D5.
Вставте чоловічі роз’єми в гніздо сервомотора. Підключіть червоний дріт до живлення, чорний до землі. Помістіть електролітичний конденсатор 100 мкФ між живленням і землею, щоб згладити можливі перепади напруги, стежачи за правильною полярністю конденсатора. Підключіть сигнальний дріт сервомотора до виводу D9 на Arduino.
Додайте бібліотеку Servo, як у проєкті Mood Cue, та створіть екземпляр об’єкта для керування мотором.
Створіть константи, щоб позначити входи та виходи.
Оголосіть змінні, які зберігатимуть значення від кнопки та п’єзоелемента.
Визначте порогові значення для ударів, задавши мінімальну та максимальну гучність удару.
Створіть змінні для стану замка та кількості отриманих ударів. Змінна locked відображатиме, чи замкнений механізм. Boolean – це тип даних, який може бути лише true (1) або false (0). Початково механізм повинен бути у відкритому стані. Остання глобальна змінна зберігатиме кількість правильних ударів.
У setup() задайте напрямок цифрових пінів, ініціалізуйте об’єкт серво та серійний порт. Підключіть сервомотор до піну 9, задайте світлодіоди як виходи, а кнопку – як вхід.
Ініціалізуйте серійний зв’язок з комп’ютером, щоб відстежувати силу ударів, стан замка та кількість ударів, необхідних для відкриття. Увімкніть зелений світлодіод, переведіть серво у розблоковану позицію та виведіть у серійний монітор повідомлення про те, що система розблокована.
У loop() спочатку перевірте, чи замкнена коробка. Від цього залежить, що відбуватиметься у програмі. Якщо замок зачинений, зчитайте значення кнопки.
#include <Servo.h> Servo myServo; const int piezo = A0; const int switchPin = 2; const int yellowLed = 3; const int greenLed = 4; const int redLed = 5; int knockVal; int switchVal; const int quietKnock = 10; const int loudKnock = 100; boolean locked = false; int numberOfKnocks = 0; void setup(){ myServo.attach(9); pinMode(yellowLed, OUTPUT); pinMode(redLed, OUTPUT); pinMode(greenLed, OUTPUT); pinMode(switchPin, INPUT); Serial.begin(9600); digitalWrite(greenLed, HIGH); myServo.write(0); Serial.println(“The box is unlocked!”); } void loop(){ if(locked == false){ switchVal = digitalRead(switchPin);
Якщо кнопка натиснута, змініть значення змінної locked на
true
, що вказує на активацію замка. Вимкніть зелений світлодіод, увімкніть червоний світлодіод. Це слугуватиме візуальним індикатором стану замка, якщо серійний монітор вимкнено. Перемістіть серво у позицію блокування та виведіть у серійний монітор повідомлення про те, що коробка тепер замкнена. Додайте затримку, щоб замок встиг зайняти правильне положення.
Якщо змінна locked == true і замок активовано, зчитайте значення вібрації з п’єзоелемента та збережіть його у змінну knockVal.
Перевірте, чи кількість правильних ударів менша за три та чи є вібрація на датчику. Якщо обидві умови виконуються, перевірте, чи удар є допустимим. Якщо так, збільшіть значення змінної numberOfKnocks. Саме тут викликається функція checkForKnocks(), яка перевірятиме коректність удару. Передайте змінну knockVal як аргумент. Після перевірки функції виведіть у серійний монітор, скільки ударів залишилося для розблокування.
Перевірте, чи отримано три або більше правильних удари. Якщо так, змініть locked на
false
, переведіть серво у розблоковане положення. Дочекайтеся кілька мілісекунд, щоб механізм встиг спрацювати, змініть стан світлодіодів: зелений вмикається, червоний вимикається. Виведіть у серійний монітор повідомлення про відкриття замка. Закрийтеelse
таloop()
парою фігурних дужок.
Тепер напишемо функцію checkForKnock(). При створенні власних функцій потрібно вказати, повертатимуть вони значення чи ні. Якщо функція нічого не повертає, її потрібно оголосити як void
, як setup()
і loop()
. Якщо вона повертає значення, потрібно вказати тип (int
, long
, float
тощо). У цьому випадку функція перевірятиме, чи удар є правильним (true
) або неправильним (false
). Тому її слід оголосити як boolean
.
if(switchVal == HIGH){ locked = true; digitalWrite(greenLed,LOW); digitalWrite(redLed,HIGH); myServo.write(90); Serial.println(“The box is locked!”); delay (1000); } } if(locked == true){ knockVal = analogRead(piezo); if(numberOfKnocks < 3 && knockVal > 0){ if(checkForKnock(knockVal) == true){ numberOfKnocks++; } Serial.print(3-numberOfKnocks); Serial.println(“ more knocks to go”); } if(numberOfKnocks >= 3){ locked = false; myServo.write(0); delay(20); digitalWrite(greenLed,HIGH); digitalWrite(redLed,LOW); Serial.println(“The box is unlocked!”); } } } boolean checkForKnock(int value){
Ця конкретна функція перевірятиме число (вашу змінну knockVal), щоб побачити, чи воно дійсне чи ні. Щоб передати цю змінну функції, ви створюєте іменований параметр під час оголошення функції.
Перевірте правильність удару. У функції, кожного разу, коли використовується value, воно прийматиме значення, яке передається з основної програми. На цьому етапі value буде рівне knockVal. Перевірте, чи значення більше, ніж мінімальний поріг удару (
quietKnock
), і менше, ніж максимальний поріг (loudKnock
).
Якщо значення знаходиться у допустимому діапазоні, удар вважається правильним. Увімкніть жовтий світлодіод, зачекайте короткий момент, після чого вимкніть його. Виведіть значення удару в серійний монітор.
Щоб основна програма отримала результат перевірки, використовуйте команду return. Виконання функції завершується після
return
, і вона повертає true у програму.
Якщо значення не входить у встановлений діапазон (тобто удар занадто тихий або гучний), виведіть його у серійний монітор та поверніть false. Закрийте функцію фігурною дужкою.
Після підключення схеми до Arduino, відкрийте серійний монітор. Ви побачите, що зелений світлодіод засвітиться, а серводвигун перейде у розблоковане положення. У серійному моніторі з’явиться повідомлення: “The box is unlocked!”.
Коли п’єзоелемент вперше отримує живлення, ви можете почути легкий клац. Спробуйте постукати тихо та голосно, щоб перевірити, які удари активують функцію розпізнавання.
Якщо все працює правильно:
Жовтий світлодіод блимне при отриманні правильного удару.
У серійному моніторі з’явиться повідомлення із значенням сили удару.
Також буде вказано, скільки ударів залишилося до розблокування.
Коли досягнуто необхідної кількості ударів:
Червоний світлодіод згасне.
Зелений світлодіод засвітиться.
Сервомотор повернеться на 90 градусів, відчиняючи замок.
У серійному моніторі з’явиться повідомлення про розблокування.
if(value > quietKnock && value < loudKnock){ digitalWrite(yellowLed, HIGH); delay(50); digitalWrite(yellowLed, LOW); Serial.print(“Valid knock of value “); Serial.println(value); return true; } else { Serial.print(“Bad knock value “); Serial.println(value); return false; } }
Значення для вашого ідеального стуку можуть відрізнятися від наведених у прикладі. Це залежить від ряду різних змінних, наприклад типу поверхні, до якої прикріплено датчик, і того, наскільки міцно він там закріплений. Використовуючи монітор послідовного порту та приклад AnalogInSerialOut у Arduino IDE, знайдіть відповідне значення детонації для вашого налаштування.
Ви можете знайти детальне пояснення цього прикладу тут: arduino.cc/analogtoserial
Якщо ви перемістите проект у коробку, вам потрібно буде зробити отвори для світлодіодів і вимикача. Вам також потрібно буде зробити засувку для обертання серводвигуна. Можливо, також буде корисно мати отвір, через який можна протягнути USB-кабель, щоб дізнатися, наскільки ваше нове середовище чутливе до ударів.
Можливо, вам знадобиться переставити макетну плату та Arduino або припаяти світлодіоди та перемкнути їх, щоб зробити їх доступними ззовні вашого корпусу. Пайка — це процес з’єднання двох або більше металевих компонентів за допомогою клею, який розплавляється між з’єднанням. Якщо ви ніколи раніше не паяли, попросіть когось, хто має досвід, допомогти вам, або спробуйте попрактикуватися на дроті, перш ніж спробувати з іншим пристроєм у цьому проекті. Коли ви паяєте щось, це має бути постійне з’єднання, тож переконайтеся, що це те, що можна зламати. Перегляньте arduino.cc/soldering для гарного пояснення того, як паяти.
Написання власних функцій не тільки дозволяє легше контролювати потік вашого коду, але також допомагає підтримувати його читабельність, оскільки ваші проекти стають все більшими і більшими. Згодом, коли ви будете писати більше коду, ви можете виявити, що у вас є велика кількість функцій, які можна повторно використовувати в різних проектах, що робить процес швидшим і унікальним для вашого стилю програмування.
Цей приклад просто підраховує правильну кількість ударів, незалежно від того, скільки часу це займе. Ви можете почати створювати більш складний приклад, створивши таймер за допомогою millis(). Використовуйте таймер, щоб визначити, чи трапляються стуки в певний період часу.
Зверніть увагу на проект Digital Hourglass, щоб побачити приклад роботи таймера. Ви не обмежені лише пошуком детонацій у певному діапазоні. Ви можете шукати складні моделі стуків на основі сумарної кількості вібрації та часу. В Інтернеті є багато прикладів, які розповідають про те, як це зробити, знайдіть «Arduino knock lock», щоб знайти більше прикладів такого типу проекту.
П’єзоелементи можна використовувати як входи, якщо підключити їх як дільники напруги з резистором високого значення. Розробка функції — це простий спосіб написати код, який можна повторно використовувати для конкретних завдань.