Managing multiple tasks using Arduino and FreeRTOS

So, I’m trying to implement a code for Arduino, that reads the values of a humidity sensor, a temperature sensor and based on that opens and closes a water valve, all of this is working great, but the problem shows up when I try to show this data on the LCD display that uses I2C protocol with the LiquidCrystal library, I’ve been attempting with queues, but when I implement it everything stops working, I don’t know if this is a Starvation issue or something else, without FreeRTOS it does works.

I’m attaching the code below because I can’t upload files:

#include <LiquidCrystal_I2C.h>
#include <Arduino_FreeRTOS.h>
#include <task.h>
#include <Wire.h>
#include <queue.h>

// Pin definitions
#define LED_PIN 13

// LCD configuration
LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address 0x27, 16 columns, 2 rows

// Global variables
float moistureReading = 0.0;
float temperatureReading = 0.0;
bool valveState = false;
const int AirValue = 452;   // You need to replace this value with Value_1
const int WaterValue = 220;  // You need to replace this value with Value_2
int soilMoistureValue = 0;
int soilMoisturePercent = 0;

void moistureTask( void *pvParameters );
void temperatureTask( void *pvParameters );
void controlTask( void *pvParameters );
void ledTask( void *pvParameters );
void lcdTask( void *pvParameters );

// Tamaño de la cola
#define QUEUE_SIZE 5

// Declaración de la cola
QueueHandle_t queue;

void setup(){


  queue = xQueueCreate(QUEUE_SIZE, sizeof(int));

  xTaskCreate(moistureTask,"Task 1",128,NULL,1,NULL);
  xTaskCreate(temperatureTask,"Task 2",128,NULL,1,NULL);
  xTaskCreate(lcdTask,"Task 5",128,NULL,1,NULL);
  xTaskCreate(controlTask,"Task 3",128,NULL,3,NULL);
  xTaskCreate(ledTask,"Task 4",128,NULL,2,NULL);

void loop (){


void moistureTask(void *pvParameters){
  while(1) {
    int soilMoistureValue = analogRead(MOISTURE_SENSOR_PIN);

    soilMoisturePercent = map(soilMoistureValue, AirValue, WaterValue, 0, 100);
    xQueueSend(queue, &soilMoistureValue, portMAX_DELAY);

    if (soilMoisturePercent >= 100) {
    else if (soilMoisturePercent <= 0) {
    else if (soilMoisturePercent > 0 && soilMoisturePercent < 100) {

    vTaskDelay(pdMS_TO_TICKS(500)); // Delay 500ms

void temperatureTask(void *pvParameters){
    while(1) {
    int sensorValue = analogRead(TEMPERATURE_SENSOR_PIN);
    temperatureReading = (sensorValue * 5.0 / 1024.0) * 100.0;
    Serial.print("Temperature: ");

    vTaskDelay(pdMS_TO_TICKS(500)); // Delay 0.5s

void controlTask(void *pvParameters){
    while(1) {
    if (soilMoisturePercent < 30) {
      valveState = true;
      Serial.println("Valve is open");
    } else {
      valveState = false;
      Serial.println("Valve is closed");

    vTaskDelay(pdMS_TO_TICKS(100)); // Delay 100ms

void ledTask(void *pvParameters){
    while(1) {
    // Update LED based on valve state
    if (valveState) {
      digitalWrite(LED_PIN, HIGH);
    } else {
      digitalWrite(LED_PIN, LOW);

    vTaskDelay(pdMS_TO_TICKS(100)); // Delay 100ms

// Tarea que lee el valor de la cola y lo muestra en la pantalla LCD
void lcdTask(void *pvParameters) {
  while (1) {
    int receivedValue;
    if (xQueueReceive(queue, &receivedValue, portMAX_DELAY)) {
      lcd.setCursor(7, 0); // Posición en la pantalla para mostrar el valor

Have you tried increasing the stack size of the tasks, especially the LCD task. Depending on the implementation of the LCD library it might be consuming more stack size than128 words.

Just tried that, still doesn’t work

Hi @jsfw7698,
Do you enable configASSERT and configCHECK_FOR_STACK_OVERFLOW?
These two options help a lot to capture the problem in early stage.


How much did you increase? Can you break the code in the debugger and see what it is doing when it appears hang?