/**
Laode Alif Ma'sum Sidrajat Raja Ika / 2106731213
Zalfy Putra Rezky / 2106731453
**/
#include <stdlib.h>
#include <string.h>
// Use only core 1 for demo purposes
#if CONFIG_FREERTOS_UNICORE
static const BaseType_t app_cpu = 0;
#else
static const BaseType_t app_cpu = 1;
#endif
// Settings
static const uint8_t buf_len = 20;
TimerHandle_t cookTimer; //Cooking timer handle
TimerHandle_t resetTimer; //Reset timer handle
const TickType_t timerInterval = 1000/portTICK_PERIOD_MS; //1 sec timer interval
int i, j;
enum state{ //State enum
Idle,
Cooking,
Waiting,
Finish
};
const char* stateStrings[] = {"Idle", "Cooking", "Waiting", "Finish"}; //State string array
enum state currentState; //currentState variable
// Task: Read from serial terminal
// Feel free to use Serial.readString() or Serial.parseInt(). I'm going to show
// it with atoi() in case you're doing this in a non-Arduino environment. You'd
// also need to replace Serial with your own UART code for non-Arduino.
void readSerial(void *parameters){
char c; //char to receive serial input
char buf[buf_len]; //string from char collected in serial input
uint8_t idx = 0; //index to iterate through string
memset(buf, 0, buf_len); // Clear whole buffer
// Loop forever
while (1)
{
// Read characters from serial
if (Serial.available() > 0)
{
do{
c = Serial.read();
// Update delay variable and reset buffer if we get a newline character
if (c == '\n')
{
idx = 0; //reset index
if(strcasecmp(buf, "Pipit") == 0){ //Burung pipit mode
Serial.println(buf);
int countLimit[3] = {8, 5, 4}; //every stage count stored in array
cookTimer = xTimerCreate(
"Burung Pipit", // Nama timer
timerInterval, // Waktu interval timer
pdFALSE, // One-shot timer
(void *)&countLimit, // Parameter timer
timerCallback // Callback timer
);
for(i = 0; i < 3; i++){
while(countLimit[i] > 0){
// Membuat dan mengatur timer
xTimerStart(cookTimer, 0); //start cooking timer
xTimerReset(cookTimer, 0); //reset cooking timer
vTaskDelay(1000/portTICK_PERIOD_MS); //wait until timer successfully reset
}
}
}else if(strcasecmp(buf, "Puyuh") == 0 ){ //Burung puyuh mode
Serial.println(buf);
int countLimit[3] = {9, 7, 2}; //every stage count stored in array
cookTimer = xTimerCreate(
"Burung Puyuh", // Nama timer
timerInterval, // Waktu interval timer
pdFALSE, // One-shot timer
(void *)&countLimit, // Parameter timer
timerCallback // Callback timer
);
for(i = 0; i < 3; i++){
while(countLimit[i] > 0){
xTimerStart(cookTimer, 0); //start cooking timer
xTimerReset(cookTimer, 0); //reset cooking timer
vTaskDelay(1000/portTICK_PERIOD_MS); //wait until timer successfully reset
}
}
}else if(strcasecmp(buf, "Hantu") == 0){ //Burung hantu mode
Serial.println(buf);
int countLimit[4] = {3, 11, 7, 3}; //every stage count stored in array
// Membuat dan mengatur timer
cookTimer = xTimerCreate(
"Burung Hantu", // Nama timer
timerInterval, // Waktu interval timer
pdFALSE, // One-shot timer
(void *)&countLimit, // Parameter timer
timerCallback // Callback timer
);
for(i = 0; i < 4; i++){
while(countLimit[i] > 0){
xTimerStart(cookTimer, 0); //start cooking timer
xTimerReset(cookTimer, 0); //reset cooking timer
vTaskDelay(1000/portTICK_PERIOD_MS); //wait until timer successfully reset
}
}
}else if(strcasecmp(buf, "Onta") == 0){ //Burung onta mode
Serial.println(buf);
int countLimit[6] = {10,5,6,3,3,2}; //every stage count stored in array
cookTimer = xTimerCreate(
"Burung Onta", // Nama timer
timerInterval, // Waktu interval timer
pdFALSE, // One-shot timer
(void *)&countLimit, // Parameter timer
timerCallback // Callback timer
);
for(i = 0; i < 5; i++){
while(countLimit[i] > 0){
xTimerStart(cookTimer, 0); //start cooking timer
xTimerReset(cookTimer, 0); //reset cooking timer
vTaskDelay(1000/portTICK_PERIOD_MS); //wait until timer successfully reset
}
}
}else{
Serial.println("Input invalid");
}
currentState = Finish; //change state to finish after finish all counting
digitalWrite(LED_BUILTIN, HIGH);
Serial.println(stateStrings[currentState]);
memset(buf, 0, buf_len); //reset buffer
//reset state back into idle state after 3 seconds in finish state
resetTimer = xTimerCreate(
"Reset State", // Nama timer
timerInterval*3, // Waktu interval timer
pdFALSE, // One-shot timer
NULL, // Parameter timer
resetCallback // Callback timer
);
xTimerStart(resetTimer, 0); //start reset timer
xTimerReset(resetTimer, 0); //reset reset timer
}
else
{
// Only append if index is not over message limit
if (idx < buf_len - 1)
{
buf[idx] = c;
idx++;
}
}
}while(currentState == Idle);
}
}
}
// Callback untuk timer
void timerCallback(TimerHandle_t xTimer) {
int *countLimitPtr = (int *)pvTimerGetTimerID(xTimer); //store timer parameter into variable
if(countLimitPtr[i] != 0){
if(i % 2 == 0){ //i = even --> cooking state, else --> waiting state
currentState = Cooking;
Serial.println((String) stateStrings[currentState] + ", " + (countLimitPtr[i]));
}else{
currentState = Waiting;
Serial.println((String) stateStrings[currentState] + ", " + (countLimitPtr[i]));
}
}
countLimitPtr[i]--; //decrement counter
}
//************************************************************************
void resetCallback(TimerHandle_t xTimer){ //reset timer after cooking finished
currentState = Idle; //back to idle state
Serial.println(stateStrings[currentState]);
Serial.println("Masukkan jenis telur: ");
digitalWrite(LED_BUILTIN, LOW); //turn off LED
}
void setup() {
// put your setup code here, to run once:
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
currentState = Idle;
Serial.println(stateStrings[currentState]);
Serial.println("Masukkan jenis telur: ");
// Start serial read task
xTaskCreatePinnedToCore( // Use xTaskCreate() in vanilla FreeRTOS
readSerial, // Function to be called
"Read Serial", // Name of task
1024, // Stack size (bytes in ESP32, words in FreeRTOS)
NULL, // Parameter to pass
1, // Task priority (must be same to prevent lockup)
NULL, // Task handle
app_cpu); // Run on one core for demo purposes (ESP32 only)
// Delete "setup and loop" task
vTaskDelete(NULL);
}
void loop() {
}