Browse Source

Uso de FreeRTOS y primeros pasos de la app

dacowars 5 ngày trước cách đây
mục cha
commit
8874053480
2 tập tin đã thay đổi với 251 bổ sung148 xóa
  1. 0 148
      V1/V1.ino
  2. 251 0
      main/main.ino

+ 0 - 148
V1/V1.ino

@@ -1,148 +0,0 @@
-#include "TinyGPSPlus.h"
-#include "DHT.h"
-#include <Wire.h>
-#include <Adafruit_GFX.h>
-#include <Adafruit_SSD1306.h>
-#include "FS.h"
-#include "SD.h"
-#include "SPI.h"
-
-/*
-Uncomment and set up if you want to use custom pins for the SPI communication
-#define REASSIGN_PINS
-int sck = -1;
-int miso = -1;
-int mosi = -1;
-int cs = -1;
-*/
-
-#define SCREEN_WIDTH 128  // Ancho píxeles
-#define SCREEN_HEIGHT 64  // Alto píxeles
-#define OLED_RESET -1     // Reset pin (no usado)
-
-// Pines para UART2 (Serial2)
-#define RX_PIN 16  // RX del ESP32 conectado a TX del GPS
-#define TX_PIN 17  // TX del ESP32 conectado a RX del GPS
-#define GPS_BAUD 115200
-
-#define DHTPIN 4     // Digital pin connected to the DHT sensor
-#define DHTTYPE DHT22 
-
-// Objeto TinyGPS++
-TinyGPSPlus gps;
-
-// Serial para GPS
-HardwareSerial gpsSerial(2);
-
-// Configuracion del DHT
-DHT dht(DHTPIN, DHTTYPE);
-
-// Bandera volátil para interrupción
-volatile bool gpsFlag = false;
-
-void ARDUINO_ISR_ATTR onTimer(void) {
-  gpsFlag = true;  // Activa bandera para procesar GPS en el loop
-}
-
-Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
-
-void DHT_test() {
-  dht.begin();
-  float h = dht.readHumidity();
-  float t = dht.readTemperature();
-  if (isnan(h) || isnan(t)) {
-    Serial.println("Failed to read from DHT sensor!");
-    OLED_print("DHT22", "Error");
-    while(1); // Detener si hay error
-  }
-  else OLED_print("DHT22", "Correcto");
-}
-
-void OLED_test() {  //pantallazo a blanco y luego iniciando
-  // Inicia I2C en pines default ESP32 (21 SDA, 22 SCL)
-  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {  // Dirección común: 0x3C
-    Serial.println(F("Error: OLED no encontrado!"));
-    for (;;);  // Para siempre
-  }
-  display.clearDisplay();
-  display.fillScreen(SSD1306_WHITE); // Pantalla blanca
-  delay(500);
-  display.display();
-  display.clearDisplay();
-  display.setTextSize(2);         // Tamaño texto
-  display.setTextColor(SSD1306_WHITE);
-  display.setCursor(0, 0);        // Posición
-  display.println("Iniciando...");
-  display.display();              // Muestra
-  delay(1000);
-}
-
-void OLED_print(const char* line1, const char* line2) {
-  display.clearDisplay();
-  display.setTextSize(1);
-  display.setTextColor(SSD1306_WHITE);
-  display.setCursor(0, 0);
-  display.println(line1);
-  display.println(line2);
-  display.display();
-}
-
-void SD_test() {
-  if (!SD.begin()) {
-    Serial.println("SD Card Mount Failed");
-    OLED_print("SD Card", "Error");
-    while(1); // Detener si hay error
-  } 
-  else OLED_print("SD Card", "Correcto");
-}
-
-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()) {
-    gps.encode(gpsSerial.read());
-    delay(10);
-    OLED_print("GPS", "Esperando.");
-    delay(100);
-    OLED_print("GPS", "Esperando..");
-    delay(100);
-    OLED_print("GPS", "Esperando...");
-  }
-  OLED_print("GPS", "Encontrado");
-}
-
-void setup() {
-  Serial.begin(115200);
-
-
-  // Configurar temporizador hardware con frecuencia de 1 MHz (tick cada 1 us)
-  hw_timer_t *timer = timerBegin(1000000);  // Frecuencia en Hz
-  
-  // Adjuntar interrupción al temporizador
-  timerAttachInterrupt(timer, &onTimer);
-  
-  // Configurar alarma para 1 segundo (1,000,000 ticks), autoreload activado, unlimited
-  timerAlarm(timer, 1000000, true, 0);
-
-  // OLED check
-  OLED_test();
-  delay(500);
-  // DHT check
-  DHT_test();
-  delay(500);
-  // SD Card check
-  SD_test();
-  delay(500);
-  // GPS check
-  GPS_test_wait();
-  delay(2000);
-
-}
-
-
-
-void loop() {
-
-
-
-}

+ 251 - 0
main/main.ino

@@ -0,0 +1,251 @@
+#include "TinyGPSPlus.h"
+#include "DHT.h"
+#include <Wire.h>
+#include <Adafruit_GFX.h>
+#include <Adafruit_SSD1306.h>
+#include "FS.h"
+#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
+#define REASSIGN_PINS
+int sck = -1;
+int miso = -1;
+int mosi = -1;
+int cs = -1;
+*/
+
+#define SCREEN_WIDTH 128  // Ancho píxeles
+#define SCREEN_HEIGHT 64  // Alto píxeles
+#define OLED_RESET -1     // Reset pin (no usado)
+
+// Pines para UART2 (Serial2)
+#define RX_PIN 16  // RX del ESP32 conectado a TX del GPS
+#define TX_PIN 17  // TX del ESP32 conectado a RX del GPS
+#define GPS_BAUD 115200
+
+#define DHTPIN 4     // Digital pin connected to the DHT sensor
+#define DHTTYPE DHT22 
+
+// Objeto TinyGPS++
+TinyGPSPlus gps;
+
+// Serial para GPS
+HardwareSerial gpsSerial(2);
+
+// Configuracion del DHT
+DHT dht(DHTPIN, DHTTYPE);
+
+//definición del objeto para la pantalla OLED
+Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
+
+// pin para pulsador
+
+#define BUTTON_PIN 0  
+
+//valores de los sensores
+
+struct SensorData {
+  double latitude;
+  double longitude;
+  float temperature;
+  float humidity;
+  float pressure;
+};
+
+SensorData latestData;
+
+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;
+
+
+void DHT_test() {
+  dht.begin();
+  float h = dht.readHumidity();
+  float t = dht.readTemperature();
+  if (isnan(h) || isnan(t)) {
+    Serial.println("Failed to read from DHT sensor!");
+    OLED_print("DHT22", "Error");
+    while(1); // Detener si hay error
+  }
+  else OLED_print("DHT22", "Correcto");
+}
+
+void OLED_test() {  //pantallazo a blanco y luego iniciando
+  // Inicia I2C en pines default ESP32 (21 SDA, 22 SCL)
+  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {  // Dirección común: 0x3C
+    Serial.println(F("Error: OLED no encontrado!"));
+    for (;;);  // Para siempre
+  }
+  display.clearDisplay();
+  display.fillScreen(SSD1306_WHITE); // Pantalla blanca
+  delay(500);
+  display.display();
+  display.clearDisplay();
+  display.setTextSize(2);         // Tamaño texto
+  display.setTextColor(SSD1306_WHITE);
+  display.setCursor(0, 0);        // Posición
+  display.println("Iniciando...");
+  display.display();              // Muestra
+  delay(1000);
+}
+
+void OLED_print(const char* line1, const char* line2) {
+  display.clearDisplay();
+  display.setTextSize(2);
+  display.setTextColor(SSD1306_WHITE);
+  display.setCursor(0, 0);
+  display.println(line1);
+  display.println(line2);
+  display.display();
+}
+
+char* SD_test() {
+  if (!SD.begin()) {
+    Serial.println("SD Card Mount Failed");
+    OLED_print("SD Card", "Error\nInserte tarjeta");
+    while(!SD.begin()); // Detener si hay error
+    OLED_print("SD Card", "Insertada");
+  } 
+  else OLED_print("SD Card", "Correcto");
+
+  char filename[] = "data001.txt";
+  int num = 1;
+  // Buscar un nombre de archivo disponible
+  while(SD.exists(filename)) {
+    num++;
+    sprintf(filename, "data%03d.txt", num);
+  }
+
+  File file = SD.open(filename, FILE_WRITE);
+  file.close();
+
+  return filename;
+
+}
+
+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()) {
+    gps.encode(gpsSerial.read());
+    delay(10);
+    OLED_print("GPS", "Esperando.");
+    delay(100);
+    OLED_print("GPS", "Esperando..");
+    delay(100);
+    OLED_print("GPS", "Esperando...");
+  }
+  OLED_print("GPS", "Encontrado");
+}
+
+
+void task_mediciones(void *pvParameters) {
+  TickType_t xLastWakeTime = xTaskGetTickCount();
+  const char* filename = (const char*) pvParameters;
+  while(1) {
+        
+    while (gpsSerial.available() > 0) {
+      gps.encode(gpsSerial.read());
+    }
+    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
+      }
+      
+      // 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.close();
+      if (!(readSensorsFlag % 120)) readSensorsFlag = 0;
+      readSensorsFlag++;
+    }
+
+    vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(10000)); // Espera 1 segundo
+  }
+}
+
+void IRAM_ATTR isr_button() {
+  xSemaphoreGiveFromISR(buttonSemaphore, NULL);
+}
+
+void task_ui(void *pvParameters){
+  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); 
+      }
+      
+      //Falta implementar la parte de UI con OLED
+    
+    }
+  }
+}
+
+
+void setup() {
+  Serial.begin(115200);
+
+  // OLED check
+  OLED_test();
+  delay(500);
+  // DHT check
+  DHT_test();
+  delay(500);
+  // SD Card check
+  char *filename = SD_test();
+  delay(500);
+  // GPS check
+  GPS_test_wait();
+  delay(2000);
+
+  // Crear tarea para mediciones
+  xTaskCreatePinnedToCore(
+    task_mediciones,     // Función de la tarea
+    "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
+    0                    // Núcleo donde se ejecuta
+  );
+
+  xTaskCreatePinnedToCore(
+    task_ui,             // Función de la tarea
+    "UI",                // Nombre de la tarea
+    2048,                // Tamaño del stack
+    NULL,                // Parámetro de la tarea
+    1,                   // Prioridad de la tarea
+    NULL,                // Handle de la tarea
+    1                    // Núcleo donde se ejecuta
+  );
+
+}
+
+
+
+void loop() {
+
+  vTaskDelay(pdMS_TO_TICKS(1000)); // Espera 1 segundo
+}