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 MOISTURE_SENSOR_PIN A0
#define TEMPERATURE_SENSOR_PIN A1
#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(){
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode(LED_PIN,OUTPUT);
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);
vTaskStartScheduler();
}
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) {
Serial.println("100%");
}
else if (soilMoisturePercent <= 0) {
Serial.println("0%");
}
else if (soilMoisturePercent > 0 && soilMoisturePercent < 100) {
Serial.print(soilMoisturePercent);
Serial.println("%");
}
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: ");
Serial.println(temperatureReading);
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
lcd.print(receivedValue);
}
}
}