// FreeRTOS with a mutex
//
// When a single device is shared by two tasks,
// and only one task can use it at a time,
// then a mutex can take care of it.
// The "hd44780" library is used for the display.
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
const int LCD_COLS = 16;
const int LCD_ROWS = 2;
hd44780_I2Cexp lcd;
const int blueLedPin = 7;
// The handle for the mutex.
SemaphoreHandle_t lcd_mutex;
void setup()
{
Serial.begin(115200);
pinMode(blueLedPin,OUTPUT);
// Do the initial setup of the display before starting the
// two tasks that use the display.
int result = lcd.begin(LCD_COLS, LCD_ROWS);
if(result!=0)
{
Serial.print("LCD initialization failed: ");
Serial.println(result);
hd44780::fatalError(result);
}
// Create a mutex in FreeRTOS.
lcd_mutex = xSemaphoreCreateMutex();
// Create two tasks.
xTaskCreate(TaskTime,"Time",2000,NULL,1,NULL);
xTaskCreate(TaskTemperature,"Temperature",2000,NULL,1,NULL);
}
void loop()
{
// Do something with the task running the Arduino loop().
digitalWrite(blueLedPin,HIGH);
delay(250);
digitalWrite(blueLedPin,LOW);
delay(750);
}
void TaskTime(void * pvParameters)
{
while(true)
{
// The mutex protects the display, so only one task
// can use at a time.
if( xSemaphoreTake(lcd_mutex,1000/portTICK_PERIOD_MS) == pdTRUE)
{
// Print exactly 16 characters to remove
// the previous written text without the need
// to clear the whole display.
lcd.setCursor(0,0);
lcd.printf("Time: %010ld",millis());
xSemaphoreGive(lcd_mutex);
}
// A delay of 100 millisconds, to update the display
// ten times per second.
// The liquid crystals of a LCD display are slow,
// a delay of 250 ms would be fast enough.
// This delay gives other tasks the possibility
// to claim the mutex.
delay(100);
}
}
void TaskTemperature(void * pvParameters)
{
while(true)
{
// The mutex protects the display, so only one task
// can use at a time.
if( xSemaphoreTake(lcd_mutex,1000/portTICK_PERIOD_MS) == pdTRUE)
{
int temperature = random(-99,99);
// Print exactly 16 characters to remove
// the previous written text without the need
// to clear the whole display.
lcd.setCursor(0,1);
lcd.printf("Temperature: %+02d",temperature);
xSemaphoreGive(lcd_mutex);
}
// A delay of 1000 ms to print the temperature
// once per second.
// This delay gives other tasks the possibility
// to claim the mutex.
delay(1000);
}
}
loop()
Demonstration of a mutex in FreeRTOS.