Upload files to "Kode Program Arduino"
This commit is contained in:
parent
ba707ecd26
commit
f2a8ec3066
|
@ -0,0 +1,423 @@
|
|||
#include <Keypad.h>
|
||||
#include <BluetoothSerial.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <EEPROM.h>
|
||||
#include <WiFi.h>
|
||||
#include <WebServer.h>
|
||||
#include <NTPClient.h>
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
// Deklarasi objek
|
||||
BluetoothSerial SerialBT;
|
||||
WebServer server(80);
|
||||
WiFiUDP ntpUDP;
|
||||
NTPClient timeClient(ntpUDP, "pool.ntp.org", 25200, 60000); // Waktu WIB (UTC +7)
|
||||
|
||||
// Konfigurasi WiFi
|
||||
const char* ssid = "realme XT";
|
||||
const char* password = "dimasdwi01";
|
||||
|
||||
// Konfigurasi keypad
|
||||
const byte ROWS = 4; // Empat baris pada keypad
|
||||
const byte COLS = 3; // Tiga kolom pada keypad
|
||||
char keys[ROWS][COLS] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'*','0','#'}
|
||||
};
|
||||
byte rowPins[ROWS] = {15, 2, 0, 4}; // Pin yang terhubung ke baris keypad
|
||||
byte colPins[COLS] = {16, 17, 5}; // Pin yang terhubung ke kolom keypad
|
||||
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
|
||||
|
||||
// Variabel global
|
||||
char btAddress[18];
|
||||
String btAddressStr = "";
|
||||
const int EEPROM_SIZE = 512;
|
||||
const int EEPROM_SLOT_SIZE = 50; // Ukuran slot di EEPROM
|
||||
const char* adminAddress = "9C:6B:72:57:0C:10";
|
||||
const int doorControlPin = 12;
|
||||
const int buzzerPin = 25;
|
||||
const int buttonPin = 18;
|
||||
const int magneticSwitchPin = 32;
|
||||
bool buzzerSounding = false;
|
||||
unsigned long buzzerStartTime = 0;
|
||||
unsigned long buzzerDuration = 0;
|
||||
bool previousDoorStatus = HIGH;
|
||||
bool currentDoorStatus = HIGH;
|
||||
String doorOpenerName;
|
||||
String doorOpenerAddress;
|
||||
String enteredCode = "";
|
||||
String activityLog = ""; // String untuk menyimpan log aktivitas
|
||||
unsigned long lastKeyPressTime = 0; // Waktu terakhir tombol ditekan
|
||||
const unsigned long keyPressTimeout = 5000; // Timeout 5 detik
|
||||
|
||||
// Memindai apakah perangkat Bluetooth ada
|
||||
void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) {
|
||||
if (event == ESP_SPP_SRV_OPEN_EVT) {
|
||||
Serial.println("Client mencoba terhubung dengan alamat:");
|
||||
memset(btAddress, 0, sizeof(btAddress));
|
||||
byte c = 0;
|
||||
byte v, v1, v2;
|
||||
const char hx[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Serial.printf("%02X", param->srv_open.rem_bda[i]);
|
||||
v = param->srv_open.rem_bda[i];
|
||||
v1 = v & 0xF;
|
||||
v2 = (v >> 4) & 0xF;
|
||||
btAddress[c] = hx[v2];
|
||||
c++;
|
||||
btAddress[c] = hx[v1];
|
||||
c++;
|
||||
if (i < 5) {
|
||||
Serial.print(":");
|
||||
btAddress[c] = ':';
|
||||
c++;
|
||||
}
|
||||
}
|
||||
btAddressStr = btAddress;
|
||||
Serial.println();
|
||||
Serial.print("Alamat: ");
|
||||
Serial.println(btAddressStr);
|
||||
|
||||
if (btAddressStr == adminAddress) {
|
||||
Serial.println("Admin terhubung.");
|
||||
logActivity("Admin terhubung", btAddressStr, true);
|
||||
soundBuzzer(2, 100);
|
||||
sendIPAddress();
|
||||
} else {
|
||||
int addr = findDeviceSlot(btAddressStr.c_str());
|
||||
if (addr >= 0) {
|
||||
String record = EEPROM.readString(addr);
|
||||
if (record != "") {
|
||||
doorOpenerName = record.substring(0, record.indexOf(',')); // Nama perangkat pembuka pintu
|
||||
doorOpenerAddress = btAddressStr; // Gunakan alamat perangkat yang terhubung
|
||||
Serial.println("Client terhubung.");
|
||||
Serial.print("Stored record: ");
|
||||
Serial.println(record);
|
||||
Serial.print("Nama perangkat: ");
|
||||
Serial.println(doorOpenerName);
|
||||
Serial.print("Alamat perangkat: ");
|
||||
Serial.println(doorOpenerAddress);
|
||||
logActivity(doorOpenerName + " terhubung", doorOpenerAddress, true);
|
||||
soundBuzzer(2, 100);
|
||||
sendIPAddress();
|
||||
} else {
|
||||
Serial.println("Client tidak diizinkan untuk terhubung.");
|
||||
SerialBT.disconnect();
|
||||
logActivity("Client tidak diizinkan untuk terhubung", btAddressStr, true);
|
||||
soundBuzzer(1, 1000);
|
||||
}
|
||||
} else {
|
||||
Serial.println("Client tidak diizinkan untuk terhubung.");
|
||||
SerialBT.disconnect();
|
||||
logActivity("Client tidak diizinkan untuk terhubung", btAddressStr, true);
|
||||
soundBuzzer(1, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Kode komunikasi diinisialisasi, pin diatur sebagai input atau output, EEPROM mulai berjalan
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
pinMode(doorControlPin, OUTPUT);
|
||||
digitalWrite(doorControlPin, LOW);
|
||||
pinMode(buzzerPin, OUTPUT);
|
||||
pinMode(buttonPin, INPUT_PULLUP);
|
||||
pinMode(magneticSwitchPin, INPUT_PULLUP);
|
||||
SerialBT.register_callback(callback);
|
||||
if (!SerialBT.begin("Door Lock")) {
|
||||
Serial.println("Terjadi kesalahan saat menginisialisasi Bluetooth");
|
||||
} else {
|
||||
Serial.println("Bluetooth terinisialisasi");
|
||||
}
|
||||
|
||||
WiFi.begin(ssid, password);
|
||||
unsigned long startAttemptTime = millis();
|
||||
while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < 10000) {
|
||||
delay(100);
|
||||
Serial.print(".");
|
||||
}
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
Serial.println("WiFi terhubung");
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
server.on("/", handleRoot);
|
||||
server.begin();
|
||||
timeClient.begin();
|
||||
} else {
|
||||
Serial.println("Koneksi WiFi gagal, melanjutkan operasi offline.");
|
||||
}
|
||||
}
|
||||
// Menambahkan dan Menghapus Perangkat
|
||||
void loop() {
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
server.handleClient();
|
||||
timeClient.update();
|
||||
}
|
||||
|
||||
if (SerialBT.available()) {
|
||||
String incomingData = "";
|
||||
while (SerialBT.available()) {
|
||||
incomingData += char(SerialBT.read());
|
||||
}
|
||||
Serial.print("Data diterima: ");
|
||||
Serial.println(incomingData);
|
||||
StaticJsonDocument<200> doc;
|
||||
DeserializationError error = deserializeJson(doc, incomingData);
|
||||
if (error) {
|
||||
Serial.print(F("deserializeJson() gagal: "));
|
||||
Serial.println(error.f_str());
|
||||
return;
|
||||
}
|
||||
const char* action = doc["action"];
|
||||
const char* name = doc["name"];
|
||||
const char* address = doc["address"];
|
||||
const char* password = doc["password"];
|
||||
if (btAddressStr == adminAddress) {
|
||||
if (strcmp(action, "add") == 0) {
|
||||
addDevice(name, address, password);
|
||||
logActivity(String(name) + ", " + address + " ditambahkan", "", false);
|
||||
} else if (strcmp(action, "delete") == 0) {
|
||||
deleteDevice(address, name);
|
||||
}
|
||||
} else {
|
||||
int addr = findDeviceSlot(btAddressStr.c_str());
|
||||
if (addr >= 0) {
|
||||
if (strcmp(action, "open_door") == 0) {
|
||||
openDoor(doorOpenerName.c_str(), doorOpenerAddress.c_str()); // Gunakan nama dan alamat perangkat yang terhubung
|
||||
} else if (strcmp(action, "close_door") == 0) {
|
||||
closeDoor();
|
||||
}
|
||||
} else {
|
||||
Serial.println("Client tidak diizinkan untuk mengontrol pintu.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (digitalRead(buttonPin) == LOW) {
|
||||
openDoorWithButton();
|
||||
}
|
||||
if (buzzerSounding && millis() - buzzerStartTime >= buzzerDuration) {
|
||||
digitalWrite(buzzerPin, LOW);
|
||||
buzzerSounding = false;
|
||||
}
|
||||
currentDoorStatus = digitalRead(magneticSwitchPin);
|
||||
if (currentDoorStatus != previousDoorStatus) {
|
||||
previousDoorStatus = currentDoorStatus;
|
||||
}
|
||||
|
||||
handleKeypadEntry();
|
||||
}
|
||||
|
||||
void addDevice(const char* name, const char* address, const char* password) {
|
||||
Serial.print("Menambahkan perangkat dengan nama: ");
|
||||
Serial.print(name);
|
||||
Serial.print(", alamat: ");
|
||||
Serial.print(address);
|
||||
Serial.print(", dan password: ");
|
||||
Serial.println(password);
|
||||
if (findDeviceSlot(address) == -1) {
|
||||
int addr = findEmptySlot();
|
||||
if (addr != -1) {
|
||||
String record = String(name) + "," + String(address) + "," + String(password);
|
||||
EEPROM.writeString(addr, record);
|
||||
EEPROM.commit();
|
||||
Serial.println("Perangkat ditambahkan ke EEPROM.");
|
||||
} else {
|
||||
Serial.println("EEPROM penuh, tidak dapat menambahkan perangkat.");
|
||||
}
|
||||
} else {
|
||||
Serial.println("Perangkat dengan alamat ini sudah ada.");
|
||||
}
|
||||
}
|
||||
|
||||
void deleteDevice(const char* address, const char* name) {
|
||||
Serial.print("Menghapus perangkat dengan alamat: ");
|
||||
Serial.println(address);
|
||||
int addr = findDeviceSlot(address);
|
||||
if (addr != -1) {
|
||||
EEPROM.writeString(addr, "");
|
||||
EEPROM.commit();
|
||||
Serial.println("Perangkat dihapus dari EEPROM.");
|
||||
logActivity(String(name) + " dihapus", address, true);
|
||||
} else {
|
||||
Serial.println("Perangkat tidak ditemukan di EEPROM.");
|
||||
}
|
||||
}
|
||||
|
||||
void openDoor(const char* name, const char* address) {
|
||||
Serial.println(String(name) + " membuka pintu.");
|
||||
Serial.print("Nama perangkat: ");
|
||||
Serial.println(name);
|
||||
Serial.print("Alamat perangkat: ");
|
||||
Serial.println(address);
|
||||
digitalWrite(doorControlPin, HIGH);
|
||||
delay(5000);
|
||||
digitalWrite(doorControlPin, LOW);
|
||||
logActivity(String(name) + " membuka pintu", address, true);
|
||||
}
|
||||
|
||||
void openDoorWithButton() {
|
||||
Serial.println("Pintu dibuka dengan tombol.");
|
||||
digitalWrite(doorControlPin, HIGH);
|
||||
delay(5000);
|
||||
digitalWrite(doorControlPin, LOW);
|
||||
logActivity("Pintu dibuka dengan tombol", "", false);
|
||||
}
|
||||
|
||||
void closeDoor() {
|
||||
Serial.println("Pintu ditutup");
|
||||
digitalWrite(doorControlPin, LOW);
|
||||
}
|
||||
//pengecekan data
|
||||
bool isCodeValid(const String& code) {
|
||||
for (int addr = 0; addr < EEPROM_SIZE; addr += EEPROM_SLOT_SIZE) {
|
||||
String record = EEPROM.readString(addr);
|
||||
if (record != "") {
|
||||
int lastCommaIndex = record.lastIndexOf(',');
|
||||
if (lastCommaIndex != -1) {
|
||||
String storedCode = record.substring(lastCommaIndex + 1);
|
||||
if (storedCode == code) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void logActivity(String name, String address, bool includeConnected) {
|
||||
time_t rawTime = timeClient.getEpochTime();
|
||||
struct tm * timeInfo = localtime(&rawTime);
|
||||
char timeBuffer[20];
|
||||
strftime(timeBuffer, sizeof(timeBuffer), "%H:%M - %d/%m/%Y", timeInfo); // Ubah format waktu untuk menyertakan tanggal lengkap
|
||||
String formattedTime = String(timeBuffer);
|
||||
String logEntry = formattedTime + " - " + name + (includeConnected ? " (" + address + ")" : "");
|
||||
activityLog += "<tr><td>" + formattedTime + "</td><td>" + name + (includeConnected ? " (" + address + ")" : "") + "</td></tr>";
|
||||
Serial.println(logEntry);
|
||||
}
|
||||
// web server
|
||||
void handleRoot() {
|
||||
// Cek status pintu
|
||||
String doorStatus = digitalRead(magneticSwitchPin) == HIGH ? "Terbuka" : "Tertutup"; // Memperbaiki logika status pintu
|
||||
|
||||
String html = "<html><head><title>Log Aktivitas Smart Lock</title>";
|
||||
html += "<style>body{font-family: Arial, sans-serif; text-align: center; background-color: #f4f4f4;} h1{background-color: #4CAF50; color: white; padding: 1em;} table{margin: 1em auto; border-collapse: collapse; width: 80%; background-color: white; box-shadow: 0 2px 3px rgba(0,0,0,0.1);} th, td{border: 1px solid #ddd; padding: 12px; text-align: left;} th{background-color: #4CAF50; color: white;} tr:nth-child(even){background-color: #f2f2f2;} .door-status{position: fixed; top: 10px; right: 10px; font-size: 1.2em; padding: 10px; background-color: #ffeb3b; border: 1px solid #ccc; border-radius: 5px;}</style>";
|
||||
html += "<meta http-equiv='refresh' content='3'></head><body>";
|
||||
html += "<div class='door-status'><strong>Status Pintu: " + doorStatus + "</strong></div>";
|
||||
html += "<h1>Log Aktivitas Smart Lock</h1>";
|
||||
html += "<table><tr><th>Waktu</th><th>Aktivitas</th></tr>";
|
||||
html += activityLog;
|
||||
html += "</table></body></html>";
|
||||
server.send(200, "text/html", html);
|
||||
}
|
||||
// penyimpanan data
|
||||
int findDeviceSlot(const char* address) {
|
||||
for (int addr = 0; addr < EEPROM_SIZE; addr += EEPROM_SLOT_SIZE) {
|
||||
String record = EEPROM.readString(addr);
|
||||
if (record.indexOf(address) != -1) {
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int findEmptySlot() {
|
||||
for (int addr = 0; addr < EEPROM_SIZE; addr += EEPROM_SLOT_SIZE) {
|
||||
String record = EEPROM.readString(addr);
|
||||
if (record == "") {
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void soundBuzzer(int beeps, int duration) {
|
||||
for (int i = 0; i < beeps; i++) {
|
||||
digitalWrite(buzzerPin, HIGH);
|
||||
delay(duration);
|
||||
digitalWrite(buzzerPin, LOW);
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
void handleKeypadEntry() {
|
||||
char key = keypad.getKey();
|
||||
if (key) {
|
||||
lastKeyPressTime = millis(); // Set waktu terakhir tombol ditekan
|
||||
soundBuzzer(1, 100); // Suara buzzer setiap tombol ditekan
|
||||
Serial.print("Keypad input: ");
|
||||
Serial.println(key);
|
||||
if (key == '*') {
|
||||
enteredCode = "";
|
||||
Serial.println("Kode yang dimasukkan direset.");
|
||||
} else if (key == '#') {
|
||||
Serial.println("Memverifikasi kode yang dimasukkan...");
|
||||
Serial.print("Kode yang dimasukkan: ");
|
||||
Serial.println(enteredCode);
|
||||
if (enteredCode.length() == 0 || !isCodeValid(enteredCode)) {
|
||||
Serial.println("Kode salah atau tidak ada perangkat terdaftar.");
|
||||
logActivity("Kode salah atau tidak ada perangkat terdaftar", "", false); // Tambahkan log aktivitas
|
||||
soundBuzzer(1, 1000); // Buzzer berbunyi 1 kali lebih panjang
|
||||
} else {
|
||||
Serial.println("Kode benar.");
|
||||
String deviceName = getDeviceNameByCode(enteredCode);
|
||||
soundBuzzer(2, 100); // Buzzer berbunyi 2 kali
|
||||
openDoorWithKeypad(deviceName.c_str());
|
||||
}
|
||||
enteredCode = "";
|
||||
} else {
|
||||
enteredCode += key;
|
||||
}
|
||||
}
|
||||
|
||||
// Cek apakah waktu timeout tercapai
|
||||
if (millis() - lastKeyPressTime >= keyPressTimeout && enteredCode != "") {
|
||||
Serial.println("Timeout: Kode yang dimasukkan salah.");
|
||||
logActivity("Timeout: Kode yang dimasukkan salah", "", false); // Tambahkan log aktivitas
|
||||
enteredCode = "";
|
||||
soundBuzzer(1, 1000); // Buzzer berbunyi 1 kali lebih panjang
|
||||
}
|
||||
}
|
||||
|
||||
void openDoorWithKeypad(const char* name) {
|
||||
Serial.println(String(name) + " membuka pintu dengan keypad.");
|
||||
digitalWrite(doorControlPin, HIGH);
|
||||
delay(5000);
|
||||
digitalWrite(doorControlPin, LOW);
|
||||
logActivity(String(name) + " membuka pintu dengan keypad", "", false);
|
||||
}
|
||||
//Pengiriman data ke aplikasi
|
||||
String getDeviceNameByCode(const String& code) {
|
||||
for (int addr = 0; addr < EEPROM_SIZE; addr += EEPROM_SLOT_SIZE) {
|
||||
String record = EEPROM.readString(addr);
|
||||
if (record != "") {
|
||||
int lastCommaIndex = record.lastIndexOf(',');
|
||||
if (lastCommaIndex != -1) {
|
||||
String storedCode = record.substring(lastCommaIndex + 1);
|
||||
if (storedCode == code) {
|
||||
int firstCommaIndex = record.indexOf(',');
|
||||
if (firstCommaIndex != -1) {
|
||||
return record.substring(0, firstCommaIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "Pengguna tidak dikenal";
|
||||
}
|
||||
|
||||
// Function to send the IP address to the connected Bluetooth client
|
||||
void sendIPAddress() {
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
String ipAddress = WiFi.localIP().toString();
|
||||
String message = "{\"ip\":\"" + ipAddress + "\"}";
|
||||
SerialBT.print(message);
|
||||
Serial.println("IP address sent: " + ipAddress);
|
||||
} else {
|
||||
Serial.println("WiFi not connected, cannot send IP address.");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue