Bläddra i källkod

Inicio para guardado en gpx, siguiente paso poner ui mejor y terminar gpx

dacowars 1 månad sedan
förälder
incheckning
ebcfa94176
1 ändrade filer med 50 tillägg och 49 borttagningar
  1. 50 49
      main/main.ino

+ 50 - 49
main/main.ino

@@ -53,10 +53,11 @@ Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
 struct SensorData {
   double latitude = 0.0;
   double longitude = 0.0;
+  float altura = 0.0;
+  String tiempo = "";
   float temperature = 0.0;
   float humidity = 0.0;
   float pressure = 0.0;
-  float altura = 0.0;
 };
 
 SensorData latestData;
@@ -65,12 +66,10 @@ SensorData datosAntiguos;
 SemaphoreHandle_t dataMutex; // Mutex para proteger el acceso a latestData
 SemaphoreHandle_t buttonSemaphore; // Semáforo para la tarea del botón
 
-//flag para reducir las lecturas de DHT y presion
-uint8_t readSensorsFlag = 0;
-
 bool grabando = false; //inicia apagado
 TaskHandle_t medicionesHandle = NULL; //para suspend/resume
-int pantallaEstado = 0; //maquina de estados
+int pantallaEstado_grab = 0; //maquina de estados cuando se graba ruta
+int pantallaEstado_menu = 0; //maquina de estados cuando no se esta grabando ruta
 float distancia_total = 0.0;
 volatile unsigned long ignore_isr_until = 0; //para debounce
 
@@ -144,30 +143,30 @@ if (!SD.begin()) {
   Serial.printf("SD Card Size: %uMB\n", cardSize);
 
   int num = 1;
-  sprintf(filename, "/data%03d.txt", num);
+  sprintf(filename, "/data%03d.xml", num);
   while (SD.exists(filename)) {
-    Serial.printf("File %s already exists. Trying next.\n", filename);
     num++;
-    sprintf(filename, "/data%03d.txt", num);
+    sprintf(filename, "/data%03d.xml", num);
   }
-  Serial.printf("Using file: %s\n", filename);
 
   File file = SD.open(filename, FILE_WRITE);
   if (file) {
-    Serial.println("File created successfully");
-    file.println("Latitud,Longitud,Temperatura,Humedad,Presion");
+    file.println('<?xml version="1.0" encoding="UTF-8"?>\n<gpx creator="ESP32 GPS LOGGER" version="1.1"\n\txmlns="http://www.topografix.com/GPX/1/1"\n\t
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n\txmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v2"\n\t
+      xmlns:gpxdata="http://www.cluetrust.com/XML/GPXDATA/1/0"\n\txsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">\n\t<trk>\n\t\t
+      <name>Rutita</name>\n\t\t<type>hiking</type>\n\t\t<trkseg>');
     file.close();
   } else {
-    Serial.println("Error creando archivo");
+    OLED_print("Error","creando archivo");
   }
 }
 
 void GPS_test_wait() {
   // Iniciar Serial2 para GPS
   gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RX_PIN, TX_PIN);
-  while ((gpsSerial.available() > 0) && !gps.location.isValid()) {
+  while (((gpsSerial.available() > 0) && gps.location.isValid()) && (gps.speed.age() < 2000)) {
     gps.encode(gpsSerial.read());
-    delay(10);
+    delay(100);
     OLED_print("GPS", "Esperando.");
     delay(100);
     OLED_print("GPS", "Esperando..");
@@ -198,8 +197,13 @@ void task_mediciones(void *pvParameters) {
 
     float new_latitude = gps.location.lat();
     float new_longitude = gps.location.lng();
-    float new_temp = (readSensorsFlag % 60 == 0) ? dht.readTemperature() : latestData.temperature;
-    float new_hum = (readSensorsFlag % 120 == 0) ? dht.readHumidity() : latestData.humidity;
+    float new_altitude = gps.altitude.meters();
+    String new_fecha = String(gps.date.year())+"-"+String(gps.date.month())+"-"+
+                   String(gps.date.day())+"T"+String(gps.time.hour())+":"+
+                   String(gps.time.minute())+":"+String(gps.time.second())+"."+
+                   String(gps.time.centisecond())
+    float new_temp = dht.readTemperature();
+    float new_hum = dht.readHumidity();
     float new_press = 0.0; // Placeholder, no hay sensor de presión 
     
     if (gps.location.isValid() && datosAntiguos.latitude != 0.0) {
@@ -209,6 +213,8 @@ void task_mediciones(void *pvParameters) {
     if (xSemaphoreTake(dataMutex, portMAX_DELAY) == pdTRUE) {
       latestData.latitude = new_latitude;
       latestData.longitude = new_longitude;
+      latestData.altura = new_altitude;
+      latestData.tiempo = new_fecha;
       latestData.temperature = new_temp;
       latestData.humidity = new_hum;
       latestData.pressure = new_press;
@@ -219,20 +225,19 @@ void task_mediciones(void *pvParameters) {
     File file = SD.open(filename, FILE_APPEND);
     if (file) {
       //Crear la string para escribir en el archivo
-      String frase = String(datosAntiguos.latitude) + "," +
-                   String(datosAntiguos.longitude) + "," +
-                   String(datosAntiguos.temperature) + "," +
-                   String(datosAntiguos.humidity) + "," +
-                   String(datosAntiguos.pressure);
+      String frase = '\t\t\t<trkpt> lat="' + String(datosAntiguos.latitude,6) + 
+                   '" lon="' + String(datosAntiguos.longitude,6) + '">\n\t\t\t\t<ele>'+
+                   String(datosAntiguos.altura) + '</ele>\n\t\t\t\t<time>'+ 
+                   datosAntiguos.tiempo+'</time>\n\t\t\t\t<extensions>\n\t\t\t\t\t<gpxtpx:TrackPointExtension>\n\t\t\t\t\t\t<gpxtpx:atemp>'+
+                   String(datosAntiguos.temperature)+'</gpxtpx:atemp>\n\t\t\t\t\t</gpxtpx:TrackPointExtension>\n\t\t\t\t\t<custom:humidity>'+
+                   String(datosAntiguos.humidity)+'</custom:humidity>\n\t\t\t\t\t<custom:pressure>'+String(datosAntiguos.pressure)+
+                   '</custom:pressure>\n\t\t\t\t</extensions>\n\t\t\t</trkpt>';
       
       // Escribir datos en el archivo
       file.println(frase);
       file.close();
     }
 
-    if (!(readSensorsFlag % 120)) readSensorsFlag = 0;
-    readSensorsFlag++;
-
     vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(MEASUREMENT_INTERVAL_S*1000)); // Espera x*1000 milisegundos
   }
 }
@@ -250,14 +255,18 @@ void IRAM_ATTR isr_button() {
     lastInterrupt = now;
     if (xHigherPriorityTaskWoken) {
       portYIELD_FROM_ISR();
-      Serial.println("Yield from ISR");
-    } else {
-      Serial.println("No yield from ISR");
     }
   }
   
 }
 
+void drawProgressBar(int x, int y, int w, int h, unsigned long progress, unsigned long total) {
+  display.drawRect(x, y, w, h, SSD1306_WHITE); // Dibuja el borde
+  int filledWidth = (progress * w) / total;
+  display.fillRect(x + 1, y + 1, filledWidth - 2, h - 2, SSD1306_WHITE); // Dibuja la barra llena
+  display.display();
+}
+
 void task_ui(void *pvParameters){
   unsigned long pressTime = 0;
   unsigned long lastActivity = millis();
@@ -268,15 +277,13 @@ void task_ui(void *pvParameters){
     if (xSemaphoreTake(buttonSemaphore, pdMS_TO_TICKS(200)) == pdTRUE){ //button pressed
       if (processingButton) continue; //evita reentradas
       processingButton = true;
-      Serial.println("Button semaphore taken");
-      
+
       pressTime = millis();
       lastActivity = millis(); //reset watchdog
 
       if (!pantallaOn){
         display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
         pantallaOn = true;
-        Serial.println("Pantalla encendida");
       }
 
       bool timed_out = false;
@@ -284,51 +291,44 @@ void task_ui(void *pvParameters){
       while (digitalRead(BUTTON_PIN) == LOW){
         vTaskDelay(pdMS_TO_TICKS(10));
         checkTime = millis();
-        if ((millis() - pressTime) > DURACION_WATCHDOG_MS){ //10s timeout para evitar bloqueos
+        if ((checkTime - pressTime) > DURACION_WATCHDOG_MS){ //10s timeout para evitar bloqueos
           timed_out = true;
           break;
         }
+        drawProgressBar(0, SCREEN_HEIGHT - 10, SCREEN_WIDTH, 8, checkTime - pressTime, PULASCION_LARGA_MS);
       }
 
       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){
         OLED_print("Apagando","pantalla");
-        delay(1000);
         display.ssd1306_command(SSD1306_DISPLAYOFF); //se apaga la
         pantallaOn = false;
-        Serial.println("Pantalla apagada por timeout");
       } else {
-
         if (duration >= PULASCION_LARGA_MS){
-          Serial.println("Pulsacion larga detectada");
           //pulsacion larga: cabia entre grabacion y no grabacion de datos
           grabando = grabando ? false : true; //toggle
           if (grabando){
             vTaskResume(medicionesHandle);
             //Mostrar que empieza la grabación
             OLED_print("Ruta","iniciada");
-            Serial.println("Toggle to grabando iniciada");
           } else {
             vTaskSuspend(medicionesHandle);
             //Mostrar que se pausa/finaliza la grabación
             OLED_print("Ruta","pausada");
-            Serial.println("Toggle to grabando pausada");
           }
-          delay (1000); //espera un segundo para que el usuario vea el mensaje
         } else {
           //Pulsacion corta + grabando datos, cicla datos
           if (grabando) {
-            pantallaEstado = (pantallaEstado + 1) % 3; //cicla entre 0-2
+            pantallaEstado_grab = (pantallaEstado_grab + 1) % 5; //cicla entre 0-4
             SensorData currentData;
             if(xSemaphoreTake(dataMutex, portMAX_DELAY) == pdTRUE){
               currentData = latestData;
               xSemaphoreGive(dataMutex);
             }
-            switch (pantallaEstado){
+            switch (pantallaEstado_grab){
               case 0:
                 OLED_print("Posicion",String(currentData.longitude) + "," + String(currentData.latitude));
                 break;
@@ -338,15 +338,17 @@ void task_ui(void *pvParameters){
               case 2:
                 OLED_print("Altitud",String(gps.altitude.meters(), 1)+"m");
                 break;
+              case 3:
+                OLED_print("Temp/Hum",String(currentData.temperature,1)+"C/"+String(currentData.humidity,1)+"%");
+                break;  
+              case 4:
+                OLED_print("Velocidad",String(gps.speed.kmph())+"km/h");
+                break;
             } 
-            Serial.println("Ciclo pantalla datos");
-            delay(1000); //espera 2 segundos para que el usuario vea el mensaje
           } else {
-              OLED_print("Grabacion","pausada");
-              Serial.println("Grabacion pausada, no ciclar datos");
-              delay(1000); //espera un segundo para que el usuario vea el mensaje
-          }
-          
+            pantallaEstado_menu = (pantallaEstado_menu + 1) % 3;
+            OLED_print("Ruta","pausada");
+          }      
         }
 
         
@@ -359,7 +361,6 @@ void task_ui(void *pvParameters){
     if (pantallaOn && ((millis() - lastActivity) > DURACION_WATCHDOG_MS)){
           display.ssd1306_command(SSD1306_DISPLAYOFF); //se apaga la pantalla
           pantallaOn = false;
-          Serial.println("Pantalla pagada por watchdog");
     }
   }
 }