|
@@ -72,6 +72,7 @@ bool grabando = false; //inicia apagado
|
|
|
TaskHandle_t medicionesHandle = NULL; //para suspend/resume
|
|
TaskHandle_t medicionesHandle = NULL; //para suspend/resume
|
|
|
int pantallaEstado = 0; //maquina de estados
|
|
int pantallaEstado = 0; //maquina de estados
|
|
|
float distancia_total = 0.0;
|
|
float distancia_total = 0.0;
|
|
|
|
|
+volatile unsigned long ignore_isr_until = 0; //para debounce
|
|
|
|
|
|
|
|
char filename[13];
|
|
char filename[13];
|
|
|
|
|
|
|
@@ -237,13 +238,21 @@ void task_mediciones(void *pvParameters) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void IRAM_ATTR isr_button() {
|
|
void IRAM_ATTR isr_button() {
|
|
|
|
|
+ unsigned long now = millis();
|
|
|
|
|
+ if (now < ignore_isr_until) {
|
|
|
|
|
+ return; // Ignorar interrupción si está dentro del período de debounce
|
|
|
|
|
+ }
|
|
|
static unsigned long lastInterrupt = 0;
|
|
static unsigned long lastInterrupt = 0;
|
|
|
- if ((millis() - lastInterrupt) > 200 ){ // debounce de 200 ms
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if ((now - lastInterrupt) > 300 ){ // debounce de 300 ms
|
|
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
|
|
- xSemaphoreGiveFromISR(buttonSemaphore, NULL);
|
|
|
|
|
- lastInterrupt = millis();
|
|
|
|
|
|
|
+ xSemaphoreGiveFromISR(buttonSemaphore, &xHigherPriorityTaskWoken);
|
|
|
|
|
+ lastInterrupt = now;
|
|
|
if (xHigherPriorityTaskWoken) {
|
|
if (xHigherPriorityTaskWoken) {
|
|
|
portYIELD_FROM_ISR();
|
|
portYIELD_FROM_ISR();
|
|
|
|
|
+ Serial.println("Yield from ISR");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Serial.println("No yield from ISR");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -253,46 +262,63 @@ void task_ui(void *pvParameters){
|
|
|
unsigned long pressTime = 0;
|
|
unsigned long pressTime = 0;
|
|
|
unsigned long lastActivity = millis();
|
|
unsigned long lastActivity = millis();
|
|
|
bool pantallaOn = true; //comprobar el estado inicial, no se cual sera
|
|
bool pantallaOn = true; //comprobar el estado inicial, no se cual sera
|
|
|
|
|
+ bool processingButton = false;
|
|
|
|
|
|
|
|
while(1){
|
|
while(1){
|
|
|
if (xSemaphoreTake(buttonSemaphore, pdMS_TO_TICKS(200)) == pdTRUE){ //button pressed
|
|
if (xSemaphoreTake(buttonSemaphore, pdMS_TO_TICKS(200)) == pdTRUE){ //button pressed
|
|
|
|
|
+ if (processingButton) continue; //evita reentradas
|
|
|
|
|
+ processingButton = true;
|
|
|
|
|
+ Serial.println("Button semaphore taken");
|
|
|
|
|
+
|
|
|
pressTime = millis();
|
|
pressTime = millis();
|
|
|
|
|
+ lastActivity = millis(); //reset watchdog
|
|
|
|
|
|
|
|
if (!pantallaOn){
|
|
if (!pantallaOn){
|
|
|
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
|
|
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
|
|
|
pantallaOn = true;
|
|
pantallaOn = true;
|
|
|
|
|
+ Serial.println("Pantalla encendida");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bool timed_out = false;
|
|
bool timed_out = false;
|
|
|
|
|
+ unsigned long checkTime = millis();
|
|
|
while (digitalRead(BUTTON_PIN) == LOW){
|
|
while (digitalRead(BUTTON_PIN) == LOW){
|
|
|
vTaskDelay(pdMS_TO_TICKS(10));
|
|
vTaskDelay(pdMS_TO_TICKS(10));
|
|
|
|
|
+ checkTime = millis();
|
|
|
if ((millis() - pressTime) > DURACION_WATCHDOG_MS){ //10s timeout para evitar bloqueos
|
|
if ((millis() - pressTime) > DURACION_WATCHDOG_MS){ //10s timeout para evitar bloqueos
|
|
|
timed_out = true;
|
|
timed_out = true;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ ignore_isr_until = millis() + 50; //ignorar nuevas interrupciones durante 500 ms
|
|
|
|
|
+
|
|
|
|
|
+ unsigned long duration = checkTime - pressTime;
|
|
|
|
|
+ Serial.printf("Button released after %lu ms\n", duration);
|
|
|
|
|
+
|
|
|
if (timed_out){
|
|
if (timed_out){
|
|
|
OLED_print("Apagando","pantalla");
|
|
OLED_print("Apagando","pantalla");
|
|
|
delay(1000);
|
|
delay(1000);
|
|
|
display.ssd1306_command(SSD1306_DISPLAYOFF); //se apaga la
|
|
display.ssd1306_command(SSD1306_DISPLAYOFF); //se apaga la
|
|
|
pantallaOn = false;
|
|
pantallaOn = false;
|
|
|
|
|
+ Serial.println("Pantalla apagada por timeout");
|
|
|
} else {
|
|
} else {
|
|
|
-
|
|
|
|
|
- unsigned long duration = millis() - pressTime;
|
|
|
|
|
|
|
|
|
|
if (duration >= PULASCION_LARGA_MS){
|
|
if (duration >= PULASCION_LARGA_MS){
|
|
|
|
|
+ Serial.println("Pulsacion larga detectada");
|
|
|
//pulsacion larga: cabia entre grabacion y no grabacion de datos
|
|
//pulsacion larga: cabia entre grabacion y no grabacion de datos
|
|
|
- grabando != grabando;
|
|
|
|
|
|
|
+ grabando = grabando ? false : true; //toggle
|
|
|
if (grabando){
|
|
if (grabando){
|
|
|
vTaskResume(medicionesHandle);
|
|
vTaskResume(medicionesHandle);
|
|
|
//Mostrar que empieza la grabación
|
|
//Mostrar que empieza la grabación
|
|
|
OLED_print("Ruta","iniciada");
|
|
OLED_print("Ruta","iniciada");
|
|
|
|
|
+ Serial.println("Toggle to grabando iniciada");
|
|
|
} else {
|
|
} else {
|
|
|
vTaskSuspend(medicionesHandle);
|
|
vTaskSuspend(medicionesHandle);
|
|
|
//Mostrar que se pausa/finaliza la grabación
|
|
//Mostrar que se pausa/finaliza la grabación
|
|
|
OLED_print("Ruta","pausada");
|
|
OLED_print("Ruta","pausada");
|
|
|
|
|
+ Serial.println("Toggle to grabando pausada");
|
|
|
}
|
|
}
|
|
|
|
|
+ delay (1000); //espera un segundo para que el usuario vea el mensaje
|
|
|
} else {
|
|
} else {
|
|
|
//Pulsacion corta + grabando datos, cicla datos
|
|
//Pulsacion corta + grabando datos, cicla datos
|
|
|
if (grabando) {
|
|
if (grabando) {
|
|
@@ -313,8 +339,12 @@ void task_ui(void *pvParameters){
|
|
|
OLED_print("Altitud",String(gps.altitude.meters(), 1)+"m");
|
|
OLED_print("Altitud",String(gps.altitude.meters(), 1)+"m");
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
+ Serial.println("Ciclo pantalla datos");
|
|
|
|
|
+ delay(1000); //espera 2 segundos para que el usuario vea el mensaje
|
|
|
} else {
|
|
} else {
|
|
|
OLED_print("Grabacion","pausada");
|
|
OLED_print("Grabacion","pausada");
|
|
|
|
|
+ Serial.println("Grabacion pausada, no ciclar datos");
|
|
|
|
|
+ delay(1000); //espera un segundo para que el usuario vea el mensaje
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
@@ -322,14 +352,15 @@ void task_ui(void *pvParameters){
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
lastActivity = millis(); //reset watchdog
|
|
lastActivity = millis(); //reset watchdog
|
|
|
|
|
+ processingButton = false;
|
|
|
|
|
+ vTaskDelay(pdMS_TO_TICKS(100)); //pequeño delay para no busy waiting
|
|
|
}
|
|
}
|
|
|
//check watchdog fuera del boton
|
|
//check watchdog fuera del boton
|
|
|
if (pantallaOn && ((millis() - lastActivity) > DURACION_WATCHDOG_MS)){
|
|
if (pantallaOn && ((millis() - lastActivity) > DURACION_WATCHDOG_MS)){
|
|
|
display.ssd1306_command(SSD1306_DISPLAYOFF); //se apaga la pantalla
|
|
display.ssd1306_command(SSD1306_DISPLAYOFF); //se apaga la pantalla
|
|
|
pantallaOn = false;
|
|
pantallaOn = false;
|
|
|
|
|
+ Serial.println("Pantalla pagada por watchdog");
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- vTaskDelay(pdMS_TO_TICKS(100)); //pequeño delay para no busy waiting
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -360,7 +391,7 @@ void setup() {
|
|
|
xTaskCreatePinnedToCore(
|
|
xTaskCreatePinnedToCore(
|
|
|
task_mediciones, // Función de la tarea
|
|
task_mediciones, // Función de la tarea
|
|
|
"Mediciones", // Nombre de la tarea
|
|
"Mediciones", // Nombre de la tarea
|
|
|
- 2048, // Tamaño del stack
|
|
|
|
|
|
|
+ 8192, // Tamaño del stack
|
|
|
NULL, // Parámetro de la tarea
|
|
NULL, // Parámetro de la tarea
|
|
|
10, // Prioridad de la tarea
|
|
10, // Prioridad de la tarea
|
|
|
&medicionesHandle, // Handle de la tarea
|
|
&medicionesHandle, // Handle de la tarea
|