/*
NAMA LENGKAP : BAYU ADI PAMBUDI
NIM : 5311422103
Deskripsi Program : Program ini mencakup 3 task dengan prioritas berbeda. Diantaranya adalah:
1. Task pertama, melakukan program LED Blink (kedip) dengan periode selain 1000ms.
2. Task kedua, membaca nilai ADC dari pin analog selain dari pin analog 0 dan mengirimkan hasilnya ke serial monitor.
3. Task ketiga, pengiriman secara berkala data "Nama Lengkap" dan "NIM" ke serial monitor.
*/
#include <Arduino_FreeRTOS.h>
// Menyertakan pustaka FreeRTOS untuk menjalankan multitasking pada Arduino.
#define LED_PIN 13
// Mendefinisikan LED_PIN sebagai pin 13, yang merupakan pin LED built-in di Arduino Uno.
#define ANALOG_PIN A5
// Mendefinisikan ANALOG_PIN sebagai pin A5, yang digunakan untuk membaca input analog dari sensor atau potensiometer.
void TaskBlink(void *pvParameters);
// Deklarasi fungsi untuk task LED Blink, yang akan didefinisikan nanti.
// Parameter 'pvParameters' tidak digunakan di sini tapi tetap diperlukan oleh FreeRTOS.
void TaskAnalogRead(void *pvParameters);
// Deklarasi fungsi untuk task membaca sinyal analog dari pin A5.
void TaskNameNIM(void *pvParameters);
// Deklarasi fungsi untuk task yang menampilkan Nama dan NIM pada Serial Monitor.
int analogValue = 0;
// Variabel global untuk menyimpan nilai analog yang dibaca dari pin A5.
void setup()
{
Serial.begin(9600);
// Memulai komunikasi serial dengan baud rate 9600 untuk menampilkan data ke Serial Monitor.
pinMode(LED_PIN, OUTPUT);
// Mengatur mode pin LED sebagai output agar dapat mengendalikan LED.
xTaskCreate(
TaskBlink,
// Fungsi yang akan dijalankan oleh task. Di sini, kita memanggil TaskBlink.
"Task Blink",
// Nama task yang kita buat. Ini hanya untuk tujuan debug atau identifikasi.
128,
// Memori stack yang dialokasikan untuk task. Dalam satuan word (biasanya 2 byte).
NULL,
// Parameter yang bisa diteruskan ke task. Di sini NULL karena tidak diperlukan.
3,
// Prioritas task. 3 adalah prioritas tertinggi dari task yang ada di kode ini.
NULL
// Pointer untuk handle task. Di sini NULL karena kita tidak membutuhkan handle.
);
xTaskCreate(
TaskAnalogRead,
"Task Analog Read",
128,
NULL,
2,
NULL
);
xTaskCreate(
TaskNameNIM,
"Task Send Info",
128,
NULL,
1,
NULL
);
}
void loop()
{
// Loop utama kosong karena semua pekerjaan dilakukan di dalam task.
// Pada FreeRTOS, tugas-tugas individual (task) menggantikan penggunaan loop biasa.
}
void TaskBlink(void *pvParameters)
{
TickType_t xLastWakeTime = xTaskGetTickCount();
// Menyimpan waktu terakhir task ini dieksekusi. Digunakan untuk menjaga interval yang tepat pada setiap iterasi.
const TickType_t xFrequency = 2000 / portTICK_PERIOD_MS;
// Menentukan frekuensi task, yaitu 2000 milidetik (2 detik) dalam satuan ticks.
for(;;)
{
digitalWrite(LED_PIN, HIGH);
// Menyalakan LED.
Serial.println("LED ON");
// Menampilkan pesan "LED ON" ke Serial Monitor.
vTaskDelayUntil(&xLastWakeTime, xFrequency);
// Menunggu hingga 2 detik berlalu sejak task ini terakhir kali dieksekusi.
digitalWrite(LED_PIN, LOW);
// Mematikan LED.
Serial.println("LED OFF");
// Menampilkan pesan "LED OFF" ke Serial Monitor.
vTaskDelayUntil(&xLastWakeTime, xFrequency);
// Menunggu hingga 2 detik lagi berlalu sejak task ini terakhir kali dieksekusi.
Serial.print("=======task LED (words): ");
Serial.println(uxTaskGetStackHighWaterMark(NULL));
// Menampilkan jumlah sisa stack yang tersedia untuk task ini. Ini penting untuk melihat apakah memori stack cukup.
}
}
void TaskAnalogRead(void *pvParameters)
{
TickType_t xLastWakeTime = xTaskGetTickCount();
// Menyimpan waktu terakhir task ini dieksekusi.
const TickType_t xFrequency = 500 / portTICK_PERIOD_MS;
// Menentukan frekuensi task, yaitu 500 milidetik (0.5 detik).
for(;;)
{
analogValue = analogRead(ANALOG_PIN);
// Membaca nilai analog dari pin A5 dan menyimpannya ke variabel 'analogValue'.
Serial.print("Nilai Analog : ");
Serial.println(analogValue);
// Menampilkan nilai analog ke Serial Monitor.
vTaskDelayUntil(&xLastWakeTime, xFrequency);
// Menunggu hingga 500 milidetik berlalu sejak task ini terakhir kali dieksekusi.
Serial.print("=======task ADC (words): ");
Serial.println(uxTaskGetStackHighWaterMark(NULL));
// Menampilkan sisa stack yang tersedia untuk task ini.
}
}
void TaskNameNIM(void *pvParameters)
{
TickType_t xLastWakeTime = xTaskGetTickCount();
// Menyimpan waktu terakhir task ini dieksekusi.
const TickType_t xFrequency = 3000 / portTICK_PERIOD_MS;
// Menentukan frekuensi task, yaitu 3000 milidetik (3 detik).
for(;;)
{
Serial.println("BAYU ADI PAMBUDI 5311422103");
// Menampilkan Nama dan NIM pada Serial Monitor.
vTaskDelayUntil(&xLastWakeTime, xFrequency);
// Menunggu hingga 3 detik berlalu sejak task ini terakhir kali dieksekusi.
Serial.print("=======task Nam dan NIM (words): ");
Serial.println(uxTaskGetStackHighWaterMark(NULL));
// Menampilkan sisa stack yang tersedia untuk task ini.
}
}
/*
Kesimpulan setelah melakukan percobaan dengan website WOKWI adalah:
vTaskDelayUntil:
Fungsi ini berguna untuk memastikan task dijalankan pada interval tetap yang diinginkan,
meskipun task lain mungkin mengambil waktu CPU. Ini membantu menjaga konsistensi waktu eksekusi.
uxTaskGetStackHighWaterMark:
Ini digunakan untuk memeriksa seberapa dekat task tersebut menghabiskan seluruh stack-nya. Stack yang tersedia rata-rata senilai 29.
Ini penting untuk debugging jika ada kekurangan memori atau masalah dengan stack overflow.
*/