#include <freertos/message_buffer.h>
#define BUFFER_SIZE 8
typedef enum {
PLAY,
PAUSE,
RESUME,
STOP
} State;
// Global variables to store LED state and timer handle
uint32_t g_currTime = 0;
uint32_t g_songDuration = 15;
State g_currState = STOP;
bool bluetoothOn = false;
SemaphoreHandle_t binSem;
MessageBufferHandle_t xMessageBuffer;
void vTimerTask(void *pvParam) {
uint8_t buffer[BUFFER_SIZE];
size_t bytes_received;
bytes_received = xMessageBufferReceive(xMessageBuffer, buffer, BUFFER_SIZE, portMAX_DELAY);
bool on = (bytes_received > 0 && buffer[0] == '1');
while (on)
{
if (g_currState == PLAY || g_currState == RESUME) Serial.print("Playing | ");
else if (g_currState == PAUSE) Serial.print("Paused | ");
else if (g_currState == STOP) {
Serial.print("Stopped | ");
g_currTime = 0;
}
Serial.print(getFormattedTime(g_currTime));
Serial.print(" / ");
Serial.println(getFormattedTime(g_songDuration));
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void onTimer(void *pvParam) {
while(true) {
if (g_currTime >= g_songDuration) {
g_currState = STOP;
g_currTime = 0;
}
else if (g_currState == PLAY || g_currState == RESUME) g_currTime++;
else if (g_currState == STOP) g_currTime = 0;
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void vLedTask(void *pvParam) {
while (true) {
if (g_currState == PLAY || g_currState == RESUME) digitalWrite(LED_BUILTIN, HIGH);
else digitalWrite(LED_BUILTIN, LOW);
vTaskDelay(pdMS_TO_TICKS(50));
}
}
void vSerialTask(void *pvParam) {
while (true) {
xSemaphoreTake(binSem, portMAX_DELAY);
if (Serial.available() <= 0) {
vTaskDelay(100 / portTICK_PERIOD_MS);
xSemaphoreGive(binSem);
continue;
}
String inpStr = Serial.readStringUntil('\n');
inpStr.trim();
if (inpStr.compareTo("PLAY") == 0) g_currState = PLAY;
else if (inpStr.compareTo("PAUSE") == 0) g_currState = PAUSE;
else if (inpStr.compareTo("RESUME") == 0 && g_currState == PAUSE) g_currState = RESUME;
else if (inpStr.compareTo("STOP") == 0) g_currState = STOP;
else Serial.println("Invalid command!");
}
}
void bluetoothInitialization(void *pvParam) {
Serial.println("Initializing bluetooth connection...");
xSemaphoreTake(binSem, portMAX_DELAY);
vTaskDelay(pdMS_TO_TICKS(2000));
Serial.println("Bluetooth connected after 2 sec");
bluetoothOn = true;
bool message_value = true;
const char message = message_value ? '1' : '0';
xMessageBufferSend(xMessageBuffer, &message, sizeof(char), portMAX_DELAY);
xSemaphoreGive(binSem);
vTaskDelete(NULL);
}
void vMediumTask(void *pvParam) {
while(1){
if(bluetoothOn) vTaskDelete(NULL);
Serial.println("Please wait!");
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void setup() {
// Initialize serial and pins
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
xMessageBuffer = xMessageBufferCreate(BUFFER_SIZE);
binSem = xSemaphoreCreateMutex();
// Create task
xTaskCreatePinnedToCore(vSerialTask, "SerialTask", 2048, NULL, 1, NULL, 1);
vTaskDelay(1 / portTICK_PERIOD_MS); //agar serial task mengambil mutex dulu
xTaskCreatePinnedToCore(bluetoothInitialization, "Bluetooth", 2048, NULL, 3, NULL, 1);
xTaskCreatePinnedToCore(vMediumTask, "MediumTask", 2048, NULL, 2, NULL, 1);
xTaskCreatePinnedToCore(vLedTask, "TaskLED", 2048, NULL, 1, NULL, 0);
xTaskCreatePinnedToCore(vTimerTask, "TimerTask", 2048, NULL, 1, NULL, 0);
xTaskCreatePinnedToCore(onTimer, "onTimer", 2048, NULL, 1, NULL, 0);
vTaskDelete(NULL);
}
void loop() {}
String getFormattedTime(int seconds) {
int minutes = seconds / 60;
int remainingSeconds = seconds % 60;
String formattedTime = String(minutes) + ":";
if (remainingSeconds < 10) formattedTime += "0";
formattedTime += String(remainingSeconds);
return formattedTime;
}