Upload files to "Kode Program Arduino"

This commit is contained in:
Dimas_dwi_A 2024-07-14 14:24:52 +07:00
parent ba707ecd26
commit f2a8ec3066
1 changed files with 423 additions and 0 deletions

View File

@ -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.");
}
}