/*
const int pinLedRojo = 32;
const int pinLedAzul = 18;
const int pinLedVerde = 19;
const int pinPotenciometro = 34;
const int pinBoton = 33;
int valorBoton = 0;
SemaphoreHandle_t xMutex;
// Variable para indicar si los LEDs deben apagarse
bool apagarLEDs = false;
// Estado actual de los LEDs
bool estadoLedAzul = false;
bool estadoLedVerde = false;
// Tiempos de encendido y apagado (milisegundos)
const int tiempoEncendidoAzul = 300;
const int tiempoApagadoAzul = 300;
const int tiempoEncendidoVerde = 1000;
const int tiempoApagadoVerde = 1000;
// Prototipos de las funciones de las tareas
void tareaLedAzul(void *pvParameters);
void tareaLedVerde(void *pvParameters);
void tareaControlPWM(void *pvParameters);
void tareaControlBoton(void *pvParameters);
void setup() {
Serial.begin(115200);
// Configurar pines de LEDs como salidas
pinMode(pinLedRojo, OUTPUT);
pinMode(pinLedAzul, OUTPUT);
pinMode(pinLedVerde, OUTPUT);
pinMode(pinBoton, INPUT_PULLUP);
// Configuración del PWM para el LED rojo
ledcAttachPin(pinLedRojo, 0);
ledcSetup(0, 5000, 8);
// Crear semáforo para la comunicación
xMutex = xSemaphoreCreateMutex();
// Crear tareas y asignarlas a los núcleos
xTaskCreatePinnedToCore(tareaLedAzul, "TareaLedAzul", 1000, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(tareaLedVerde, "TareaLedVerde", 1000, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(tareaControlPWM, "TareaControlPWM", 1000, NULL, 1, NULL, 0);
xTaskCreatePinnedToCore(tareaControlBoton, "TareaControlBoton", 1000, NULL, 2, NULL, 0);
}
void loop() {
int valorPot = analogRead(pinPotenciometro);
float voltaje = (valorPot / 4095.0) * 3.3;
Serial.print("Voltaje Potenciometro: ");
Serial.print(voltaje, 3);
delay(1000);
}
// Funciones de las tareas
void tareaLedVerde(void *pvParameters) {
for (;;) {
if (xSemaphoreTake(xMutex, portMAX_DELAY)) {
// Verificar si se debe apagar el LED verde
if (apagarLEDs) {
estadoLedVerde = false;
digitalWrite(pinLedVerde, LOW);
} else {
// Encender el LED verde
estadoLedVerde = true;
//le añadi esto
digitalWrite(pinLedVerde, HIGH);
vTaskDelay(tiempoEncendidoVerde / portTICK_PERIOD_MS);
digitalWrite(pinLedVerde, LOW);
vTaskDelay(tiempoApagadoVerde/ portTICK_PERIOD_MS);
}
xSemaphoreGive(xMutex);
}
vTaskDelay(estadoLedVerde ? tiempoEncendidoVerde : tiempoApagadoVerde / portTICK_PERIOD_MS);
}
}
void tareaLedAzul(void *pvParameters) {
for (;;) {
if (xSemaphoreTake(xMutex, portMAX_DELAY)) {
// Verificar si se debe apagar el LED azul
if (apagarLEDs) {
estadoLedAzul = false;
digitalWrite(pinLedAzul, LOW);
} else {
// Encender el LED azul
estadoLedAzul = true;
digitalWrite(pinLedAzul, HIGH);
vTaskDelay(tiempoEncendidoAzul / portTICK_PERIOD_MS);
digitalWrite(pinLedAzul, LOW);
vTaskDelay(tiempoApagadoAzul / portTICK_PERIOD_MS);
}
xSemaphoreGive(xMutex);
}
vTaskDelay(estadoLedAzul ? tiempoEncendidoAzul : tiempoApagadoAzul / 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);
}
}
void tareaControlBoton(void *pvParameters) {
for (;;) {
valorBoton = digitalRead(pinBoton);
if (valorBoton == 0) {
Serial.println("Se oprimió el botón");
// Adquirir el semáforo antes de modificar la variable apagarLEDs
if (xSemaphoreTake(xMutex, portMAX_DELAY)) {
// Invertir el valor de apagarLEDs
apagarLEDs = !apagarLEDs;
xSemaphoreGive(xMutex);
// Esperar a que el botón sea liberado antes de continuar
while (digitalRead(pinBoton) == 0) {
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
} else {
Serial.println("No se ha oprimido el botón");
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
*/
//----------------------------------------------
/*
#include <Arduino.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/semphr.h>
// Definición de pines
#define BUTTON_PIN 33
#define GREEN_LED_PIN 19
#define BLUE_LED_PIN 18
// Definición de tiempos
#define GREEN_LED_ON_TIME 1000
#define GREEN_LED_OFF_TIME 1000
#define BLUE_LED_ON_TIME 300
#define BLUE_LED_OFF_TIME 300
// Variables globales y semáforos
SemaphoreHandle_t buttonSemaphore;
bool ledsOn = true;
// Funciones de los dos núcleos
void buttonTask(void *parameter);
void ledsTask(void *parameter);
void setup() {
Serial.begin(115200);
// Configurar el botón como entrada con pull-up
pinMode(BUTTON_PIN, INPUT_PULLUP);
// Configurar los LEDs como salidas
pinMode(GREEN_LED_PIN, OUTPUT);
pinMode(BLUE_LED_PIN, OUTPUT);
// Crear el semáforo
buttonSemaphore = xSemaphoreCreateBinary();
// Crear tareas
xTaskCreate(buttonTask, "ButtonTask", 2048, NULL, 1, NULL);
xTaskCreate(ledsTask, "LedsTask", 2048, NULL, 1, NULL);
}
void loop() {
// No hay código en el loop principal
}
void buttonTask(void *parameter) {
while (1) {
// Esperar a que se presione el botón
if (digitalRead(BUTTON_PIN) == LOW) {
delay(50); // Antirrebote
if (digitalRead(BUTTON_PIN) == LOW) {
// Cambiar el estado de los LEDs
ledsOn = !ledsOn;
if (ledsOn) {
Serial.println("LEDs Encendidos");
} else {
Serial.println("LEDs Apagados");
}
// Notificar a la tarea de los LEDs usando el semáforo
xSemaphoreGive(buttonSemaphore);
}
while (digitalRead(BUTTON_PIN) == LOW) {
// Esperar a que se libere el botón
delay(10);
}
}
delay(10);
}
}
void ledsTask(void *parameter) {
while (1) {
if (ledsOn) {
// Encender y apagar el LED verde
digitalWrite(GREEN_LED_PIN, HIGH);
delay(GREEN_LED_ON_TIME);
digitalWrite(GREEN_LED_PIN, LOW);
delay(GREEN_LED_OFF_TIME);
// Encender y apagar el LED azul
digitalWrite(BLUE_LED_PIN, HIGH);
delay(BLUE_LED_ON_TIME);
digitalWrite(BLUE_LED_PIN, LOW);
delay(BLUE_LED_OFF_TIME);
} else {
// Si los LEDs están apagados, esperar la señal del botón
xSemaphoreTake(buttonSemaphore, portMAX_DELAY);
}
}
}
*/
/*
#include <Arduino.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
// Definición de pines
#define PIN_LED_VERDE 19
#define PIN_LED_AZUL 18
// Prototipos de funciones
void tareaLedVerde(void *parameter);
void tareaLedAzul(void *parameter);
void setup() {
// Configuración de pines
pinMode(PIN_LED_VERDE, OUTPUT);
pinMode(PIN_LED_AZUL, OUTPUT);
// Creación de tareas
xTaskCreatePinnedToCore(tareaLedVerde, "LedVerdeTask", 1000, NULL, 1, NULL, 0);
xTaskCreatePinnedToCore(tareaLedAzul, "LedAzulTask", 1000, NULL, 1, NULL, 0);
}
void loop() {
// No es necesario colocar código aquí cuando se usa FreeRTOS
}
void tareaLedVerde(void *parameter) {
while (1) {
// Encender el LED verde durante 1 segundo
digitalWrite(PIN_LED_VERDE, HIGH);
delay(1000);
// Apagar el LED verde durante 1 segundo
digitalWrite(PIN_LED_VERDE, LOW);
delay(1000);
}
}
void tareaLedAzul(void *parameter) {
while (1) {
// Encender el LED azul durante 3 milisegundos
digitalWrite(PIN_LED_AZUL, HIGH);
delay(3);
// Apagar el LED azul durante 300 milisegundos
digitalWrite(PIN_LED_AZUL, LOW);
delay(300);
}
}*/
/*-------------------------------------------
#include <Arduino.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
// Definición de pines
#define PIN_BOTON 33
// Prototipo de función
void tareaBoton(void *parameter);
void setup() {
// Configuración de pines
pinMode(PIN_BOTON, INPUT_PULLUP);
Serial.begin(115200);
// Creación de tarea para el botón
xTaskCreatePinnedToCore(tareaBoton, "BotonTask", 1000, NULL, 1, NULL, 1);
}
void loop() {
// No es necesario colocar código aquí cuando se usa FreeRTOS
}
void tareaBoton(void *parameter) {
while (1) {
// Verificar si el botón ha sido oprimido (nivel bajo)
if (digitalRead(PIN_BOTON) == LOW) {
// Imprimir mensaje en el Monitor Serie
Serial.println("Se ha oprimido el botón");
// Esperar un breve tiempo para evitar múltiples detecciones rápidas
}
// Pausa para evitar saturar la CPU
}
}*/
/*-------------------------------------
#include <Arduino.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
// Definición de pines
#define PIN_LED_VERDE 19
#define PIN_LED_AZUL 18
#define PIN_BOTON 33
// Variables para controlar el estado de los LEDs
bool ledsActivos = true;
// Prototipos de funciones
void tareaLeds(void *parameter);
void tareaBoton(void *parameter);
void setup() {
// Inicialización del Monitor Serie
Serial.begin(115200);
// Configuración de pines
pinMode(PIN_LED_VERDE, OUTPUT);
pinMode(PIN_LED_AZUL, OUTPUT);
pinMode(PIN_BOTON, INPUT_PULLUP);
// Creación de tarea para los LEDs
xTaskCreatePinnedToCore(tareaLeds, "LedsTask", 1000, NULL, 1, NULL, 0);
// Creación de tarea para el botón
xTaskCreatePinnedToCore(tareaBoton, "BotonTask", 1000, NULL, 1, NULL, 1);
}
void loop() {
// No es necesario colocar código aquí cuando se usa FreeRTOS
}
void tareaLeds(void *parameter) {
while (1) {
if (ledsActivos) {
// Encender el LED verde durante 1 segundo
digitalWrite(PIN_LED_VERDE, HIGH);
delay(1000);
// Apagar el LED verde durante 1 segundo
digitalWrite(PIN_LED_VERDE, LOW);
delay(1000);
// Encender el LED azul durante 3 milisegundos
digitalWrite(PIN_LED_AZUL, HIGH);
delay(3);
// Apagar el LED azul durante 3 milisegundos
digitalWrite(PIN_LED_AZUL, LOW);
delay(3);
} else {
// Apagar ambos LEDs si están desactivados
digitalWrite(PIN_LED_VERDE, LOW);
digitalWrite(PIN_LED_AZUL, LOW);
}
}
}
void tareaBoton(void *parameter) {
bool botonAnterior = HIGH; // Estado previo del botón
while (1) {
// Verificar si el botón ha sido oprimido (flanco de bajada)
if (digitalRead(PIN_BOTON) == LOW && botonAnterior == HIGH) {
// Cambiar el estado de los LEDs
ledsActivos = !ledsActivos;
// Imprimir mensaje en el Monitor Serie
if (ledsActivos) {
Serial.println("Se ha reanudado el parpadeo de los LEDs");
} else {
Serial.println("Se han apagado los LEDs");
}
// Esperar un breve tiempo para evitar múltiples detecciones rápidas
delay(500);
}
// Actualizar el estado previo del botón
botonAnterior = digitalRead(PIN_BOTON);
// Pausa para evitar saturar la CPU
delay(10);
}
}
*/
/*#include <Arduino.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
// Definición de pines
#define PIN_LED_VERDE 19
#define PIN_LED_AZUL 18
#define PIN_BOTON 33
// Variables para controlar el estado de los LEDs y el botón
bool ledsActivos = true;
bool botonAnterior = HIGH; // Estado previo del botón
// Prototipos de funciones
void tareaLeds(void *parameter);
void tareaBoton(void *parameter);
// Variables para temporizadores de hardware
hw_timer_t *timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
volatile uint32_t verdeStartMillis = 0;
volatile uint32_t azulStartMillis = 0;
void IRAM_ATTR onTimer() {
portENTER_CRITICAL_ISR(&timerMux);
if (ledsActivos) {
// Manejar LED verde
if (millis() - verdeStartMillis >= 1000) {
digitalWrite(PIN_LED_VERDE, !digitalRead(PIN_LED_VERDE));
verdeStartMillis = millis();
}
// Manejar LED azul
if (millis() - azulStartMillis >= 300) {
digitalWrite(PIN_LED_AZUL, !digitalRead(PIN_LED_AZUL));
azulStartMillis = millis();
}
} else {
// Apagar ambos LEDs si están desactivados
digitalWrite(PIN_LED_VERDE, LOW);
digitalWrite(PIN_LED_AZUL, LOW);
}
portEXIT_CRITICAL_ISR(&timerMux);
}
void setup() {
// Inicialización del Monitor Serie
Serial.begin(115200);
// Configuración de pines
pinMode(PIN_LED_VERDE, OUTPUT);
pinMode(PIN_LED_AZUL, OUTPUT);
pinMode(PIN_BOTON, INPUT_PULLUP);
// Configurar y habilitar el temporizador de hardware
timer = timerBegin(0, 80, true); // Timer 0, prescaler 80 (divide la frecuencia de la CPU por 80)
timerAttachInterrupt(timer, &onTimer, true); // true para llamar la interrupción en modo ascendente
timerAlarmWrite(timer, 1000, true); // Configurar el temporizador para que llame a la interrupción cada 1000 microsegundos (1 ms)
timerAlarmEnable(timer); // Habilitar el temporizador
// Creación de tarea para el botón
xTaskCreatePinnedToCore(tareaBoton, "BotonTask", 1000, NULL, 1, NULL, 1);
}
void loop() {
// No es necesario colocar código aquí cuando se usa FreeRTOS
}
void tareaBoton(void *parameter) {
while (1) {
// Verificar si el botón ha sido oprimido (flanco de bajada)
if (digitalRead(PIN_BOTON) == LOW && botonAnterior == HIGH) {
// Cambiar el estado de los LEDs
ledsActivos = !ledsActivos;
// Imprimir mensaje en el Monitor Serie
if (ledsActivos) {
Serial.println("Se ha reanudado el parpadeo de los LEDs");
} else {
Serial.println("Se han apagado los LEDs");
}
// Esperar un breve tiempo para evitar múltiples detecciones rápidas
vTaskDelay(500 / portTICK_PERIOD_MS);
}
// Actualizar el estado previo del botón
botonAnterior = digitalRead(PIN_BOTON);
// Pausa para evitar saturar la CPU
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
*/
/*
// Definición de pines
#define PIN_LED_VERDE 19
#define PIN_LED_AZUL 18
#define PIN_BOTON 33
const int pinLedRojo = 32;
const int pinPotenciometro = 34;
// Variables para controlar el estado de los LEDs y el botón
bool ledsActivos = true;
bool botonAnterior = HIGH; // Estado previo del botón
void tareaControlPWM(void *pvParameters);
// Definición de pines
#define PIN_LED_ROJO 2
#define PIN_POTENCIOMETRO 34
// Variables globales
int valorPotenciometro = 0;
SemaphoreHandle_t potenciometroSemaphore;
// Prototipos de funciones
void tareaLeds(void *parameter);
void tareaBoton(void *parameter);
void tareaPotenciometro(void *parameter);
void tareaLedRojo(void *parameter);
// Variables para temporizadores de hardware
hw_timer_t *timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
volatile uint32_t verdeStartMillis = 0;
volatile uint32_t azulStartMillis = 0;
void IRAM_ATTR onTimer() {
portENTER_CRITICAL_ISR(&timerMux);
if (ledsActivos) {
// Manejar LED verde
if (millis() - verdeStartMillis >= 1000) {
digitalWrite(PIN_LED_VERDE, !digitalRead(PIN_LED_VERDE));
verdeStartMillis = millis();
}
// Manejar LED azul
if (millis() - azulStartMillis >= 300) {
digitalWrite(PIN_LED_AZUL, !digitalRead(PIN_LED_AZUL));
azulStartMillis = millis();
}
} else {
// Apagar ambos LEDs si están desactivados
digitalWrite(PIN_LED_VERDE, LOW);
digitalWrite(PIN_LED_AZUL, LOW);
}
portEXIT_CRITICAL_ISR(&timerMux);
}
void setup() {
// Inicialización del Monitor Serie
Serial.begin(115200);
// Configuración de pines
pinMode(PIN_LED_VERDE, OUTPUT);
pinMode(PIN_LED_AZUL, OUTPUT);
pinMode(PIN_BOTON, INPUT_PULLUP);
pinMode(pinLedRojo, OUTPUT);
pinMode(PIN_LED_ROJO, OUTPUT);
// Configuración del PWM para el LED rojo
ledcAttachPin(pinLedRojo, 0);
ledcSetup(0, 5000, 8);
// Configurar y habilitar el temporizador de hardware
timer = timerBegin(0, 80, true); // Timer 0, prescaler 80 (divide la frecuencia de la CPU por 80)
timerAttachInterrupt(timer, &onTimer, true); // true para llamar la interrupción en modo ascendente
timerAlarmWrite(timer, 1000, true); // Configurar el temporizador para que llame a la interrupción cada 1000 microsegundos (1 ms)
timerAlarmEnable(timer); // Habilitar el temporizador
// Creación de tarea para el botón
xTaskCreatePinnedToCore(tareaBoton, "BotonTask", 1000, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(tareaControlPWM, "TareaControlPWM", 1000, NULL, 1, NULL, 0);
// Creación de semáforo
potenciometroSemaphore = xSemaphoreCreateMutex();
// Creación de tarea para el potenciómetro (núcleo 1)
xTaskCreatePinnedToCore(tareaPotenciometro, "PotenciometroTask", 1000, NULL, 1, NULL, 1);
// Creación de tarea para el LED rojo (núcleo 0)
xTaskCreatePinnedToCore(tareaLedRojo, "LedRojoTask", 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);
}
void tareaBoton(void *parameter) {
while (1) {
// Verificar si el botón ha sido oprimido (flanco de bajada)
if (digitalRead(PIN_BOTON) == LOW && botonAnterior == HIGH) {
// Cambiar el estado de los LEDs
ledsActivos = !ledsActivos;
// Imprimir mensaje en el Monitor Serie
if (ledsActivos) {
Serial.println("Se ha reanudado el parpadeo de los LEDs");
} else {
Serial.println("Se han apagado los LEDs");
}
// Esperar un breve tiempo para evitar múltiples detecciones rápidas
vTaskDelay(500 / portTICK_PERIOD_MS);
}
// Actualizar el estado previo del botón
botonAnterior = digitalRead(PIN_BOTON);
// Pausa para evitar saturar la CPU
vTaskDelay(10 / 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);
}
}
void tareaPotenciometro(void *parameter) {
while (1) {
// Leer el valor del potenciómetro
int nuevoValor = analogRead(PIN_POTENCIOMETRO);
// Adquirir el semáforo para actualizar el valorPotenciometro de manera segura
if (xSemaphoreTake(potenciometroSemaphore, portMAX_DELAY) == pdTRUE) {
valorPotenciometro = nuevoValor;
// Liberar el semáforo
xSemaphoreGive(potenciometroSemaphore);
}
// Esperar un breve tiempo para evitar lecturas muy rápidas
vTaskDelay(50 / portTICK_PERIOD_MS);
}
}
void tareaLedRojo(void *parameter) {
while (1) {
// Adquirir el semáforo para leer el valorPotenciometro de manera segura
if (xSemaphoreTake(potenciometroSemaphore, portMAX_DELAY) == pdTRUE) {
// Escalar el valor del potenciómetro al rango adecuado para analogWrite (0-255)
int valorEscalado = map(valorPotenciometro, 0, 4095, 0, 255);
// Intensificar el brillo del LED rojo según el valor del potenciómetro
analogWrite(PIN_LED_ROJO, valorEscalado);
// Liberar el semáforo
xSemaphoreGive(potenciometroSemaphore);
}
// Esperar un breve tiempo para evitar cambios muy rápidos en el brillo
vTaskDelay(50 / portTICK_PERIOD_MS);
}
}
*/
/*
// Definición de pines
#define PIN_LED_VERDE 19
#define PIN_LED_AZUL 18
#define PIN_BOTON 33
const int pinLedRojo = 32;
const int pinPotenciometro = 34;
// Variables para controlar el estado de los LEDs y el botón
bool ledsActivos = true;
bool botonAnterior = HIGH; // Estado previo del botón
void tareaControlPWM(void *pvParameters);
// Definición de pines
#define PIN_LED_ROJO 2
#define PIN_POTENCIOMETRO 34
// Variables globales
int valorPotenciometro = 0;
SemaphoreHandle_t potenciometroSemaphore;
// Prototipos de funciones
void tareaLeds(void *parameter);
void tareaBoton(void *parameter);
void tareaPotenciometro(void *parameter);
void tareaLedRojo(void *parameter);
// Variables para temporizadores de hardware
hw_timer_t *timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
volatile uint32_t verdeStartMillis = 0;
volatile uint32_t azulStartMillis = 0;
void IRAM_ATTR onTimer() {
portENTER_CRITICAL_ISR(&timerMux);
if (ledsActivos) {
// Manejar LED verde
if (millis() - verdeStartMillis >= 1000) {
digitalWrite(PIN_LED_VERDE, !digitalRead(PIN_LED_VERDE));
verdeStartMillis = millis();
}
// Manejar LED azul
if (millis() - azulStartMillis >= 300) {
digitalWrite(PIN_LED_AZUL, !digitalRead(PIN_LED_AZUL));
azulStartMillis = millis();
}
} else {
// Apagar ambos LEDs si están desactivados
digitalWrite(PIN_LED_VERDE, LOW);
digitalWrite(PIN_LED_AZUL, LOW);
}
portEXIT_CRITICAL_ISR(&timerMux);
}
void setup() {
// Inicialización del Monitor Serie
Serial.begin(115200);
// Configuración de pines
pinMode(PIN_LED_VERDE, OUTPUT);
pinMode(PIN_LED_AZUL, OUTPUT);
pinMode(PIN_BOTON, INPUT_PULLUP);
pinMode(pinLedRojo, OUTPUT);
pinMode(PIN_LED_ROJO, OUTPUT);
// Configuración del PWM para el LED rojo
ledcAttachPin(pinLedRojo, 0);
ledcSetup(0, 5000, 8);
// Configurar y habilitar el temporizador de hardware
timer = timerBegin(0, 80, true); // Timer 0, prescaler 80 (divide la frecuencia de la CPU por 80)
timerAttachInterrupt(timer, &onTimer, true); // true para llamar la interrupción en modo ascendente
timerAlarmWrite(timer, 1000, true); // Configurar el temporizador para que llame a la interrupción cada 1000 microsegundos (1 ms)
timerAlarmEnable(timer); // Habilitar el temporizador
// Creación de tarea para el botón
xTaskCreatePinnedToCore(tareaBoton, "BotonTask", 1000, NULL, 1, NULL, 0);
xTaskCreatePinnedToCore(tareaControlPWM, "TareaControlPWM", 1000, NULL, 1, NULL, 0);
// Creación de semáforo
potenciometroSemaphore = xSemaphoreCreateMutex();
// Creación de tarea para el potenciómetro (núcleo 1)
xTaskCreatePinnedToCore(tareaPotenciometro, "PotenciometroTask", 1000, NULL, 1, NULL, 1);
// Creación de tarea para el LED rojo (núcleo 0)
xTaskCreatePinnedToCore(tareaLedRojo, "LedRojoTask", 1000, NULL, 1, NULL, 0);
}
void loop() {
}
void tareaBoton(void *parameter) {
while (1) {
// Verificar si el botón ha sido oprimido (flanco de bajada)
if (digitalRead(PIN_BOTON) == LOW && botonAnterior == HIGH) {
// Cambiar el estado de los LEDs
ledsActivos = !ledsActivos;
// Imprimir mensaje en el Monitor Serie
if (ledsActivos) {
Serial.println("Se ha reanudado el parpadeo de los LEDs");
} else {
Serial.println("Se han apagado los LEDs");
}
// Esperar un breve tiempo para evitar múltiples detecciones rápidas
vTaskDelay(500 / portTICK_PERIOD_MS);
}
// Actualizar el estado previo del botón
botonAnterior = digitalRead(PIN_BOTON);
// Pausa para evitar saturar la CPU
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
void tareaPotenciometro(void *parameter) {
while (1) {
// Leer el valor del potenciómetro
int nuevoValor = analogRead(PIN_POTENCIOMETRO);
// Adquirir el semáforo para actualizar el valorPotenciometro de manera segura
if (xSemaphoreTake(potenciometroSemaphore, portMAX_DELAY) == pdTRUE) {
valorPotenciometro = nuevoValor;
// Liberar el semáforo
xSemaphoreGive(potenciometroSemaphore);
}
// Esperar un breve tiempo para evitar lecturas muy rápidas
vTaskDelay(50 / portTICK_PERIOD_MS);
}
}
void tareaLedRojo(void *parameter) {
while (1) {
// Adquirir el semáforo para leer el valorPotenciometro de manera segura
if (xSemaphoreTake(potenciometroSemaphore, portMAX_DELAY) == pdTRUE) {
// Escalar el valor del potenciómetro al rango adecuado para analogWrite (0-255)
int valorEscalado = map(valorPotenciometro, 0, 4095, 0, 255);
// Intensificar el brillo del LED rojo según el valor del potenciómetro
analogWrite(PIN_LED_ROJO, valorEscalado);
// Liberar el semáforo
xSemaphoreGive(potenciometroSemaphore);
}
// Esperar un breve tiempo para evitar cambios muy rápidos en el brillo
vTaskDelay(50 / portTICK_PERIOD_MS);
}
}
*/
#include <Arduino.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
// Definición de pines
#define PIN_LED_VERDE 19
#define PIN_LED_AZUL 18
#define PIN_BOTON 33
// Variables para controlar el estado de los LEDs y el botón
bool ledsActivos = true;
bool botonAnterior = HIGH; // Estado previo del botón
void tareaControlPWM(void *pvParameters);
// Prototipos de funciones
void tareaLeds(void *parameter);
void tareaBoton(void *parameter);
// Variables para temporizadores de hardware
hw_timer_t *timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
volatile uint32_t verdeStartMillis = 0;
volatile uint32_t azulStartMillis = 0;
void IRAM_ATTR onTimer() {
portENTER_CRITICAL_ISR(&timerMux);
if (ledsActivos) {
// Manejar LED verde
if (millis() - verdeStartMillis >= 1000) {
digitalWrite(PIN_LED_VERDE, !digitalRead(PIN_LED_VERDE));
verdeStartMillis = millis();
}
// Manejar LED azul
if (millis() - azulStartMillis >= 300) {
digitalWrite(PIN_LED_AZUL, !digitalRead(PIN_LED_AZUL));
azulStartMillis = millis();
}
} else {
// Apagar ambos LEDs si están desactivados
digitalWrite(PIN_LED_VERDE, LOW);
digitalWrite(PIN_LED_AZUL, LOW);
}
portEXIT_CRITICAL_ISR(&timerMux);
}
void setup() {
// Inicialización del Monitor Serie
Serial.begin(115200);
// Configuración de pines
pinMode(PIN_LED_VERDE, OUTPUT);
pinMode(PIN_LED_AZUL, OUTPUT);
pinMode(PIN_BOTON, INPUT_PULLUP);
// Configurar y habilitar el temporizador de hardware
timer = timerBegin(0, 80, true); // Timer 0, prescaler 80 (divide la frecuencia de la CPU por 80)
timerAttachInterrupt(timer, &onTimer, true); // true para llamar la interrupción en modo ascendente
timerAlarmWrite(timer, 1000, true); // Configurar el temporizador para que llame a la interrupción cada 1000 microsegundos (1 ms)
timerAlarmEnable(timer); // Habilitar el temporizador
// Creación de tarea para el botón
xTaskCreatePinnedToCore(tareaBoton, "BotonTask", 1000, NULL, 1, NULL, 0);
}
void loop() {
}
void tareaBoton(void *parameter) {
while (1) {
// Verificar si el botón ha sido oprimido (flanco de bajada)
if (digitalRead(PIN_BOTON) == LOW && botonAnterior == HIGH) {
// Cambiar el estado de los LEDs
ledsActivos = !ledsActivos;
// Imprimir mensaje en el Monitor Serie
if (ledsActivos) {
Serial.println("Se ha reanudado el parpadeo de los LEDs");
} else {
Serial.println("Se han apagado los LEDs");
}
// Esperar un breve tiempo para evitar múltiples detecciones rápidas
vTaskDelay(500 / portTICK_PERIOD_MS);
}
// Actualizar el estado previo del botón
botonAnterior = digitalRead(PIN_BOTON);
// Pausa para evitar saturar la CPU
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}