/*
Blink without delay and print the LED state onto Serial monitor.
by PHAM PHUC HUY 18-04-2024
*/
//#include <Arduino_FreeRTOS.h>
#include <Arduino_FreeRTOS.h>
#include <Streaming.h>
#include "semphr.h"
#define BAUD_RATE 9600
#define BLINKY_pin 11
#define Button_pin 5
#define Button_LED 10
#define Idle_pin 7
#define Button_stack_size 130
#define BLINKY_stack_size 130
#define input_brightness_from_serial_monitor_stack_size 160
#define Idle_stack_size 100
SemaphoreHandle_t xSerialSemaphore;
int blink_interval = 200; // blink frequency, can be changed by input into the serial monitor
static void Button(void* pvParameters);
static void BLINKY(void* pvParameters);
static void Idle(void* pvParameters);
static void input_brightness_from_serial_monitor(void* pvParameters);
void setup() {
Serial.begin(BAUD_RATE);
Serial << "In Setup function\n";
pinMode(BLINKY_pin, OUTPUT);
pinMode(Button_LED, OUTPUT);
pinMode(Button_pin, INPUT);
xSerialSemaphore = xSemaphoreCreateBinary();
// Create tasks
xTaskCreate(Button, "Button", Button_stack_size, NULL, 1, NULL);
xTaskCreate(BLINKY, "BLINKY", BLINKY_stack_size, NULL, 1, NULL);
xTaskCreate(input_brightness_from_serial_monitor, "Serial Input", input_brightness_from_serial_monitor_stack_size, NULL, 2, NULL);
xTaskCreate(Idle, "IdleTask", 100, NULL, 0, NULL);
vTaskStartScheduler();
}
void loop() {
// Not used. Tasks are handled by FreeRTOS.
}
static void BLINKY(void* pvParameters) {
TickType_t xLastWakeTime;
TickType_t xFrequency = pdMS_TO_TICKS(blink_interval);
BaseType_t xWasDelayed;
int blinky_current_state = 0;
// Initialize the xLastWakeTime variable with the current time.
xLastWakeTime = xTaskGetTickCount();
for (;;) {
xFrequency = pdMS_TO_TICKS(blink_interval);
// Wait for the next cycle.
xWasDelayed = xTaskDelayUntil(&xLastWakeTime, xFrequency);
blinky_current_state = !blinky_current_state;
digitalWrite(BLINKY_pin, blinky_current_state);
// Optionally print the LED state to the serial monitor
// Serial << "blink " << (blinky_current_state ? "HIGH\n" : "LOW\n");
}
vTaskDelete(NULL);
}
static void Button(void* pvParameters) {
TickType_t xLastWakeTime;
const TickType_t xFrequency = pdMS_TO_TICKS(20);
BaseType_t xWasDelayed;
int button_current_state = 0;
// Initialize the xLastWakeTime variable with the current time.
xLastWakeTime = xTaskGetTickCount();
for (;;) {
// Wait for the next cycle.
xWasDelayed = xTaskDelayUntil(&xLastWakeTime, xFrequency);
button_current_state = digitalRead(Button_pin);
digitalWrite(Button_LED, button_current_state);
}
vTaskDelete(NULL);
}
static void input_brightness_from_serial_monitor(void* pvParameters) {
char inputString[10];
int inputIndex = 0;
int temp_for_blink_interval;
for (;;) {
// Wait for the semaphore to be given by serialEvent
if (xSemaphoreTake(xSerialSemaphore, portMAX_DELAY) == pdTRUE) {
while (Serial.available() > 0) {
char c = Serial.read();
if (c == '\n' || c == '\r') {
if (inputIndex > 0) {
inputString[inputIndex] = '\0';
temp_for_blink_interval = atoi(inputString);
// Print the new interval to the serial monitor
Serial << ("You entered: ");
Serial << (temp_for_blink_interval) << "\n";
if (temp_for_blink_interval <= 16){
blink_interval = 20;
Serial << "This interval is to low, and will cause a bug for the program.\n";
Serial << "Blink interval is now 20 (minimum), enter another blink value.\n";
}
else {
blink_interval = temp_for_blink_interval;
}
inputIndex = 0; // Reset for next input
}
xSemaphoreGive(xSerialSemaphore);
} else if (inputIndex < (sizeof(inputString) - 1)) {
inputString[inputIndex++] = c;
}
}
}
}
}
// This function is called when serial data is available
void serialEvent() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
// Give the semaphore to wake up Task 3
xSemaphoreGiveFromISR(xSerialSemaphore, &xHigherPriorityTaskWoken);
// Perform a context switch if necessary
if (xHigherPriorityTaskWoken) {
portYIELD_FROM_ISR();
}
}
static void Idle(void* pvParameters) {
int TaskIDLE_LED_state = 0;
for (;;)
{
TaskIDLE_LED_state = !TaskIDLE_LED_state;
digitalWrite(Idle_pin, TaskIDLE_LED_state);
//Serial << "Idling_free_task\n";
vTaskDelay(1);
}
vTaskDelete(NULL);
}
/*
#include <Arduino_FreeRTOS.h>
#include <Streaming.h>
#include "semphr.h"
#define BAUD_RATE 9600
#define BLINKY_pin 11
#define Button_pin 5
#define Button_LED 10
#define Idle_pin 7
#define Button_stack_size 180
#define BLINKY_stack_size 180
#define input_brightness_from_serial_monitor_stack_size 180
#define Idle_stack_size 180
SemaphoreHandle_t xSerialSemaphore;
//#define blink_interval 200
int blink_interval = 200; // blink frequency, can be changed by input into the serial monitor
static void Button (void* pvParameters);
static void BLINKY (void* pvParameters);
static void Idle (void* pvParameters);
void setup(){
Serial.begin( BAUD_RATE );
Serial << "In Setup function\n";
pinMode(BLINKY_pin, OUTPUT);
pinMode(Button_LED, OUTPUT);
pinMode(Button_pin, INPUT);
xSerialSemaphore = xSemaphoreCreateBinary();
//Button
xTaskCreate(Button, "Button", Button_stack_size, NULL, 1, NULL);
//BLINKY:
xTaskCreate(BLINKY, "BLINKY", BLINKY_stack_size, NULL, 1, NULL);
//Serial input
xTaskCreate(input_brightness_from_serial_monitor, "Serial Input", input_brightness_from_serial_monitor_stack_size, NULL, 3, NULL);
//Idle: tác vụ nhàn rỗi, không làm gì, mức ưu tiên thấp nhất, chỉ chạy khi không có tác vụ nào khác READY hoặc RUNNING
xTaskCreate(Idle, "IdleTask", 100, NULL, 0, NULL);
vTaskStartScheduler();
}
void loop(){
//There is no instruction in the loop section of the code.
// Because each task executes on interrupt after specified time
}
static void BLINKY(void* pvParameters) {
TickType_t xLastWakeTime;
TickType_t xFrequency = pdMS_TO_TICKS(blink_interval);
BaseType_t xWasDelayed;
int blinky_current_state = 0;
// Initialise the xLastWakeTime variable with the current time.
xLastWakeTime = xTaskGetTickCount ();
for( ;; )
{
xFrequency = pdMS_TO_TICKS(blink_interval);
// Wait for the next cycle.
xWasDelayed = xTaskDelayUntil( &xLastWakeTime, xFrequency );
blinky_current_state = !blinky_current_state;
if (blinky_current_state == 0) {
digitalWrite(BLINKY_pin, LOW);
//Serial << "blink LOW\n";
}
else {
digitalWrite(BLINKY_pin, HIGH);
//Serial << "blink HIGH\n";
}
// if ( xWasDelayed == pdTRUE ) {
// Serial << "Blinky delayed\n";
// xWasDelayed = pdFALSE;
// }
}
vTaskDelete(NULL);
}
static void Button(void* pvParameters) {
TickType_t xLastWakeTime;
const TickType_t xFrequency = pdMS_TO_TICKS(20);
BaseType_t xWasDelayed;
int button_current_state = 0;
// Initialise the xLastWakeTime variable with the current time.
xLastWakeTime = xTaskGetTickCount ();
for( ;; )
{
// Wait for the next cycle.
xWasDelayed = xTaskDelayUntil( &xLastWakeTime, xFrequency );
button_current_state = digitalRead(Button_pin);
if (button_current_state == HIGH) {
digitalWrite(Button_LED, HIGH);
}
else digitalWrite(Button_LED, LOW);
}
vTaskDelete(NULL);
}
static void Idle(void* pvParameters) {
int TaskIDLE_LED_state = 0;
for (;;)
{
TaskIDLE_LED_state = !TaskIDLE_LED_state;
digitalWrite(Idle_pin, TaskIDLE_LED_state);
//Serial << "Idling_free_task\n";
vTaskDelay(1);
}
vTaskDelete(NULL);
}
static void input_brightness_from_serial_monitor(void* pvParameters){
TickType_t xLastWakeTime;
const TickType_t xFrequency = pdMS_TO_TICKS(10);
BaseType_t xWasDelayed;
int birghtness = 0;
xLastWakeTime = xTaskGetTickCount ();
for(;;){
// Wait for the next cycle.
xWasDelayed = xTaskDelayUntil( &xLastWakeTime, xFrequency );
if (xSemaphoreTake(xSerialSemaphore, portMAX_DELAY) == pdTRUE) {
// Read the incoming data as a string
String inputString = Serial.readStringUntil('\n');
// Convert the string to an integer
blink_interval = inputString.toInt();
// Print the number back to the serial monitor
Serial.print("You entered: ");
Serial.println(blink_interval);
}
}
}
void serialEvent() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
// Give the semaphore to wake up Task 3
xSemaphoreGiveFromISR(xSerialSemaphore, &xHigherPriorityTaskWoken);
// Perform a context switch if necessary
if (xHigherPriorityTaskWoken) {
portYIELD_FROM_ISR();
}
}
*/
// #include <Streaming.h>
// const long baud_rate = 9600;
// const int led_pin = 10 ;
// bool led_STATE = false;
// const int button_reader = 5;
// const int button_led = 11;
// unsigned int currTime = 0;
// unsigned int prevTime = 0;
// unsigned int interval = 700;
// int button_state = 0;
// unsigned int loop_counter = 1;
// unsigned int currTime_2 = 0;
// unsigned int prevTime_2 = 0;
// unsigned int interval_2 = 100;
// void setup() {
// // put your setup code here, to run once:
// Serial.begin ( baud_rate );
// Serial.println ("In setup(). Please wait...");
// pinMode (led_pin, OUTPUT);
// pinMode(button_led, OUTPUT);
// pinMode(button_reader, INPUT);
// Serial.println("setup() is completed");
// digitalWrite(led_pin, LOW);
// delay(interval);
// }
// void loop(){
// currTime = millis();
// if (currTime - prevTime >= interval){
// prevTime = currTime;
// led_STATE = !led_STATE;
// digitalWrite(led_pin, led_STATE);
// }
// currTime_2 = millis();
// button_state = digitalRead(button_reader);
// if (currTime_2 - prevTime_2 >= interval_2){
// prevTime_2 = currTime_2;
// if ( button_state == HIGH ){
// digitalWrite(button_led, HIGH);
// Serial << "1. Button state = " << digitalRead(button_reader) << endl;
// }
// else if (button_state == LOW){
// digitalWrite(button_led, LOW);
// Serial << "2. Button state = " << digitalRead(button_reader) << endl;
// }
// }
// }
// void loop() {
// // put your main code here, to run repeatedly:
// currTime = millis();
// if (currTime - prevTime >= interval ) {
// prevTime = currTime;
// led_STATE = !led_STATE;
// digitalWrite (led_pin, led_STATE);
// if (led_STATE) {
// Serial.println("LED is on.");
// }
// else {
// Serial.println("LED is off.");
// }
// if (loop_counter == 1 ) {
// Serial << loop_counter << " loop has been done.\n";
// loop_counter++;
// }
// else {
// Serial << loop_counter << " loops has been done.\n";
// loop_counter++;
// //Serial.print(loop_counter);Serial.println(" loop(s) has been done.");
// }
// }
// }