#include <SD.h> //Librería SD: Arduino puede comunicarse con memoria SD
#include <SPI.h>
#include <RTClib.h>
RTC_DS1307 clockRTC;
//Define constante "CS_PIN" con valor 10
#define CS_PIN 10
//Define los pines de los sensores PIR
#define PIR_PIN_1 2
#define PIR_PIN_2 3
#define PIR_PIN_3 4
#define PIR_PIN_4 5
#define RED1 8
#define GREEN1 7
#define BLUE1 6
#define RED2 13
#define GREEN2 11
#define BLUE2 9
//Define un contador de plazas de las plantas 0 y 1
volatile int Ocupadas0 = 0;
volatile int Ocupadas1 = 0;
//Define número de plazas de cada planta
int plazas0 = 5;
int plazas1 = 2;
File root; //Variable de tipo File (Maneja el sistema de archivos de la tarjeta SD) llamada root
//Variable de tipo File con la que apuntamos al nuevo arhivo en el que se guardan lo datos
File Datos;
void setup() { //Sólo se ejecuta 1 vez al inicio
Serial.begin(115200);
// Configura los pines de los sensores PIR como entrada
pinMode(PIR_PIN_1, INPUT);
pinMode(PIR_PIN_2, INPUT);
pinMode(PIR_PIN_3, INPUT);
pinMode(PIR_PIN_4, INPUT);
// Configura los pines de los led como salida
pinMode(RED1, OUTPUT);
pinMode(GREEN1, OUTPUT);
pinMode(BLUE1, OUTPUT);
//salidas estaran inicializadas con valor LOW
digitalWrite(RED1, LOW);
digitalWrite(GREEN1, LOW);
digitalWrite(BLUE1, LOW);
// Configura los pines de los led como salida
pinMode(RED2, OUTPUT);
pinMode(GREEN2, OUTPUT);
pinMode(BLUE2, OUTPUT);
//salidas estaran inicializadas con valor LOW
digitalWrite(RED2, LOW);
digitalWrite(GREEN2, LOW);
digitalWrite(BLUE2, LOW);
Serial.print("Initializing SD card... ");
//Comprobar si está conectada correctamente
if (!SD.begin(CS_PIN)) {
Serial.println("Card initialization failed!");
while (true);
}
Serial.println("initialization done.");
//Creamos un nuevo archivo para guardar los datos recolectados por los sensores
Datos = SD.open("Datos.csv", FILE_WRITE); //Lo abrimos modo escritura
// Escribir una línea de datos en el archivo
Datos.println("ID,FECHA,HORA,ACCESO,PLANTA,MOVIMIENTO,LIBRESP0,LIBRESP1");
Serial.println("ID,FECHA,HORA,ACCESO,PLANTA,MOVIMIENTO,LIBRESP0,LIBRESP1");
clockRTC.begin();
if (!Datos) { //Comprobamos si se ha abierto correctamente el archivo
Serial.println("Error al abrir el archivo");
} else {
Serial.println("Archivo abierto correctamente");
while (Datos.available()) {
Serial.write(Datos.read());
}
Datos.close();
}
//Imprime los archivos de la tarjeta SD
Serial.println("Files in the card:");
root = SD.open("/"); //Abre el directorio raíz de la tarjeta SD y lo asigna a root
printDirectory(root, 0); //Imprimir el contenido del directorio raíz de la tarjeta SD
Serial.println("");
}
void loop() {
DateTime now = clockRTC.now();
Datos = SD.open("Datos.csv", FILE_WRITE); //Lo abrimos modo escritura
// Lee el valor de cada sensor PIR
int EntradaP0 = digitalRead(PIR_PIN_1);
int SalidaP0 = digitalRead(PIR_PIN_2);
int EntradaP1 = digitalRead(PIR_PIN_3);
int SalidaP1 = digitalRead(PIR_PIN_4);
// Comprueba el valor de cada sensor y envía un mensaje adecuado
if (EntradaP0 == HIGH) {
Ocupadas0 = Ocupadas0 + 1;
Serial.print("Ocupadas0: ");
Serial.println(Ocupadas0, DEC);
}
if (SalidaP0 == HIGH) {
if (Ocupadas0 != 0){
Ocupadas0 = Ocupadas0 - 1;
Serial.print("Ocupadas0: ");
Serial.println(Ocupadas0, DEC);
}
}
// Encender el LED verde si hay al menos una plaza disponible, de lo contrario, encender el LED rojo
if (Ocupadas0 < plazas0) { // Suponiendo que el estacionamiento tiene un límite de 50 plazas
digitalWrite(RED1, LOW);
digitalWrite(GREEN1, HIGH);
} else {
digitalWrite(GREEN1, LOW);
digitalWrite(RED1, HIGH);
}
if (EntradaP1 == HIGH) {
Ocupadas1 = Ocupadas1 + 1;
Serial.print("Ocupadas1: ");
Serial.println(Ocupadas1, DEC);
}
if (SalidaP1 == HIGH) {
if (Ocupadas1 != 0){
Ocupadas1 = Ocupadas1 - 1;
Serial.print("Ocupadas1: ");
Serial.println(Ocupadas1, DEC);
}
}
// Encender el LED verde si hay al menos una plaza disponible, de lo contrario, encender el LED rojo
if (Ocupadas1 < plazas1) { // Suponiendo que el estacionamiento tiene un límite de 50 plazas
digitalWrite(RED2, LOW);
digitalWrite(GREEN2, HIGH);
} else {
digitalWrite(GREEN2, LOW);
digitalWrite(RED2, HIGH);
}
// Si el archivo está disponible, escribir los datos
if (Datos) {
// Formato de fecha y hora: "DD/MM/AAAA,HH:MM:SS"
String timestamp = String(now.day()) + "/" + String(now.month()) + "/" + String(now.year()) + "," +
String(now.hour()) + ":" + String(now.minute()) + ":" + String(now.second());
// Guardar los valores en un archivo CSV
String data1 = "Sensor1," + timestamp + "," + "Entrada," + "P0," + String(EntradaP0) + "," + String(plazas0 - Ocupadas0) + "," + String(plazas1 - Ocupadas1);
String data2 = "Sensor2," + timestamp + "," + "Salida," + "P0," + String(SalidaP0) + "," + String(plazas0 - Ocupadas0) + "," + String(plazas1 - Ocupadas1);
String data3 = "Sensor3," + timestamp + "," + "Entrada," + "P1," + String(EntradaP1) + "," + String(plazas0 - Ocupadas0) + "," + String(plazas1 - Ocupadas1);
String data4 = "Sensor4," + timestamp + "," + "Salida," + "P1," + String(EntradaP1) + "," + String(plazas0 - Ocupadas0) + "," + String(plazas1 - Ocupadas1);
Datos.println(data1);
Datos.println(data2);
Datos.println(data3);
Datos.println(data4);
Serial.println(data1);
Serial.println(data2);
Serial.println(data3);
Serial.println(data4);
Datos.close();
} else {
Serial.println("Error opening sensor.csv");
}
delay(5000); // Espera 5 segundos antes de volver a comprobar
}
void printDirectory(File dir, int numTabs) { //dir=directorio a imprimir numTabs=# de tabulaciones
while (true) { //Hasta que se hayan procesado todos los archivos y directorios en el directorio actual
File entry = dir.openNextFile(); //Abre el siguiente archivo o directorio a la raíz y lo asigna a entry
if (! entry) { //Si no hay más archivos o directorios en el directorio actual
break;
}
//Hacer tabulaciones
for (uint8_t i = 0; i < numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name()); //Imprime el nombre del archivo o directorio
if (entry.isDirectory()) { //Si entry es un directorio imprime / tras su mobre para indicarlo
Serial.println("/");
printDirectory(entry, numTabs + 1); //Llama recursivamente a printDirectory para imprimir el contenido del directorio entry, aumentando numTabs en 1 para la indentación
} else {//Si entry es un archivo
Serial.print("\t\t"); //imprime dos tabulaciones
Serial.println(entry.size(), DEC); //tamaño del archivo en el monitor serial, utilizando la base decimal
}
entry.close();
}
}