Sebelum nya saya mau kasi informasi bahwa project yang di share sekarang bisa kalian coba di software arduino terbaru tanpa perlu adanya library tambahan lagi.
Alat yang akan saya share disini sebenarnya sudah pernah dibuat layout nya pada tahun 2011 namun berhubung saya mendapatkan sponsor lagi dari JLCPCB.COM akhirnya saya cetak ulang PCB nya dengan design yang lebih unik lagi.
Untuk membuat Alat Kunci Ketuk Pintu Digital Sebenarnya bisa dilakukan dengan hanya menggunakan board arduino apapun. Salah satunya adalah arduino uno.
Alat dan Bahan
Adapun alat dan bahan dasar yang kamu perlukan adalah
- Arduino uno
- Piezoelectric
- Modul relay
- Kabel Jumper
- Doorlock digital
Gambar Rangkaian
Dari gambar rangkaian tersebut saya membuat design PCB pengganti dengan menggunakan software Eagle PCB.
Skematik
Layout PCB
Nah untu coding nya kalian bisa copy dibawah pada tempat yang sudah diberikan di akhir dari artikel ini.
Jika kalian merasa artikel ini bermanfaat silahkan share dan informasikan ke teman teman kalian yang membutuhkan project ini.
#include <EEPROM.h>
const byte eepromValid = 123;
const int programButton = 4;
const int ledPin = 5;
const int knockSensor = 0;
const int audioOut = 8;
const int lockPin = 7;
int threshold = 3;
const int rejectValue = 25;
const int averageRejectValue = 15;
const int knockFadeTime = 150;
const int lockOperateTime = 2500;
const int maximumKnocks = 20;
const int knockComplete = 1200;
byte secretCode[maximumKnocks] = {50, 25, 25, 50, 100, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Initial setup: "Shave and a Hair Cut, two bits."
int knockReadings[maximumKnocks];
int knockSensorValue = 0;
boolean programModeActive = false;
void setup() {
pinMode(programButton,INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
pinMode(lockPin, OUTPUT);
readSecretKnock();
doorUnlock(500);
delay(500);
}
void loop() {
knockSensorValue = analogRead(knockSensor);
if (digitalRead(programButton) == LOW){
delay(100);
if (digitalRead(programButton) == LOW){
if (programModeActive == false){
programModeActive = true;
digitalWrite(ledPin, HIGH);
chirp(500, 1500);
chirp(500, 1000);
} else {
programModeActive = false;
digitalWrite(ledPin, LOW);
chirp(500, 1000);
chirp(500, 1500);
delay(500);
}
while (digitalRead(programButton) == LOW){
delay(10);
}
}
delay(250);
}
if (knockSensorValue >= threshold){
if (programModeActive == true){
digitalWrite(ledPin, LOW);
} else {
digitalWrite(ledPin, HIGH);
}
knockDelay();
if (programModeActive == true){
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}
listenToSecretKnock();
}
}
void listenToSecretKnock(){
int i = 0;
for (i=0; i < maximumKnocks; i++){
knockReadings[i] = 0;
}
int currentKnockNumber = 0;
int startTime = millis();
int now = millis();
do {
knockSensorValue = analogRead(knockSensor);
if (knockSensorValue >= threshold){
now=millis();
knockReadings[currentKnockNumber] = now - startTime;
currentKnockNumber ++;
startTime = now;
if (programModeActive==true){
digitalWrite(ledPin, LOW);
} else {
digitalWrite(ledPin, HIGH);
}
knockDelay();
if (programModeActive == true){
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}
}
now = millis();
} while ((now-startTime < knockComplete) && (currentKnockNumber < maximumKnocks));
if (programModeActive == false){
if (validateKnock() == true){
doorUnlock(lockOperateTime);
} else {
for (i=0; i < 4; i++){
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
}
}
} else {
validateKnock();
}
}
void doorUnlock(int delayTime){
digitalWrite(ledPin, HIGH);
digitalWrite(lockPin, HIGH);
delay(delayTime);
digitalWrite(lockPin, LOW);
digitalWrite(ledPin, LOW);
delay(500);
}
boolean validateKnock(){
int i = 0;
int currentKnockCount = 0;
int secretKnockCount = 0;
int maxKnockInterval = 0;
for (i=0;i<maximumKnocks;i++){
if (knockReadings[i] > 0){
currentKnockCount++;
}
if (secretCode[i] > 0){
secretKnockCount++;
}
if (knockReadings[i] > maxKnockInterval){
maxKnockInterval = knockReadings[i];
}
}
if (programModeActive == true){
for (i=0; i < maximumKnocks; i++){
secretCode[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100);
}
saveSecretKnock();
programModeActive = false;
playbackKnock(maxKnockInterval);
return false;
}
if (currentKnockCount != secretKnockCount){
return false;
}
int totaltimeDifferences = 0;
int timeDiff = 0;
for (i=0; i < maximumKnocks; i++){
knockReadings[i]= map(knockReadings[i], 0, maxKnockInterval, 0, 100);
timeDiff = abs(knockReadings[i] - secretCode[i]);
if (timeDiff > rejectValue){
return false;
}
totaltimeDifferences += timeDiff;
}
if (totaltimeDifferences / secretKnockCount > averageRejectValue){
return false;
}
return true;
}
void readSecretKnock(){
byte reading;
int i;
reading = EEPROM.read(0);
if (reading == eepromValid){
for (int i=0; i < maximumKnocks ;i++){
secretCode[i] = EEPROM.read(i+1);
}
}
}
void saveSecretKnock(){
EEPROM.write(0, 0);
for (int i=0; i < maximumKnocks; i++){
EEPROM.write(i+1, secretCode[i]);
}
EEPROM.write(0, eepromValid);
}
void playbackKnock(int maxKnockInterval){
digitalWrite(ledPin, LOW);
delay(1000);
digitalWrite(ledPin, HIGH);
chirp(200, 1800);
for (int i = 0; i < maximumKnocks ; i++){
digitalWrite(ledPin, LOW);
if (secretCode[i] > 0){
delay(map(secretCode[i], 0, 100, 0, maxKnockInterval));
digitalWrite(ledPin, HIGH);
chirp(200, 1800);
}
}
digitalWrite(ledPin, LOW);
}
void knockDelay(){
int itterations = (knockFadeTime / 20);
for (int i=0; i < itterations; i++){
delay(10);
analogRead(knockSensor);
delay(10);
}
}
void chirp(int playTime, int delayTime){
long loopTime = (playTime * 1000L) / delayTime;
pinMode(audioOut, OUTPUT);
for(int i=0; i < loopTime; i++){
digitalWrite(audioOut, HIGH);
delayMicroseconds(delayTime);
digitalWrite(audioOut, LOW);
}
pinMode(audioOut, INPUT);
}
Untuk referensi coding tentang pembacaan nilai adc piezoelectric semua diperoleh dari adadruit.