// PASE - TP 03 - Proyecto con FreeRTOS
//
/*
Versión 2: una tarea indica el ritmo adecuado para hacer RCP con un LED (task3)
Otra tarea muestra un ECG ok (tarea 2)
La tarea 1 hay que modificarla para que muestra un ECG NO OK
Hay que crear tarea 4 que lea un interruptor que indicará si se está realizando con la frecuencia adecuada la maniobra de RCP
Proyecto con ESP32 utilizando FreeRTOS
Simulador de ECG para entrenador de RCP
Ing. Ivana Trento
Fecha: Diciembre 2023
Especialización en Sist. Embebidos - UNSL
Materia: PASE
Prof: Martín Murdocca
Placa: ESP32 Arduino -> Wemos D1 R32
*/
#include <Arduino.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/semphr.h>
//const int LED_PIN = 2; //LED_BUILTIN en pin 2 para la placa Wemos;
int LED_PIN = 22;
const int PULS = 23; //Pulsador
bool lectura_actual=1;
bool lectura_anterior=1;
bool cambio=0;
int cont=0;
int rcp_ok[20]={3, 3, 3, 3, 4, 3, 3, 2, 10, 1, 3, 3, 4, 5, 4, 3, 3, 3, 3, 3};
SemaphoreHandle_t uartSemaphore;
//Prototipo de funciones / tareas
void task1(void *parameter);
void task2(void *parameter);
void Blink_LED (void *pvParameters);
void setup() {
uartSemaphore = xSemaphoreCreateMutex();
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT); // Inicializar el pin del LED como una salida
pinMode(PULS, INPUT_PULLUP); //Inicializo pin del pulsador como entrada con pull-up
// Creación de las tareas
// Prioridad de las tareas: a mayor número, mayor prioridad.
//Hay dos tareas con igual prioridad (si no fuera por el vtaskDelay, no entraría nunca la tarea de menor prioridad)
xTaskCreate(task1,"Task1",4000,NULL,2,NULL); //Tarea 1
xTaskCreate(task2,"Task2",4000,NULL,2,NULL); //Tarea 2
xTaskCreate(Blink_LED, "ParpadeoLED", 4000, NULL, 1, NULL); //Tarea 3
}
void loop() {
// No se utiliza el bucle principal en FreeRTOS
}
//Funciones / Tareas
void task1(void *parameter) {
while (1) {
/*
// Esperar a que el semáforo esté disponible
if (xSemaphoreTake(uartSemaphore, portMAX_DELAY) == pdTRUE) {
Serial.println("Tarea 1: Enviando mensaje por UART0");
xSemaphoreGive(uartSemaphore);// Liberar el semáforo
}
*/
lectura_actual= digitalRead(PULS);
if(lectura_actual == lectura_anterior) //si se presionó el pulsador
cambio=0;
else
{
cambio=1;
lectura_anterior = lectura_actual;
if(lectura_actual==0)
Serial.println("Tarea 1: Pulsador presionado");
else
Serial.println("Tarea 1: Pulsador no presionado");
}
vTaskDelay(5 / portTICK_PERIOD_MS);
}
}
void task2(void *parameter) {
while (1) {
// Esperar a que el semáforo esté disponible
if (xSemaphoreTake(uartSemaphore, portMAX_DELAY) == pdTRUE) {
//Serial.println("Tarea 2: Enviando mensaje por UART0");
//for (float i = 0; i < 2 * PI; i += 0.1) {
//float value = cos(i);
//Serial.println(value);
for (int i=0; i<20; i++){
Serial.println(rcp_ok[i]);
}
xSemaphoreGive(uartSemaphore); // Liberar el semáforo
}
vTaskDelay(800 / portTICK_PERIOD_MS);
}
}
void Blink_LED (void *pvParameters) {
while (1) {
// El LED indica el ritmo ideal de compresiones de la RCP (120 compresiones por minuto) es decir 500 ms por compresión
digitalWrite(LED_PIN, HIGH);
vTaskDelay(pdMS_TO_TICKS(200)); //200 ms
digitalWrite(LED_PIN, LOW);
vTaskDelay(pdMS_TO_TICKS(300)); //300 ms
cont++;
if(cont==120)
{
cont=0;
Serial.println("1 minuto");
}
}
}