#include <Arduino.h>
// simulasi kualitas udara saat ini menggunakan button untuk menggantikan
// sensor MQ-135 (karena di wokwi tidak ada). saat button di tekan menandakan
// sensor MQ-135 deteksi gas (misal alkohol) maka kipas 1 akan aktif.
// ada tombol untuk kill task sensor (ditekan selama 5 detik) bila kualitas
// udara sangat tidak baik (emergency button) dan mengkatifkan semua kipas
// (menggunakan relay) yang awalnya satu menjadi tiga. untuk pengiriman peringatan
// saat ini masih di serial monitor namun untuk berikutnya akan ada dua yaitu di
// LED display dan peringatan ke aplikasi IoT seperti Blynk.
// untuk kondisi normal (lokail di LED Display) peringatan muncul
// "tidak ada alkohol" dan "alkohol terdeteksi!"
// untuk keaadaan darurat peringatan normal di ganti dengan
// "Kondisi alkohol di ruangan sangat berbahaya!" dikirim ke aplikasi IoT
// untuk sensor MQ-135 dapat mendeteksi: Amonia(NH3), Nitrogen Oksida (NOx),
// Sulfur (SO2), Karbon Monoksida (CO), Ethanol (C2H2O), gas LPG dan sebagainya.
// saat ini yang terpenuhi dari 5 poin dari tugas besar adalah poin 1 (ada 4 task)
// dan poin 3 (kill task)
// link project di wokwi: https://wokwi.com/projects/415869754006406145
// Pin deklarasi
const int BUTTON_SENSOR_PIN = 14; // Tombol sensor alkohol
const int BUTTON_KILL_PIN = 12; // Tombol kill task
const int RELAY1_PIN = 18; // Relay untuk kipas 1
const int RELAY2_PIN = 17; // Relay untuk kipas 2
const int RELAY3_PIN = 16; // Relay untuk kipas 3
const int BUZZER_PIN = 19; // Pin buzzer
// Variabel global
volatile bool alcoholDetected = false; // Status alkohol
volatile bool emergencyMode = false; // Mode darurat
TaskHandle_t sensorTaskHandle = NULL; // Handle task sensor
void readButtonTask(void *pvParameters) {
while (1) {
// Membaca status tombol sensor
int buttonState = digitalRead(BUTTON_SENSOR_PIN);
if (!emergencyMode) { // Hanya bekerja di mode normal
if (buttonState == LOW) { // Tombol ditekan
alcoholDetected = true;
Serial.println("Alkohol terdeteksi!");
} else {
alcoholDetected = false;
Serial.println("Tidak ada alkohol.");
}
}
// Delay untuk Round Robin
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void relayControlTask(void *pvParameters) {
while (1) {
if (emergencyMode) { // Mode darurat
digitalWrite(RELAY1_PIN, HIGH);
digitalWrite(RELAY2_PIN, HIGH);
digitalWrite(RELAY3_PIN, HIGH);
} else { // Mode normal
digitalWrite(RELAY1_PIN, alcoholDetected ? HIGH : LOW);
digitalWrite(RELAY2_PIN, LOW);
digitalWrite(RELAY3_PIN, LOW);
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void buzzerControlTask(void *pvParameters) {
while (1) {
if (emergencyMode) { // Buzzer aktif dalam mode darurat
digitalWrite(BUZZER_PIN, HIGH);
} else { // Buzzer mati dalam mode normal
digitalWrite(BUZZER_PIN, LOW);
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void killTaskHandler(void *pvParameters) {
int buttonPressTime = 0; // Waktu tombol ditekan
while (1) {
int buttonState = digitalRead(BUTTON_KILL_PIN);
if (buttonState == LOW) { // Tombol ditekan
buttonPressTime += 100; // Tambahkan waktu tekan
if (buttonPressTime >= 5000 && !emergencyMode) { // Jika tombol ditekan selama 5 detik
Serial.println("Kondisi alkohol di ruangan sangat berbahaya!");
emergencyMode = true; // Masuk mode darurat
// Kill task sensor
if (sensorTaskHandle != NULL) {
vTaskDelete(sensorTaskHandle);
sensorTaskHandle = NULL;
}
}
} else { // Tombol tidak ditekan
buttonPressTime = 0; // Reset waktu tekan
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void setup() {
// Inisialisasi pin
pinMode(BUTTON_SENSOR_PIN, INPUT_PULLUP);
pinMode(BUTTON_KILL_PIN, INPUT_PULLUP);
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
pinMode(RELAY3_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
// Serial monitor untuk debugging
Serial.begin(115200);
Serial.println("Sistem Deteksi Alkohol dengan Kill Task");
// Membuat task RTOS
xTaskCreate(readButtonTask, "Read Button", 1000, NULL, 1, &sensorTaskHandle);
xTaskCreate(relayControlTask, "Relay Control", 1000, NULL, 1, NULL);
xTaskCreate(buzzerControlTask, "Buzzer Control", 1000, NULL, 1, NULL);
xTaskCreate(killTaskHandler, "Kill Task Handler", 1000, NULL, 1, NULL);
}
void loop() {
// Tidak digunakan, semua tugas berjalan pada RTOS
}