#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Arduino_FreeRTOS.h>
#include <semphr.h>
#include <queue.h>
// Inisialisasi objek untuk LCD I2C
LiquidCrystal_I2C lcd(0x27, 16, 2); // Alamat LCD I2C biasanya 0x27 atau 0x3F
const int LED_AKTIF = 2; // Tentukan pin LED ON/OFF
const int BUZZER_PIN = 3; // Tentukan pin Buzzer
const int LED_WARNING = 4; // Tentukan pin LED Warning
// Inisialisasi objek untuk sensor suhu DS18B20
OneWire oneWire(A1);
DallasTemperature sensors(&oneWire);
SemaphoreHandle_t sensorSemaphore;
float temperatureData;
TaskHandle_t displayTaskHandle, ledTaskHandle, sensorTaskHandle, greetingTaskHandle;
QueueHandle_t temperatureQueue;
void taskReadTemperature(void *pvParameters);
void taskDisplayTemperature(void *pvParameters);
void taskLEDControl(void *pvParameters);
void taskGreeting(void *pvParameters);
void setup() {
Serial.begin(9600);
// Inisialisasi LCD
pinMode(LED_AKTIF, OUTPUT); // Atur pin LED sebagai output
pinMode(BUZZER_PIN, OUTPUT); // Atur pin Buzzer sebagai output
pinMode(LED_WARNING, OUTPUT); // Atur pin LED Warning sebagai output
lcd.begin(16, 2);
// Inisialisasi sensor suhu
sensors.begin();
// Buat semaphore untuk sinkronisasi
sensorSemaphore = xSemaphoreCreateBinary();
// Buat antrian (queue) untuk mentransfer data suhu antar tugas
temperatureQueue = xQueueCreate(5, sizeof(float));
// Buat task untuk menyapa (greeting)
xTaskCreate(taskGreeting, "Greeting", 128, NULL, 0, &greetingTaskHandle);
// Mulai scheduler
vTaskStartScheduler();
}
void loop() {
// Tidak ada kode di sini karena scheduler sudah mengambil alih kontrol
}
void taskGreeting(void *pvParameters) {
(void)pvParameters;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Power ON!");
// Tunggu sebentar
vTaskDelay(pdMS_TO_TICKS(1500));
// Hilangkan pesan sambutan
lcd.clear();
// Buat task untuk membaca suhu
xTaskCreate(taskReadTemperature, "ReadTemperature", 128, NULL, 3, &sensorTaskHandle);
// Buat task untuk menampilkan suhu
xTaskCreate(taskDisplayTemperature, "DisplayTemperature", 128, NULL, 2, &displayTaskHandle);
// Buat task untuk mengontrol LED
xTaskCreate(taskLEDControl, "LEDControl", 128, NULL, 1, &ledTaskHandle);
// Hapus task greeting
vTaskDelete(greetingTaskHandle);
}
void taskReadTemperature(void *pvParameters) {
(void)pvParameters;
while (1) {
// Baca suhu dari sensor
sensors.requestTemperatures();
temperatureData = sensors.getTempCByIndex(0);
// Beri tahu task lain bahwa data sudah siap
xSemaphoreGive(sensorSemaphore);
// Tunggu 0.5 detik sebelum membaca suhu lagi
vTaskDelay(pdMS_TO_TICKS(500));
// Kirim data suhu ke antrian
xQueueSend(temperatureQueue, &temperatureData, portMAX_DELAY);
}
}
void taskDisplayTemperature(void *pvParameters) {
(void)pvParameters;
float receivedTemperature;
while (1) {
// Terima data suhu dari antrian
xQueueReceive(temperatureQueue, &receivedTemperature, portMAX_DELAY);
// Tampilkan data suhu pada LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Suhu: ");
lcd.print(receivedTemperature);
lcd.print(" C");
// Beri tahu task LEDControl bahwa tampilan sudah diperbarui
xTaskNotify(ledTaskHandle, 1, eSetBits);
// Tunggu sebelum menampilkan suhu lagi
vTaskDelay(pdMS_TO_TICKS(500));
}
}
void taskLEDControl(void *pvParameters) {
(void)pvParameters;
float receivedTemperature;
while (1) {
// Terima data suhu dari antrian
xQueueReceive(temperatureQueue, &receivedTemperature, portMAX_DELAY);
// Cek suhu
if (receivedTemperature > 50.0) {
// LED Warning ON jika suhu lebih dari 50 derajat
digitalWrite(LED_WARNING, HIGH);
} else {
// Matikan LED Warning jika suhu tidak lebih dari 50 derajat
digitalWrite(LED_WARNING, LOW);
}
// Tidak ada delay untuk LED Warning, tetap menyala
// LED ON
digitalWrite(LED_AKTIF, HIGH);
// Buzzer ON
digitalWrite(BUZZER_PIN, HIGH);
// Tunggu sebentar
vTaskDelay(pdMS_TO_TICKS(2000)); // Sesuaikan dengan kebutuhan
// LED OFF
digitalWrite(LED_AKTIF, LOW);
// Buzzer OFF
digitalWrite(BUZZER_PIN, LOW);
// Tunggu sebentar
vTaskDelay(pdMS_TO_TICKS(2000)); // Sesuaikan dengan kebutuhan
}
}