main.ino 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. #include "TinyGPSPlus.h"
  2. #include "DHT.h"
  3. #include <Wire.h>
  4. #include <Adafruit_GFX.h>
  5. #include <Adafruit_SSD1306.h>
  6. #include "FS.h"
  7. #include "SD.h"
  8. #include "SPI.h"
  9. #include "Arduino.h"
  10. //#include "FreeRTOS.h"
  11. /*
  12. Uncomment and set up if you want to use custom pins for the SPI communication
  13. #define REASSIGN_PINS
  14. int sck = -1;
  15. int miso = -1;
  16. int mosi = -1;
  17. int cs = -1;
  18. */
  19. #define SCREEN_WIDTH 128 // Ancho píxeles
  20. #define SCREEN_HEIGHT 64 // Alto píxeles
  21. #define OLED_RESET -1 // Reset pin (no usado)
  22. // Pines para UART2 (Serial2)
  23. #define RX_PIN 16 // RX del ESP32 conectado a TX del GPS
  24. #define TX_PIN 17 // TX del ESP32 conectado a RX del GPS
  25. #define GPS_BAUD 115200
  26. #define DHTPIN 4 // Digital pin connected to the DHT sensor
  27. #define DHTTYPE DHT22
  28. // Objeto TinyGPS++
  29. TinyGPSPlus gps;
  30. // Serial para GPS
  31. HardwareSerial gpsSerial(2);
  32. // Configuracion del DHT
  33. DHT dht(DHTPIN, DHTTYPE);
  34. //definición del objeto para la pantalla OLED
  35. Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  36. // pin para pulsador
  37. #define BUTTON_PIN 0
  38. //valores de los sensores
  39. struct SensorData {
  40. double latitude;
  41. double longitude;
  42. float temperature;
  43. float humidity;
  44. float pressure;
  45. };
  46. SensorData latestData;
  47. SemaphoreHandle_t dataMutex; // Mutex para proteger el acceso a latestData
  48. SemaphoreHandle_t buttonSemaphore; // Semáforo para la tarea del botón
  49. //flag para reducir las lecturas de DHT y presion
  50. uint8_t readSensorsFlag = 0;
  51. void DHT_test() {
  52. dht.begin();
  53. float h = dht.readHumidity();
  54. float t = dht.readTemperature();
  55. if (isnan(h) || isnan(t)) {
  56. Serial.println("Failed to read from DHT sensor!");
  57. OLED_print("DHT22", "Error");
  58. while(1); // Detener si hay error
  59. }
  60. else OLED_print("DHT22", "Correcto");
  61. }
  62. void OLED_test() { //pantallazo a blanco y luego iniciando
  63. // Inicia I2C en pines default ESP32 (21 SDA, 22 SCL)
  64. if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Dirección común: 0x3C
  65. Serial.println(F("Error: OLED no encontrado!"));
  66. for (;;); // Para siempre
  67. }
  68. display.clearDisplay();
  69. display.fillScreen(SSD1306_WHITE); // Pantalla blanca
  70. delay(500);
  71. display.display();
  72. display.clearDisplay();
  73. display.setTextSize(2); // Tamaño texto
  74. display.setTextColor(SSD1306_WHITE);
  75. display.setCursor(0, 0); // Posición
  76. display.println("Iniciando...");
  77. display.display(); // Muestra
  78. delay(1000);
  79. }
  80. void OLED_print(const char* line1, const char* line2) {
  81. display.clearDisplay();
  82. display.setTextSize(2);
  83. display.setTextColor(SSD1306_WHITE);
  84. display.setCursor(0, 0);
  85. display.println(line1);
  86. display.println(line2);
  87. display.display();
  88. }
  89. char* SD_test() {
  90. if (!SD.begin()) {
  91. Serial.println("SD Card Mount Failed");
  92. OLED_print("SD Card", "Error\nInserte tarjeta");
  93. while(!SD.begin()); // Detener si hay error
  94. OLED_print("SD Card", "Insertada");
  95. }
  96. else OLED_print("SD Card", "Correcto");
  97. char filename[] = "data001.txt";
  98. int num = 1;
  99. // Buscar un nombre de archivo disponible
  100. while(SD.exists(filename)) {
  101. num++;
  102. sprintf(filename, "data%03d.txt", num);
  103. }
  104. File file = SD.open(filename, FILE_WRITE);
  105. file.close();
  106. return filename;
  107. }
  108. void GPS_test_wait() {
  109. // Iniciar Serial2 para GPS
  110. gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RX_PIN, TX_PIN);
  111. while ((gpsSerial.available() > 0) && !gps.location.isValid()) {
  112. gps.encode(gpsSerial.read());
  113. delay(10);
  114. OLED_print("GPS", "Esperando.");
  115. delay(100);
  116. OLED_print("GPS", "Esperando..");
  117. delay(100);
  118. OLED_print("GPS", "Esperando...");
  119. }
  120. OLED_print("GPS", "Encontrado");
  121. }
  122. void task_mediciones(void *pvParameters) {
  123. TickType_t xLastWakeTime = xTaskGetTickCount();
  124. const char* filename = (const char*) pvParameters;
  125. while(1) {
  126. while (gpsSerial.available() > 0) {
  127. gps.encode(gpsSerial.read());
  128. }
  129. File file = SD.open(filename, FILE_WRITE);
  130. if (file) {
  131. // guardar datos en latestData
  132. if (xSemaphoreTake(dataMutex, portMAX_DELAY) == pdTRUE){
  133. latestData.latitude = gps.location.lat();
  134. latestData.longitude = gps.location.lng();
  135. if ((readSensorsFlag % 60) == 0) latestData.temperature = dht.readTemperature();
  136. if ((readSensorsFlag % 120) == 0) latestData.humidity = dht.readHumidity();
  137. latestData.pressure = 0.0; // Placeholder, no hay sensor de presión
  138. }
  139. // Escribir datos en el archivo
  140. file.println(String(latestData.latitude) + "," +
  141. String(latestData.longitude) + "," +
  142. String(latestData.temperature) + "," +
  143. String(latestData.humidity) + "," +
  144. String(latestData.pressure));
  145. xSemaphoreGive(dataMutex);
  146. file.close();
  147. if (!(readSensorsFlag % 120)) readSensorsFlag = 0;
  148. readSensorsFlag++;
  149. }
  150. vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(10000)); // Espera 1 segundo
  151. }
  152. }
  153. void IRAM_ATTR isr_button() {
  154. xSemaphoreGiveFromISR(buttonSemaphore, NULL);
  155. }
  156. void task_ui(void *pvParameters){
  157. while(1){
  158. if (xSemaphoreTake(buttonSemaphore, portMAX_DELAY) == pdTRUE){
  159. SensorData dataCopy;
  160. // Copiar datos protegidos por mutex
  161. if (xSemaphoreTake(dataMutex, portMAX_DELAY) == pdTRUE){
  162. dataCopy = latestData;
  163. xSemaphoreGive(dataMutex);
  164. }
  165. //Falta implementar la parte de UI con OLED
  166. }
  167. }
  168. }
  169. void setup() {
  170. Serial.begin(115200);
  171. // OLED check
  172. OLED_test();
  173. delay(500);
  174. // DHT check
  175. DHT_test();
  176. delay(500);
  177. // SD Card check
  178. char *filename = SD_test();
  179. delay(500);
  180. // GPS check
  181. GPS_test_wait();
  182. delay(2000);
  183. // Crear tarea para mediciones
  184. xTaskCreatePinnedToCore(
  185. task_mediciones, // Función de la tarea
  186. "Mediciones", // Nombre de la tarea
  187. 2048, // Tamaño del stack
  188. (void*)filename, // Parámetro de la tarea
  189. 1, // Prioridad de la tarea
  190. NULL, // Handle de la tarea
  191. 0 // Núcleo donde se ejecuta
  192. );
  193. xTaskCreatePinnedToCore(
  194. task_ui, // Función de la tarea
  195. "UI", // Nombre de la tarea
  196. 2048, // Tamaño del stack
  197. NULL, // Parámetro de la tarea
  198. 1, // Prioridad de la tarea
  199. NULL, // Handle de la tarea
  200. 1 // Núcleo donde se ejecuta
  201. );
  202. }
  203. void loop() {
  204. vTaskDelay(pdMS_TO_TICKS(1000)); // Espera 1 segundo
  205. }