#include <WiFi.h> // Memasukkan library untuk mengakses WiFi
#include <Wire.h> // Memasukkan library untuk mengakses I2C
#include <Adafruit_GFX.h> // Memasukkan library dasar untuk tampilan grafis
#include <Adafruit_SSD1306.h> // Memasukkan library untuk display OLED
#include <FirebaseESP32.h> // Memasukkan library untuk mengakses Firebase pada ESP32
#include <DHT.h> // Memasukkan library untuk sensor DHT
#include <ESP32Servo.h> // Memasukkan library untuk mengakses Servo pada ESP32
#include <addons/TokenHelper.h> // Memasukkan library tambahan untuk Firebase
#include <addons/RTDBHelper.h> // Memasukkan library tambahan untuk Firebase
// Pin sensor
#define DHTPIN 33 // Mendefinisikan pin DHT22 terhubung ke pin 33
#define POTPIN 34 // Mendefinisikan pin potensiometer terhubung ke pin 34
#define SERVO_PIN 32 // Mendefinisikan pin servo terhubung ke pin 32
// Konfigurasi sensor DHT
#define DHTTYPE DHT22 // Mendefinisikan tipe sensor DHT
// Konfigurasi display OLED
#define SCREEN_WIDTH 128 // Mendefinisikan lebar layar OLED, dalam piksel
#define SCREEN_HEIGHT 64 // Mendefinisikan tinggi layar OLED, dalam piksel
#define OLED_RESET -1 // Mendefinisikan pin reset # (atau -1 jika berbagi pin reset Arduino)
// Konfigurasi WiFi dan Firebase
#define ssid "Sarangtawon" // Mendefinisikan nama SSID WiFi
#define password "satusampaidelapan" // Mendefinisikan kata sandi WiFi
#define firebase_host "https://tugasutsiot-c8b7d-default-rtdb.asia-southeast1.firebasedatabase.app/" // Mendefinisikan URL host Firebase
#define firebase_auth "AIzaSyBLxVL1_NChPvjLuX3a4_ClS9xQOmPySVo" // Mendefinisikan autentikasi Firebase
// Inisialisasi sensor DHT
DHT dht(DHTPIN, DHTTYPE);
// Inisialisasi display OLED
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Inisialisasi WiFi Client
WiFiClient client;
// Inisialisasi Firebase
FirebaseData fbdo;
FirebaseJson Json;
FirebaseAuth auth;
FirebaseConfig config;
// Inisialisasi Servo
Servo myservo;
// Semaphore untuk sinkronisasi antara task1 dan task2
SemaphoreHandle_t semSensor;
// Queue untuk mengirimkan data dari task1 ke task2
QueueHandle_t queueSensor;
void setup() {
Serial.begin(115200); // Memulai komunikasi serial dengan kecepatan 115200 baud
// Inisialisasi sensor DHT
dht.begin();
// Inisialisasi display OLED
Wire.begin(); // Memulai komunikasi I2C
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Memulai komunikasi dengan display OLED
// Menghubungkan ke WiFi
WiFi.begin(ssid, password); // Memulai koneksi WiFi dengan nama SSID dan kata sandi tertentu
while (WiFi.status() != WL_CONNECTED) { // Melakukan loop sampai koneksi WiFi terhubung
delay(1000);
Serial.println("Connecting to WiFi.."); // Menampilkan pesan "Connecting to WiFi.." di serial monitor
}
// Inisialisasi Firebase
config.api_key = firebase_auth; // Mengatur kunci API Firebase
config.database_url = firebase_host; // Mengatur URL database Firebase
Firebase.begin(&config, &auth); // Memulai koneksi Firebase dengan konfigurasi dan autentikasi tertentu
Firebase.reconnectWiFi(true); // Mengatur ulang koneksi WiFi jika terputus
Firebase.setReadTimeout(fbdo, 1000 * 60); // Mengatur waktu timeout baca data Firebase
Firebase.setwriteSizeLimit(fbdo, "tiny"); // Mengatur batasan ukuran tulisan kecil saat menulis data Firebase
Serial.println("------------------------------------"); // Menampilkan garis pemisah di serial monitor
// Inisialisasi Servo
myservo.attach(SERVO_PIN); // Menghubungkan pin servo
// Inisialisasi Semaphore
semSensor = xSemaphoreCreateBinary(); // Membuat semaphore biner
// Inisialisasi Queue
queueSensor = xQueueCreate(1, sizeof(float) * 2); // Membuat queue dengan kapasitas 1 dan ukuran data 2 float
// Memulai tugas RTOS
xTaskCreatePinnedToCore(task1, "task1", 4096, NULL, 1, NULL, 0); // Membuat task1 dan menetapkannya ke core 0
xTaskCreatePinnedToCore(task2, "task2", 4096, NULL, 1, NULL, 0); // Membuat task2 dan menetapkannya ke core 0
xTaskCreatePinnedToCore(task3, "task3", 4096, NULL, 1, NULL, 0); // Membuat task3 dan menetapkannya ke core 0
}
void loop() {
}
void task1(void * parameter) {
// Task untuk membaca nilai sensor dan mengirimkan ke Queue
while(1) {
float humidity = dht.readHumidity(); // Membaca nilai kelembaban dari sensor DHT
float temperature = dht.readTemperature(); // Membaca nilai suhu dari sensor DHT
float sensorData[2] = {temperature, humidity}; // Menyimpan data suhu dan kelembaban dalam array
xQueueSend(queueSensor, &sensorData, portMAX_DELAY); // Mengirim data sensor ke Queue
// Kirim data sensor ke Firebase
if (Firebase.setFloat(fbdo, "/test/suhu", float(temperature))) { // Mengirim data suhu ke Firebase
Serial.print("Suhu terkirim ke Firebase:"); // Menampilkan pesan di Serial Monitor
Serial.println(float (temperature)); // Menampilkan nilai suhu di Serial Monitor
} else {
Serial.print("Gagal mengirim suhu ke Firebase"); // Menampilkan pesan di Serial Monitor
Serial.println("Alasan: " + fbdo.errorReason()); // Menampilkan alasan kegagalan di Serial Monitor
}
if (Firebase.setFloat(fbdo, "/test/kelembaban", float(humidity))) { // Mengirim data kelembaban ke Firebase
Serial.print("Kelembaban terkirim ke Firebase:"); // Menampilkan pesan di Serial Monitor
Serial.println(float (humidity)); // Menampilkan nilai kelembaban di Serial Monitor
} else {
Serial.print("Gagal mengirim kelembaban ke Firebase"); // Menampilkan pesan di Serial Monitor
Serial.println("Alasan: " + fbdo.errorReason()); // Menampilkan alasan kegagalan di Serial Monitor
}
// Mengirimkan sinyal ke task2 bahwa data sudah tersedia
xSemaphoreGive(semSensor); // Memberikan sinyal ke Semaphore
delay(2000); // Menunda eksekusi task selama 2 detik
}
}
void task2(void * parameter) {
// Task untuk menampilkan nilai sensor pada OLED
while(1) {
// Menunggu sinyal dari task1 bahwa data sudah tersedia
if (xSemaphoreTake(semSensor, portMAX_DELAY)) { // Mengambil sinyal dari Semaphore
float sensorData[2]; // Membuat array untuk menyimpan data sensor
xQueueReceive(queueSensor, &sensorData, portMAX_DELAY); // Menerima data sensor dari Queue
float temperature = sensorData[0]; // Mendapatkan nilai suhu dari data sensor
float humidity = sensorData[1]; // Mendapatkan nilai kelembaban dari data sensor
display.clearDisplay(); // Menghapus tampilan pada display OLED
display.setTextSize(1); // Mengatur ukuran teks
display.setTextColor(SSD1306_WHITE); // Mengatur warna teks
display.setCursor(0,0); // Mengatur posisi kursor
display.println("Humidity: " + String(humidity) + "%"); // Menampilkan nilai kelembaban di display OLED
display.println("Temperature: " + String(temperature) + "C"); // Menampilkan nilai suhu di display OLED
display.display(); // Menampilkan tampilan yang telah dibuat
}
}
}
void task3(void * parameter) {
// Task untuk mengontrol servo berdasarkan nilai potensiometer
while(1) {
int potValue = analogRead(POTPIN); // Membaca nilai potensiometer
int angle = map(potValue, 0, 4095, 0, 180); // Mengonversi nilai potensiometer menjadi sudut untuk servo
myservo.write(angle); // Menggerakkan servo ke posisi sudut yang diinginkan
delay(20); // Menunda eksekusi task selama 20 milidetik
}
}