Tambahkan file baru

This commit is contained in:
aidil 2025-08-15 15:52:06 +07:00
parent 28edb0fe1b
commit cc8fe8d30f
4 changed files with 46445 additions and 0 deletions

14
pengusirhama/debug.cfg Normal file
View File

@ -0,0 +1,14 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Example OpenOCD configuration file for ESP32-WROVER-KIT board.
#
# For example, OpenOCD can be started for ESP32 debugging on
#
# openocd -f board/esp32-wrover-kit-3.3v.cfg
#
# Source the JTAG interface configuration file
source [find interface/ftdi/esp32_devkitj_v1.cfg]
set ESP32_FLASH_VOLTAGE 3.3
# Source the ESP32 configuration file
source [find target/esp32.cfg]

View File

@ -0,0 +1,19 @@
{
"name":"Arduino on ESP32",
"toolchainPrefix":"xtensa-esp32-elf",
"svdFile":"esp32.svd",
"request":"attach",
"postAttachCommands":[
"set remote hardware-watchpoint-limit 2",
"monitor reset halt",
"monitor gdb_sync",
"thb setup",
"c"
],
"overrideRestartCommands":[
"monitor reset halt",
"monitor gdb_sync",
"thb setup",
"c"
]
}

46087
pengusirhama/esp32.svd Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,325 @@
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_AMG88xx.h>
#include <Firebase_ESP_Client.h>
#include <ESP32Servo.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <time.h>
// ====== WiFi ======
#define WIFI_SSID "POCO F4"
#define WIFI_PASSWORD "87654321"
// ====== Firebase RTDB ======
#define API_KEY "AIzaSyDgtq_bU0aNjKwErdns50EldaRRSdd5Sg0"
#define DATABASE_URL "https://hamaguard-e911d-default-rtdb.firebaseio.com"
#define USER_EMAIL "test@gmail.com"
#define USER_PASSWORD "123456"
// ====== REST API Endpoint ======
const char* apiEndpoint = "https://service-hama-guard.vercel.app/api/notifikasi";
// ====== Pin ======
#define PIR_PIN 33
#define TRIG_PIN 25
#define ECHO_PIN 26
#define BUZZER_PIN 13
#define SERVO_PIN 32
// ====== Firebase Objects ======
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;
// ====== Sensor & Servo ======
Adafruit_AMG88xx amg;
float pixels[AMG88xx_PIXEL_ARRAY_SIZE];
Servo servo;
// ====== Kalibrasi AMG8833 ======
const float amgOffset = 2,94 ;
// ====== Control Flags ======
bool isAutoMode = true;
bool isRepellerOn = false;
String prevMode = "";
// ====== Timing Control ======
unsigned long lastSensorSend = 0;
unsigned long lastNotifSend = 0;
unsigned long humanBuzzEndTime = 0;
const unsigned long SENSOR_INTERVAL = 1000;
const unsigned long NOTIF_INTERVAL = 5000;
// ====== Repeller Task Control ======
TaskHandle_t repellerTaskHandle = NULL;
bool repellerActive = false;
unsigned long repellerEndTime = 0;
// ====== FreeRTOS Servo Task ======
void repellerTask(void* parameter) {
static int pos = 0;
static bool forward = true;
const int step = 6;
const int delayMs = 10;
while (true) {
if (repellerActive) {
digitalWrite(BUZZER_PIN, HIGH);
servo.write(pos);
if (forward) {
pos += step;
if (pos >= 180) {
pos = 180;
forward = false;
}
} else {
pos -= step;
if (pos <= 0) {
pos = 0;
forward = true;
}
}
vTaskDelay(delayMs / portTICK_PERIOD_MS);
} else {
digitalWrite(BUZZER_PIN, LOW);
servo.write(90);
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
}
void setupTime() {
configTime(7 * 3600, 0, "pool.ntp.org", "time.nist.gov");
Serial.print("Sinkronisasi waktu NTP");
while (time(nullptr) < 8 * 3600 * 2) {
delay(500);
Serial.print(".");
}
Serial.println("");
}
String getISO8601Timestamp() {
time_t now = time(nullptr);
struct tm timeinfo;
localtime_r(&now, &timeinfo);
char buf[30];
strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%z", &timeinfo);
return String(buf);
}
void setup() {
Serial.begin(115200);
delay(500);
Serial.print("Menghubungkan ke WiFi");
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
int retry = 0;
while (WiFi.status() != WL_CONNECTED && retry < 20) {
delay(500);
Serial.print(".");
retry++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("");
Serial.println("WiFi terhubung ke: " + String(WiFi.SSID()));
Serial.println("IP Address: " + WiFi.localIP().toString());
} else {
Serial.println("");
Serial.println("Gagal terhubung ke WiFi. Periksa SSID/Password.");
}
setupTime();
config.api_key = API_KEY;
config.database_url = DATABASE_URL;
auth.user.email = USER_EMAIL;
auth.user.password = USER_PASSWORD;
Firebase.begin(&config, &auth);
Firebase.reconnectWiFi(true);
delay(1000);
if (Firebase.ready()) {
Serial.println("Firebase terhubung ✓");
} else {
Serial.println("Firebase tidak terhubung ✗");
}
pinMode(PIR_PIN, INPUT);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
servo.attach(SERVO_PIN);
servo.write(90);
if (!amg.begin()) {
Serial.println("Sensor AMG8833 tidak ditemukan!");
while (1) delay(10);
} else {
Serial.println("Sensor AMG8833 berhasil diinisialisasi.");
}
xTaskCreatePinnedToCore(repellerTask, "RepellerTask", 2048, NULL, 1, &repellerTaskHandle, 1);
Serial.println("Setup selesai. Sistem siap berjalan.");
}
String classifyObject(float distance, float maxTemp, int hotGridCount) {
if ((distance <= 5 && maxTemp >= 41 && hotGridCount >= 9 && hotGridCount <= 14) ||
(distance <= 10 && maxTemp >= 37-39 && hotGridCount >= 3 && hotGridCount <= 4)) {
return "burung";
}
if ((distance <= 5 && maxTemp >= 36 && maxTemp <= 37 && hotGridCount >= 64) ||
((distance >= 10 && distance <= 35) && maxTemp >= 36 && maxTemp <= 28 && hotGridCount >= 12 && hotGridCount <= 30) ||
(distance <= 30 && maxTemp == 35 && hotGridCount >= 15 && hotGridCount <= 20)) {
return "manusia";
}
if (maxTemp >= 36.0) {
return "hama_unknown";
}
return "tidak_terdeteksi";
}
void loop() {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi terputus. Mencoba reconnect...");
WiFi.disconnect();
WiFi.reconnect();
unsigned long startAttemptTime = millis();
while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < 10000) {
delay(500);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi berhasil terhubung kembali!");
} else {
Serial.println("\nGagal reconnect ke WiFi.");
}
}
unsigned long now = millis();
if (Firebase.RTDB.getString(&fbdo, "/control/mode")) {
String mode = fbdo.stringData();
isAutoMode = (mode == "auto");
if (mode != prevMode) {
sendModeChangeNotification(isAutoMode ? "Otomatis" : "Manual");
prevMode = mode;
}
}
if (Firebase.RTDB.getBool(&fbdo, "/control/repeller")) {
isRepellerOn = fbdo.boolData();
}
if (!isAutoMode) {
repellerActive = isRepellerOn;
return;
}
amg.readPixels(pixels);
float maxTemp = -100;
int hotGridCount = 0;
for (int i = 0; i < AMG88xx_PIXEL_ARRAY_SIZE; i++) {
pixels[i] += amgOffset;
if (pixels[i] > maxTemp) maxTemp = pixels[i];
if (pixels[i] > 23.0) hotGridCount++;
}
bool pirDetected = digitalRead(PIR_PIN) == HIGH;
digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);
float distance_cm = duration * 0.034 / 2.0;
String jenis = classifyObject(distance_cm, maxTemp, hotGridCount);
bool classified = (jenis != "tidak_terdeteksi");
// === Logika pengusir berdasarkan klasifikasi ===
if (pirDetected || jenis == "burung" || jenis == "ayam" || jenis == "hama_unknown") {
repellerActive = true;
repellerEndTime = millis() + 10000;
} else if (jenis == "manusia") {
repellerActive = false;
digitalWrite(BUZZER_PIN, HIGH);
humanBuzzEndTime = millis() + 10000;
}
if (repellerActive && millis() > repellerEndTime) {
repellerActive = false;
}
if (jenis == "manusia" && millis() > humanBuzzEndTime) {
digitalWrite(BUZZER_PIN, LOW);
}
if (now - lastSensorSend >= SENSOR_INTERVAL) {
sendSensorData(pirDetected, distance_cm, jenis, maxTemp);
lastSensorSend = now;
}
if ((now - lastNotifSend >= NOTIF_INTERVAL) && classified) {
sendNotification(jenis, distance_cm, maxTemp);
lastNotifSend = now;
}
}
void sendSensorData(bool pir, float dist, String jenis, float maxTemp) {
if (!Firebase.ready()) return;
FirebaseJson sensorJson;
sensorJson.set("pir", pir);
sensorJson.set("ultrasonik", dist);
sensorJson.set("jenis_deteksi", jenis);
sensorJson.set("pengusir", (jenis != "tidak_terdeteksi"));
sensorJson.set("timestamp", millis());
FirebaseJson thermalJson;
FirebaseJsonArray arr;
for (int i = 0; i < AMG88xx_PIXEL_ARRAY_SIZE; i++) arr.add(pixels[i]);
thermalJson.set("temperatures", arr);
thermalJson.set("timestamp", millis());
Firebase.RTDB.setJSON(&fbdo, "/sensor", &sensorJson);
Firebase.RTDB.setJSON(&fbdo, "/thermal_data", &thermalJson);
}
void sendNotification(String jenis, float distance, float suhu) {
HTTPClient http;
http.begin(apiEndpoint);
http.addHeader("Content-Type", "application/json");
DynamicJsonDocument json(512);
json["type"] = "warning";
json["title"] = "Deteksi " + jenis;
json["message"] = "Terdeteksi " + jenis + " pada jarak " + String(distance, 1) + " cm dan suhu maksimum " + String(suhu, 1) + "°C";
json["timestamp"] = getISO8601Timestamp();
String requestBody;
serializeJson(json, requestBody);
http.POST(requestBody);
http.end();
}
void sendModeChangeNotification(String mode) {
HTTPClient http;
http.begin(apiEndpoint);
http.addHeader("Content-Type", "application/json");
DynamicJsonDocument json(512);
json["type"] = "success";
json["title"] = "Mode Diganti";
json["message"] = "Mode sistem diganti menjadi " + mode;
json["timestamp"] = getISO8601Timestamp();
String body;
serializeJson(json, body);
http.POST(body);
http.end();
}