commit 72a9519df87012a276c68cf75d5d4c17d9becf8e Author: irsyadrosidi Date: Wed Jul 30 14:36:15 2025 +0700 Add Tugas Akhir monitoring suhu berbasis IOT diff --git a/Tugas Akhir monitoring suhu berbasis IOT b/Tugas Akhir monitoring suhu berbasis IOT new file mode 100644 index 0000000..92ef3a8 --- /dev/null +++ b/Tugas Akhir monitoring suhu berbasis IOT @@ -0,0 +1,368 @@ +#include +#include +#include +#include +#include + +// Konfigurasi LCD +LiquidCrystal_I2C lcd(0x27, 16, 2); + +// Konfigurasi DHT11 +#define DHTPIN 2 // GPIO2 (D4) +#define DHTTYPE DHT11 +DHT dht(DHTPIN, DHTTYPE); + +// Konfigurasi MQ135 +#define MQ135_PIN A0 +float R0 = 76.63; // Nilai default, akan dikalibrasi ulang + +// Konfigurasi Buzzer dan LED +#define BUZZER_PIN 12 // GPIO12 (D6) +#define LED_PIN 14 // GPIO14 (D5) - Pin untuk LED indikator (diubah ke D5) +#define CO2_THRESHOLD 90 // Threshold CO2 dalam ppm +#define TEMP_THRESHOLD 30 // Threshold suhu dalam °C +#define HUMID_THRESHOLD 80 // Threshold kelembaban dalam % + +// Konfigurasi WiFi dan MQTT +const char* ssid = "SKK - STUDENT"; +const char* password = ""; +const char* mqtt_server = "103.124.138.170"; +const int mqtt_port = 1883; +const char* mqtt_user = "USER_MQTT"; +const char* mqtt_pass = "PASS_MQTT"; +const char* topic_temp = "sensor/temperature"; +const char* topic_humid = "sensor/humidity"; +const char* topic_co2 = "sensor/co2"; +const char* topic_control = "sensor/control"; +const char* topic_status = "sensor/status"; +const char* topic_alert = "sensor/alert"; + +WiFiClient espClient; +PubSubClient client(espClient); + +// Variabel status sistem +bool systemEnabled = true; +unsigned long lastSensorUpdate = 0; +const long sensorInterval = 60000; // Interval pengiriman data sensor (ms) + +void setup_wifi() { + delay(10); + Serial.println(); + Serial.print("Connecting to "); + Serial.println(ssid); + + WiFi.begin(ssid, password); + + lcd.clear(); + lcd.print("Connecting WiFi"); + + while (WiFi.status() != WL_CONNECTED) { + for(int i=0; i<10; i++) { + delay(500); + Serial.print("."); + lcd.print("."); + } + lcd.clear(); + lcd.print("Retrying WiFi..."); + } + + Serial.println(""); + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + + lcd.clear(); + lcd.print("WiFi Connected"); + lcd.setCursor(0, 1); + lcd.print(WiFi.localIP()); + delay(2000); +} + +void reconnect() { + while (!client.connected()) { + Serial.print("Attempting MQTT connection..."); + + if (client.connect("ESP8266Client", mqtt_user, mqtt_pass)) { + Serial.println("connected"); + client.subscribe(topic_control); + Serial.println("Subscribed to control topic"); + client.publish(topic_status, systemEnabled ? "ON" : "OFF", true); + } else { + Serial.print("failed, rc="); + Serial.print(client.state()); + Serial.println(" try again in 5 seconds"); + + lcd.clear(); + lcd.print("MQTT Fail"); + lcd.setCursor(0, 1); + lcd.print("Retrying..."); + + delay(5000); + } + } +} + +void callback(char* topic, byte* payload, unsigned int length) { + Serial.print("Message arrived ["); + Serial.print(topic); + Serial.print("] "); + + char message[length+1]; + for (int i = 0; i < length; i++) { + message[i] = (char)payload[i]; + } + message[length] = '\0'; + Serial.println(message); + + if (String(topic) == topic_control) { + if (strcmp(message, "ON") == 0) { + systemEnabled = true; + noTone(BUZZER_PIN); // Matikan buzzer saat sistem dihidupkan + digitalWrite(LED_PIN, LOW); // Matikan LED + lcd.clear(); + lcd.print("System ON"); + client.publish(topic_status, "ON", true); + Serial.println("System turned ON"); + delay(1000); + } + else if (strcmp(message, "OFF") == 0) { + systemEnabled = false; + noTone(BUZZER_PIN); // Matikan buzzer saat sistem dimatikan + digitalWrite(LED_PIN, LOW); // Matikan LED + lcd.clear(); + lcd.print("System OFF"); + client.publish(topic_status, "OFF", true); + Serial.println("System turned OFF"); + delay(1000); + } + } +} +//mengubah waktu kalibrasi +void calibrateR0() { + if (!systemEnabled) return; + + Serial.println("Kalibrasi MQ135 dimulai..."); + lcd.clear(); + lcd.print("Kalibrasi MQ135"); + lcd.setCursor(0, 1); + lcd.print("Udara bersih 5m"); + //rubah pada waktu 300 + for(int i = 0; i < 300; i++) { + delay(1000); + if(i % 30 == 0) { + Serial.print("."); + lcd.print("."); + } + if (!systemEnabled) { + Serial.println("Kalibrasi dibatalkan!"); + lcd.clear(); + lcd.print("Kalibrasi"); + lcd.setCursor(0, 1); + lcd.print("Dibatalkan"); + delay(2000); + return; + } + } + + Serial.println("\nMengambil sampel..."); + float sum = 0; + int validReadings = 0; + + for (int i = 0; i < 100; i++) { + int rawValue = analogRead(MQ135_PIN); + if(rawValue < 50 || rawValue > 1000) { + continue; + } + + float sensor_volt = rawValue * (3.3 / 1023.0); + float RS_air = (3.3 - sensor_volt) / sensor_volt; + sum += RS_air; + validReadings++; + delay(100); + + if (!systemEnabled) { + Serial.println("Kalibrasi dibatalkan!"); + lcd.clear(); + lcd.print("Kalibrasi"); + lcd.setCursor(0, 1); + lcd.print("Dibatalkan"); + delay(2000); + return; + } + } + + if(validReadings < 50) { + Serial.println("Gagal kalibrasi: Pembacaan tidak stabil"); + lcd.clear(); + lcd.print("Gagal Kalibrasi!"); + delay(3000); + return; + } + + R0 = sum / validReadings; + Serial.print("R0 terkalibrasi: "); + Serial.println(R0); + + lcd.clear(); + lcd.print("Kalibrasi Selesai"); + lcd.setCursor(0, 1); + lcd.print("R0: "); + lcd.print(R0); + delay(3000); +} + +void controlBuzzerAndLED(float temperature, float humidity, float co2) { + bool alertCondition = false; + String alertMessage = ""; + + if (co2 > CO2_THRESHOLD && co2 > 0) { + alertCondition = true; + alertMessage += "CO2 tinggi! "; + Serial.println("Peringatan: Level CO2 melebihi threshold!"); + } + + if (temperature > TEMP_THRESHOLD && temperature > 0) { + alertCondition = true; + alertMessage += "Suhu tinggi! "; + Serial.println("Peringatan: Suhu melebihi threshold!"); + } + + if (humidity > HUMID_THRESHOLD && humidity > 0) { + alertCondition = true; + alertMessage += "Kelembaban tinggi! "; + Serial.println("Peringatan: Kelembaban melebihi threshold!"); + } + + if (alertCondition && systemEnabled) { + tone(BUZZER_PIN, 1000); // Frekuensi 1 kHz + digitalWrite(LED_PIN, HIGH); // Nyalakan LED + lcd.setCursor(15, 0); + lcd.print("!"); + + if (alertMessage.length() > 0) { + client.publish(topic_alert, alertMessage.c_str()); + } + } else { + noTone(BUZZER_PIN); + digitalWrite(LED_PIN, LOW); // Matikan LED + lcd.setCursor(15, 0); + lcd.print(" "); + } +} + +void readAndSendSensorData() { + if (!systemEnabled) { + noTone(BUZZER_PIN); + digitalWrite(LED_PIN, LOW); + return; + } + + float humidity = dht.readHumidity(); + float temperature = dht.readTemperature(); + int rawValue = analogRead(MQ135_PIN); + + float sensor_volt = rawValue * (3.3 / 1023.0); + float RS_gas = (3.3 - sensor_volt) / sensor_volt; + float ratio = RS_gas / R0; + float ppm_CO2 = 116.6020682 * pow(ratio, -2.769034857); + + float corrected_ppm = ppm_CO2; + if (!isnan(temperature) && !isnan(humidity)) { + corrected_ppm = ppm_CO2 * (1.0 + 0.0005*(25-temperature) + 0.0002*humidity); + } + + if (isnan(humidity)) humidity = -1; + if (isnan(temperature)) temperature = -1; + if(rawValue < 50 || rawValue > 1000) corrected_ppm = -1; + + controlBuzzerAndLED(temperature, humidity, corrected_ppm); + + lcd.clear(); + lcd.setCursor(0, 0); + lcd.print("S:"); + lcd.print(systemEnabled ? "ON " : "OFF"); + lcd.print(" T:"); + lcd.print(temperature >= 0 ? temperature : -1, 1); + lcd.print("C"); + + lcd.setCursor(0, 1); + lcd.print("H:"); + lcd.print(humidity >= 0 ? humidity : -1, 0); + lcd.print("% CO2:"); + if(corrected_ppm < 0) { + lcd.print("Err"); + } else { + lcd.print(corrected_ppm, 0); + } + + char tempStr[10], humidStr[10], co2Str[10]; + dtostrf(temperature, 4, 2, tempStr); + dtostrf(humidity, 4, 2, humidStr); + dtostrf(corrected_ppm, 4, 0, co2Str); + + client.publish(topic_temp, tempStr); + client.publish(topic_humid, humidStr); + client.publish(topic_co2, co2Str); + + Serial.print("Temperature: "); + Serial.print(tempStr); + Serial.print("C | Humidity: "); + Serial.print(humidStr); + Serial.print("% | CO2: "); + Serial.print(co2Str); + Serial.println("ppm"); +} + +void setup() { + Serial.begin(115200); + + pinMode(BUZZER_PIN, OUTPUT); + pinMode(LED_PIN, OUTPUT); + digitalWrite(BUZZER_PIN, LOW); + digitalWrite(LED_PIN, LOW); + + lcd.init(); + lcd.backlight(); + lcd.setCursor(0, 0); + lcd.print("Starting System..."); + + dht.begin(); + + int testVal = analogRead(MQ135_PIN); + if(testVal < 50) { + Serial.println("ERROR: Sensor MQ135 tidak terdeteksi!"); + lcd.clear(); + lcd.print("MQ135 Error!"); + while(1) { + delay(1000); + Serial.println("Periksa koneksi dan reset board"); + } + } + + setup_wifi(); + + client.setServer(mqtt_server, mqtt_port); + client.setCallback(callback); + + calibrateR0(); + + lcd.clear(); +} + +void loop() { + if (!client.connected()) { + reconnect(); + } + client.loop(); + + lcd.setCursor(3, 0); + lcd.print(systemEnabled ? "ON " : "OFF"); + + unsigned long currentMillis = millis(); + if (currentMillis - lastSensorUpdate >= sensorInterval && systemEnabled) { + lastSensorUpdate = currentMillis; + readAndSendSensorData(); + } + + delay(100); +} \ No newline at end of file