/*
* Connect the SD card to the following pins:
*
* SD Card | ESP32
* D2 -
* D3 SS
* CMD MOSI
* VSS GND
* VDD 3.3V
* CLK SCK
* VSS GND
* D0 MISO
* D1 -
*/
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#define CS_PIN
#define BUTTON_PIN 13
//File root;
File file;
unsigned long previousMillis = 0;
unsigned long buttonPressTime = 0;
#define DEBOUNCE_DELAY 50 // Tiempo de rebote en milisegundos
#define LONG_PRESS_DELAY 8000 // Tiempo en milisegundos para considerar un largo presionado
#define MAX_SERIAL_BUFFER 50
unsigned long buttonPressStartTime = 0;
const long interval = 1000; // Intervalo de 1 segundo
bool buttonPressed = false;
bool firstTimePress = false;
bool PressDelete = false;
bool button3s = false; // Bandera para indicar si se ha presionado el botón
int segundos=0;
int minutos=0;
int horas=0;
int dia=0;
enum ButtonState {
WAITING_PRESS,
FIRST_PRESS,
RECORDING_DATA,
STOP_RECORDING,
READ_DATA,
DELETE_DATA
};
ButtonState buttonState = WAITING_PRESS;
unsigned long elapsedTime;
char serialBuffer[MAX_SERIAL_BUFFER];
int serialIndex = 0;
void createDir(fs::FS &fs, const char *path) {
Serial.printf("Creating Dir: %s\n", path);
if (fs.exists(path)) {
Serial.println("Directory already exists");
} else {
if (fs.mkdir(path)) {
Serial.println("Dir created");
} else {
Serial.println("mkdir failed");
}
}
}
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
Serial.printf("Listing directory: %s\n", dirname);
File root = fs.open(dirname);
if(!root){
Serial.println("Failed to open directory");
return;
}
if(!root.isDirectory()){
Serial.println("Not a directory");
return;
}
File file = root.openNextFile();
while(file){
if(file.isDirectory()){
Serial.print(" DIR : ");
Serial.println(file.name());
if(levels){
listDir(fs, file.path(), levels -1);
}
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print(" SIZE: ");
Serial.println(file.size());
}
file = root.openNextFile();
}
}
void leerArchivo() {
// Abrir el archivo en modo de lectura
file = SD.open("/datagps.txt");
if (!file) {
Serial.println("Failed to open file for reading");
return;
}
// Leer y mostrar el contenido del archivo línea por línea
Serial.println("Contenido del archivo:");
while (file.available()) {
Serial.write(file.read());
}
// Cerrar el archivo
// file.close();
}
void readFile(fs::FS &fs, const char * path){
// Serial.printf("Reading file: %s\n", path);
File file = fs.open(path);
if(!file){
Serial.println("Failed to open file for reading");
return;
}
// Serial.print("Read from file: ");
while(file.available()){
Serial.write(file.read());
}
file.close();
}
void borrarMemoria() {
// Abrir el archivo en modo de escritura
/* file = SD.open("/datagps.txt", FILE_WRITE);
if (!file) {
Serial.println("Failed to open file for writing");
return;
}*/
// Cerrar el archivo
file.close();
delay(100);
if (SD.exists("/datagps.txt")) {
SD.remove("/datagps.txt");
}
Serial.println("Memory cleared successfully");
delay(3000);
// Abrir el archivo en modo de escritura
file = SD.open("/datagps.txt", FILE_WRITE);
if (!file) {
Serial.println("Failed to open file for writing");
return;
}
}
/*
void writeFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Writing file: %s\n", path);
File file = fs.open(path, FILE_WRITE);
if(!file){
Serial.println("Failed to open file for writing");
return;
}
if(file.print(message)){
Serial.println("File written");
} else {
Serial.println("Write failed");
}
file.close();
}
*/
void setup() {
Serial.begin(115200);
Serial.print("Initializing SD card... ");
if (!SD.begin(CS_PIN)) {
Serial.println("Card initialization failed!");
while (true);
}
Serial.println("initialization done.");
uint8_t cardType = SD.cardType();
if(cardType == CARD_NONE){
Serial.println("No SD card attached");
return;
}
Serial.print("SD Card Type: ");
if(cardType == CARD_MMC){
Serial.println("MMC");
} else if(cardType == CARD_SD){
Serial.println("SDSC");
} else if(cardType == CARD_SDHC){
Serial.println("SDHC");
} else {
Serial.println("UNKNOWN");
}
//crear direccion en sd
// createDir(SD, "/datagps");
// listDir(SD, "/", 0);
// Verificar si existen datos en el archivo
// Si no existen datos, abrir el archivo en modo de escritura
file = SD.open("/datagps.txt", FILE_WRITE);
if (!file) {
Serial.println("No se pudo abrir el archivo");
return;
}
// writeFile(SD, "/datagps.txt", "acatenesdatogps1223444 ");
// readFile(SD, "/datagps.txt");
// Configurar el pin del botón como entrada con pull-up interno
pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop() {
unsigned long currentMillis = millis();
unsigned long currentMill = millis();
if (currentMill - previousMillis >= interval) {
previousMillis = currentMill;
if (button3s) { // Si el botón no se ha presionado, ejecutar la función prueba()
prueba();
}
}
// Verificar si hay datos disponibles en el puerto serial
while (Serial.available() > 0) {
char incomingChar = Serial.read();
if (incomingChar != '\n' && serialIndex < MAX_SERIAL_BUFFER - 1) {
serialBuffer[serialIndex] = incomingChar;
serialIndex++;
} else {
serialBuffer[serialIndex] = '\0'; // Terminar la cadena
if (strcmp(serialBuffer, "mostrardatos") == 0) {
leerArchivo();
} else if (strcmp(serialBuffer, "borrardatos") == 0) {
borrarMemoria();
}
serialIndex = 0;
}
}
switch (buttonState) {
case WAITING_PRESS:
if (digitalRead(BUTTON_PIN) == LOW) {
buttonPressStartTime = currentMillis;
elapsedTime=0;
buttonState = FIRST_PRESS;
}
break;
case FIRST_PRESS:
if (digitalRead(BUTTON_PIN) == LOW) {
elapsedTime = currentMillis - buttonPressStartTime;
//hacer acumulador de tiempo aca
// buttonPressStartTime = 0;
// buttonState = WAITING_PRESS;
Serial.println(elapsedTime);
} else {
/*
despues de press los 3 seg se muestra lo guardado en memoria constantemente , quitar la rutina de boton 8 seg press (reemplazar la logica por esta )
LUZ para los 3 seg
*/
if (elapsedTime >= 3000 && !firstTimePress) {
buttonState = RECORDING_DATA;
}
if( elapsedTime >= 3000 && firstTimePress){
buttonState = STOP_RECORDING;
}
if(elapsedTime >= 6000 && elapsedTime <= 8000){
buttonState = READ_DATA;
}
if(elapsedTime >= 9000 ){
buttonState = DELETE_DATA;
}
}
break;
case RECORDING_DATA:
// Lógica para la grabación de datos aquí
button3s = true;
firstTimePress = true;
Serial.println("guardando datos");
delay(500);
buttonState = WAITING_PRESS;
break;
case STOP_RECORDING:
// Lógica para detener la grabación de datos aquí
/* if (digitalRead(BUTTON_PIN) == HIGH) {
buttonPressStartTime = 0;
buttonState = WAITING_PRESS;
}else{*/
button3s = false;
firstTimePress = false;
Serial.println("dejar de guardando datos");
delay(500);
buttonState = WAITING_PRESS;
//}
break;
case READ_DATA:
// Lógica para detener la grabación de datos aquí
Serial.println("MOSTRAR DATOS");
leerArchivo();
delay(500);
buttonState = WAITING_PRESS;
break;
case DELETE_DATA:
// Lógica para detener la grabación de datos aquí
Serial.println("dejar de guardando datos");
borrarMemoria();
delay(500);
buttonState = WAITING_PRESS;
break;
}
/*
// Verificar si el botón se ha presionado
if (digitalRead(BUTTON_PIN) == LOW) {
if (buttonPressStartTime == 0) {
buttonPressStartTime = currentMillis;
}
if (digitalRead(BUTTON_PIN) == LOW &&
currentMillis - buttonPressStartTime >= 3000
&& firstTimePress == false && PressDelete == false) {
button3s = true;
firstTimePress = true;
buttonPressStartTime = 0;
Serial.println("guardando datos");
}
if (digitalRead(BUTTON_PIN) == LOW &&
currentMillis - buttonPressStartTime >= 3000
&& firstTimePress == true && PressDelete == false) {
if( currentMillis - buttonPressStartTime >= 4000 &&
currentMillis - buttonPressStartTime <= 5000 ){
firstTimePress = false;
}
if( currentMillis - buttonPressStartTime >= 6000){
PressDelete = true;
}
// firstTimePress = false;
// PressDelete = true;
button3s = false; //dejar de guardar datos
buttonPressStartTime = 0; // Restablecer el tiempo de inicio de la presión del botón
Serial.println("dejar de guardar datos");
}
if (digitalRead(BUTTON_PIN) == LOW &&
currentMillis - buttonPressStartTime >= 9000
&& PressDelete == true ) {
leerArchivo();
buttonPressStartTime = 0; // Restablecer el tiempo de inicio de la presión del botón
Serial.println("MOSTRAR DATOS");
}
if (digitalRead(BUTTON_PIN) == LOW &&
currentMillis - buttonPressStartTime >= 20000
&& PressDelete == true ) {
PressDelete = false;
borrarMemoria();
buttonPressStartTime = 0; // Restablecer el tiempo de inicio de la presión del botón
Serial.println("BORRAR DATOS");
}
} else {
// Si el botón está suelto, y se había iniciado la presión del botón anteriormente,
// leer el contenido del archivo
if (buttonPressStartTime != 0) {
//leerArchivo();
buttonPressStartTime = 0; // Restablecer el tiempo de inicio de la presión del botón
}
}*/
}
void prueba() {
// Abre el archivo en modo de escritura, agregando datos al final del archivo
file = SD.open("/datagps.txt", FILE_APPEND);
if (!file) {
Serial.println("No se pudo abrir el archivo");
return;
}
//ESTO ES PARA GUARDAR EL TIEMPO QUE HA TRANSCURRIDO, PERO SIN QUE LOS SEGUNDOS Y MINUTOS LLEGUEN A 60, Y HORAS A 24.
segundos=segundos+1;
if (segundos>=60){
segundos=segundos-60;
minutos=minutos+1;
if(minutos>=60){
minutos=minutos-60;
horas=horas+1;
if(horas>=24){
dia=dia+1;
horas=horas-24;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//EN ESTA SECCIÓN ALMACENAMOS LA INFORMACIÓN EN LA TARJETA SD
file.print("Tiempo = ");
file.print(dia);
file.print(", ");
if(horas<10)
{
file.print("0");
}
file.print(horas);
file.print(":");
if(minutos<10)
{
file.print("0");
}
file.print(minutos);
file.print(":");
if(segundos<10)
{
file.print("0");
}
file.print(", ");
// Escribir datos en el archivo en formato CSV
file.print("Tiempo = D");
file.print(","); // Separador
file.print("Tiempo = noche"); // Nueva línea
file.print(","); // Separador
file.print(12);
file.print(","); // Separador
file.println(13); // Nueva línea
// Cerrar el archivo
file.close();
Serial.println("GPS data saved to SD card.");
}