Add Tugas Akhir monitoring suhu berbasis IOT

This commit is contained in:
irsyadrosidi 2025-07-30 14:36:15 +07:00
commit 72a9519df8
1 changed files with 368 additions and 0 deletions

View File

@ -0,0 +1,368 @@
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// 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);
}