Kaynağa Gözat

Cambios en las funciones principales y ui basica generada,generada, falta comprobar si funciona

dacowars 3 gün önce
ebeveyn
işleme
f2243e8eb6
1 değiştirilmiş dosya ile 126 ekleme ve 28 silme
  1. 126 28
      main/main.ino

+ 126 - 28
main/main.ino

@@ -7,7 +7,6 @@
 #include "SD.h"
 #include "SPI.h"
 #include "Arduino.h"
-//#include "FreeRTOS.h"
 
 /*
 Uncomment and set up if you want to use custom pins for the SPI communication
@@ -64,6 +63,17 @@ SemaphoreHandle_t buttonSemaphore; // Semáforo para la tarea del botón
 //flag para reducir las lecturas de DHT y presion
 uint8_t readSensorsFlag = 0;
 
+//definicion de tiempos de pulsacion
+#define PULASCION_LARGA_MS 2000
+#define DURACION_WATCHDOG_MS 10000
+
+bool grabando = 0; //inicia apagado
+TaskHandle_t medicionesHandle = NULL; //para suspend/resume
+#define X  1    //separación entre mediciones (s) 
+int pantallaEstado = 0; //maquina de estados
+
+float distancia_total = 0;
+
 
 void DHT_test() {
   dht.begin();
@@ -124,6 +134,7 @@ char* SD_test() {
   }
 
   File file = SD.open(filename, FILE_WRITE);
+  file.Println("Latitud,Longitud,Temperatura,Humedad,Presión")
   file.close();
 
   return filename;
@@ -145,61 +156,148 @@ void GPS_test_wait() {
   OLED_print("GPS", "Encontrado");
 }
 
+float calcular_delta_dist(float lat1, float  long1, float lat2, float long2){
+  float R = 6371;
+  float delta_lat = lat2 - lat1;
+  float delta_long = long2 - long1;
+  float a = sin(delta_lat/2)ˆ2+cos(lat1)*cos(lat2)*sin(delta_long/2)ˆ2;
+  float c = 2 * atan2(sqrt(a),sqrt(1-a));
+  return float d = R * c; 
+}
 
 void task_mediciones(void *pvParameters) {
   TickType_t xLastWakeTime = xTaskGetTickCount();
   const char* filename = (const char*) pvParameters;
+  SensorData datosAntiguos;
   while(1) {
-        
+    
+    // se leen los valores antes de utilizar el semaphore    
     while (gpsSerial.available() > 0) {
       gps.encode(gpsSerial.read());
     }
+    float new_latitude = gps.location.lat();
+    float new_longitude = gps.location.lng();
+    if ((readSensorsFlag % 60) == 0) float new_temp = dht.readTemperature();
+    if ((readSensorsFlag % 120) == 0) float new_hum = ddht.readHumidity();
+    float new_press = 0.0; // Placeholder, no hay sensor de presión 
+    
+
     File file = SD.open(filename, FILE_WRITE);
     if (file) {
       // guardar datos en latestData
       if (xSemaphoreTake(dataMutex, portMAX_DELAY) == pdTRUE){
-        latestData.latitude = gps.location.lat();
-        latestData.longitude = gps.location.lng();
-        if ((readSensorsFlag % 60) == 0) latestData.temperature = dht.readTemperature();
-        if ((readSensorsFlag % 120) == 0) latestData.humidity = dht.readHumidity();
-        latestData.pressure = 0.0; // Placeholder, no hay sensor de presión
+        latestData.latitude = new_latitude;
+        latestData.longitude = new_longitude;
+        latestData.temperature = new_temp;
+        latestData.humidity = new_hum;
+        latestData.pressure = new_press; 
       }
+      distancia_total += calcular_delta_dist(new_latitude, new_longitude, datosAntiguos.latitude, datosAntiguos.longitude); 
+      datosAntiguos = latestData;
+      xSemaphoreGive(dataMutex);
+
+
+      //Crear la string para escribir en el archivo
+      char frase = String(datosAntiguos.latitude) + "," +
+                   String(datosAntiguos.longitude) + "," +
+                   String(datosAntiguos.temperature) + "," +
+                   String(datosAntiguos.humidity) + "," +
+                   String(datosAntiguos.pressure);
       
+
       // Escribir datos en el archivo
-      file.println(String(latestData.latitude) + "," +
-                   String(latestData.longitude) + "," +
-                   String(latestData.temperature) + "," +
-                   String(latestData.humidity) + "," +
-                   String(latestData.pressure));
-      xSemaphoreGive(dataMutex);
+      file.println(frase);
 
       file.close();
       if (!(readSensorsFlag % 120)) readSensorsFlag = 0;
       readSensorsFlag++;
     }
 
-    vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(10000)); // Espera 1 segundo
+    vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(X*1000)); // Espera x*1000 milisegundos
   }
 }
 
 void IRAM_ATTR isr_button() {
-  xSemaphoreGiveFromISR(buttonSemaphore, NULL);
+  static unsigned long lastInterrupt = 0;
+  if ((millis() - lastInterrupt) > 200 ){ // debounce de 200 ms 
+    xSemaphoreGiveFromISR(buttonSemaphore, NULL); 
+    lastInterrupt = mmillis();
+  }
+  
 }
 
 void task_ui(void *pvParameters){
+  unsigned long pressTime = 0;
+  unsigned long lastActivity = 0;
+  bool pantallaOn = true; //comprobar el estado inicial, no se cual sera
+
   while(1){
-    if (xSemaphoreTake(buttonSemaphore, portMAX_DELAY) == pdTRUE){
-      
-      SensorData dataCopy;
-      // Copiar datos protegidos por mutex
-      if (xSemaphoreTake(dataMutex, portMAX_DELAY) == pdTRUE){
-        dataCopy = latestData;
-        xSemaphoreGive(dataMutex); 
+    if (xSemaphoreTake(buttonSemaphore, portMAX_DELAY) == pdTRUE){ //button pressed
+      pressTime = millis();
+      lastActivity = millis();
+
+      if (!pantallaOn){
+        display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
+        pantallaOn = true;
+      }
+
+      while (digitalRead(BUTTON_PIN) == LOW){
+        vTaskDelay(pdMS_TO_TICKS(10));
+        if ((millis() - lastActivity) > DURACION_WATCHDOG_MS){
+          //WATCHDOG 'activo' solo funciona si se mantiene presionado el boton ese tiempo
+          break;
+        }
       }
       
-      //Falta implementar la parte de UI con OLED
-    
+      unsigned long duration = millis() - pressTime;
+
+      if (duration >= PULASCION_LARGA_MS){
+        //pulsacion larga: cabia entre grabacion y no grabacion de datos
+        grabando != grabando;
+        if (grabando){
+          vTaskResume(medicionesHandle);
+          //Mostrar que empieza la grabación
+          OLED_print("Ruta","iniciada");
+        } else {
+          vTaskSuspend(medicionesHandle);
+          //Mostrar que se pausa/finaliza la grabación
+          OLED_print("Ruta","pausada");
+        }
+      } else {
+        //Pulsacion corta + grabando datos, cicla datos
+        if (grabando) {
+          pantallaEstado = (pantallaEstado + 1) % 3; //cicla entre 0-2
+          SensorData currentData;
+          if(xSemaphoreTake(dataMutex, portMAX_DELAY) == pdTRUE){
+            currentData = latestData;
+            xSemaphoreGive(dataMutex);
+          }
+          switch (pantallaEstado){
+            case 0:
+              OLED_print("Posicion",String(currentData.longitude)+","+String(currentData.latitude));
+              break;
+            case 1:
+              OLED_print("Distancia",String(distancia_total)+"km");
+              break;
+            case 2:
+              OLED_print("Altitud",String(currentData.pressure)+"m");
+              break;
+          } else {
+            OLED_print("Grabación","pausada");
+          }
+        }
+        lastActivity = mmillis();  //reset watchdog
+      }
+
+      //check watchdog fuera del boton
+      if (pantallaOn && ((millis() - lastActivity) > DURACION_WATCHDOG_MS)){
+        display.ssd1306_command(SSD1306_DISPLAYOFF); //se apaga la pantalla
+        pantallaOn = false;
+      }
+
     }
+   
+    vTaskDelay(pdMS_TO_TICKS(100)); //pequeño delay para no busy waiting
   }
 }
 
@@ -226,17 +324,17 @@ void setup() {
     "Mediciones",        // Nombre de la tarea
     2048,                // Tamaño del stack
     (void*)filename,     // Parámetro de la tarea
-    1,                   // Prioridad de la tarea
-    NULL,                // Handle de la tarea
+    10,                   // Prioridad de la tarea
+    &medicionesHandle,                // Handle de la tarea
     0                    // Núcleo donde se ejecuta
   );
 
   xTaskCreatePinnedToCore(
     task_ui,             // Función de la tarea
     "UI",                // Nombre de la tarea
-    2048,                // Tamaño del stack
+    8192,                // Tamaño del stack
     NULL,                // Parámetro de la tarea
-    1,                   // Prioridad de la tarea
+    5,                   // Prioridad de la tarea
     NULL,                // Handle de la tarea
     1                    // Núcleo donde se ejecuta
   );