/* 
"2 Núcleos del ESP32 con FreeRTOS"

[OBJETIVO]: Comprender mejor el uso de FreeRTOS y de los conceptos que anteriormente has 
descrito, a través del diseño de un sistema capaz de:
a) Controlar el encendido y apagado de 3 LEDs mediante tareas independientes entre si 
   en UNO de los núcleos del ESP32.
b) Controlar el brillo de un LED amarillo empleando PWM, y teniendo como su variable de 
   control el voltaje en la terminal central de un potenciómetro conectado al pin GND 
   y al pin 3.3 V del ESP32. Este voltaje también se deberá imprimir en el monitor 
   serial del IDE. Todo este inciso b) deberá ejecutarse en el OTRO núcleo del ESP32.
c) El {LLM} deberá elegir cuál de los núcleos del ESP32 emplea para las tareas del 
   inciso a)  y cuál emplea para las tareas del inciso b).

[ESPECIFICACION FUNCIONAL]: Las características y componentes esenciales del sistema "2 
                            Núcleos del ESP32 con FreeRTOS" deberán ser:
a) {TARJETA DE DESARROLLO} :  ESP32 de 38 pines.
b) {LENGUAJE DE PROGRAMACIÓN} : El código deberá estar escrito en Lenguaje C++ optimizado 
   para el IDE de Arduino.
c) Los 3 LEDs que se han de controlar con tareas independientes pero en el mismo Núcleo 
   del ESP32 deberán ser :  Rojo, Azul y Verde y estar conectados en la {TARJETA DE 
  DESARROLLO} de la siguiente manera:  
   - LED Rojo al GPIO 17
   - LED Azul al GPIO 18
   - LED Verde al GPIO 19
d) Los tiempos de Encendido y Apagado de cada uno de los 3 LEDs deberán poderse establecer 
   mediante constantes en la parte inicial del código.
e) Para la primera prueba, establece los siguientes tiempo de Encendido / Apagado :
   - LED rojo:  0.3 seg / 1 seg
   - LED azul:  0.4 seg / 0.4 seg
   - LED verde:  2.3 seg / 0.7 seg
f) El GPIO del ESP32 al que se deberá conectar la terminal central del potenciómetro es el 34.
g) El GPIO 32 del ESP32 se empleará para conectar el LED amarillo cuyo brillo será controlado 
   mediante PWM.
h) En el OTRO NÚCLEO del ESP32 deberá programarse una sola tarea controlada por FreeRTOS,  
   independiente de las 3 tareas anteriores con los LEDs, esta tarea deberá cumplir con :
   - Leer la terminal central del potenciómetro con el ESP32.
   - Con el valor de lectura anterior, controlar el brillo del LED amarillo con PWM.
i) En el void loop() se deberá convertir la lectura de la terminal central del potenciómetro 
   a voltaje ( deberá estar en un rango de 0 a 3.3 V) y mostrar el valor de ese voltaje 
   en el monitor serial del IDE.

Autor: ChatGPT plus
Revisión y corrección: MC. Rodolfo Fernando Porras Sánchez
Versión 1.0   13 de Enero 2024 
*/

// Definición de pines
const int pinLedRojo = 17;
const int pinLedAzul = 18;
const int pinLedVerde = 19;
const int pinLedAmarillo = 32;
const int pinPotenciometro = 34;

// Tiempos de encendido y apagado (milisegundos)
const int tiempoEncendidoRojo = 300;
const int tiempoApagadoRojo = 1000;
const int tiempoEncendidoAzul = 400;
const int tiempoApagadoAzul = 400;
const int tiempoEncendidoVerde = 2300;
const int tiempoApagadoVerde = 700;

// Prototipos de las funciones de las tareas
void tareaLedRojo(void *pvParameters);
void tareaLedAzul(void *pvParameters);
void tareaLedVerde(void *pvParameters);
void tareaControlPWM(void *pvParameters);

void setup() {
  Serial.begin(115200);

  // Configurar pines de LEDs como salidas
  pinMode(pinLedRojo, OUTPUT);
  pinMode(pinLedAzul, OUTPUT);
  pinMode(pinLedVerde, OUTPUT);
  pinMode(pinLedAmarillo, OUTPUT);

  // Configuración del PWM para el LED amarillo
  ledcAttachPin(pinLedAmarillo, 0);
  ledcSetup(0, 5000, 8);

  // Crear tareas y asignarlas a los núcleos
  xTaskCreatePinnedToCore(tareaLedRojo, "TareaLedRojo", 1000, NULL, 1, NULL, 1);
  xTaskCreatePinnedToCore(tareaLedAzul, "TareaLedAzul", 1000, NULL, 1, NULL, 1);
  xTaskCreatePinnedToCore(tareaLedVerde, "TareaLedVerde", 1000, NULL, 1, NULL, 1);
  xTaskCreatePinnedToCore(tareaControlPWM, "TareaControlPWM", 1000, NULL, 1, NULL, 0);
}

void loop() {
  int valorPot = analogRead(pinPotenciometro);
  float voltaje = (valorPot / 4095.0) * 3.3;
  Serial.print("Voltaje Potenciometro: ");
  Serial.println(voltaje, 3);
  delay(1000);
}

// Funciones de las tareas
void tareaLedRojo(void *pvParameters) {
  for (;;) {
    digitalWrite(pinLedRojo, HIGH);
    vTaskDelay(tiempoEncendidoRojo / portTICK_PERIOD_MS);
    digitalWrite(pinLedRojo, LOW);
    vTaskDelay(tiempoApagadoRojo / portTICK_PERIOD_MS);
  }
}

void tareaLedAzul(void *pvParameters) {
  for (;;) {
    digitalWrite(pinLedAzul, HIGH);
    vTaskDelay(tiempoEncendidoAzul / portTICK_PERIOD_MS);
    digitalWrite(pinLedAzul, LOW);
    vTaskDelay(tiempoApagadoAzul / portTICK_PERIOD_MS);
  }
}

void tareaLedVerde(void *pvParameters) {
  for (;;) {
    digitalWrite(pinLedVerde, HIGH);
    vTaskDelay(tiempoEncendidoVerde / portTICK_PERIOD_MS);
    digitalWrite(pinLedVerde, LOW);
    vTaskDelay(tiempoApagadoVerde / portTICK_PERIOD_MS);
  }
}

void tareaControlPWM(void *pvParameters) {
  for (;;) {
    int valorPot = analogRead(pinPotenciometro);
    int brilloLed = map(valorPot, 0, 4095, 0, 255);
    ledcWrite(0, brilloLed);
    vTaskDelay(10 / portTICK_PERIOD_MS);
  }
}
Loading
esp32-devkit-c-v4