Optimizacion de codigo para arduino Uno

#include <SPI.h>
#include <MFRC522.h>
#include <Wire.h>
#include <ThreeWire.h>
#include <LiquidCrystal_I2C.h>
#include <RtcDS1302.h>
#include <SD.h>

// Definiciones de pines
#define RST_PIN     9
#define SS_PIN      10
#define button      2
#define buzzerPin   3
#define cspin       4

// Variables globales
byte valueButton = 1;
byte minutoA, minuto, mesA, mes, diaA, dia, horaA, hora;
int aA, a;
byte stateButton = 0;
unsigned long tx = 0;
unsigned long timepassed;
bool cardRead = false;
String cardValue;
char uidBuffer[4];
byte lengthU;
int toRun;
String copy = "";

// Objetos para periféricos
LiquidCrystal_I2C lcd(0x27, 16, 2);
ThreeWire myWire(6, 5, 7);
RtcDS1302<ThreeWire> Rtc(myWire);
MFRC522 mfrc522(SS_PIN, RST_PIN);

// Archivos
File usuarios, registro, entraron, file;
String fileF = "FILE.TXT";
String entraronF = "ENTRARON.TXT"; 
String usuariosF = "USUARIOS.TXT";          
String registroF = "REGISTRO.TXT"; 

void setup() {
  Serial.begin(9600);
  pinMode(cspin, OUTPUT);
  digitalWrite(cspin, HIGH);
  
  pinMode(buzzerPin, OUTPUT);
  pinMode(button, INPUT_PULLUP);
  lcd.begin(16, 2);
  lcd.backlight();
  Rtc.Begin();
  //Config for RTC
  /*RtcDateTime currentTime = RtcDateTime(__DATE__ , __TIME__);
  Rtc.SetDateTime(currentTime);
  */
  SPI.begin();
  mfrc522.PCD_Init();

  // Inicializar la tarjeta SD
  if (!SD.begin(cspin)) {
    Serial.println(F("Error initializing SD card."));
    displayMessage("Error iniciando", "tarjeta SD");
    while(1){}
  }
  Serial.println(F("SD card initialized successfully."));

  // Esperar para iniciar la comunicación Serial
  while (!Serial);
  mfrc522.PCD_DumpVersionToSerial();
  Serial.println(F("Comunicaión Serial iniciada"));

  if (!SD.exists(usuariosF)) {
    usuarios = SD.open(usuariosF, FILE_WRITE);
    usuarios.close();
    Serial.println(F("usuariosF ha sido creado"));
  } else {
    Serial.println(F("usuariosF ya existe"));
    } 
  // Verificar si el archivo "registroF" existe y crearlo si no existe
  if (!SD.exists(registroF)) {
    registro = SD.open(registroF, FILE_WRITE);
    registro.close();
    Serial.println(F("registroF ha sido creado"));
  } else {
    Serial.println(F("registroF ya existe"));
  }

  // Verificar si el archivo "entraronF" existe y crearlo si no existe
  if (!SD.exists(entraronF)) {
    entraron = SD.open(entraronF, FILE_WRITE);
    entraron.close();
    Serial.println(F("entraronF ha sido creado"));
  } else {
    Serial.println(F("entraronF ya existe"));
  }
}

void loop() {
  timepassed = millis();
  registerButton();
  clock();
  mainProcess();
}

void clock() {
  // Obtener la fecha y hora actual del RTC
  RtcDateTime now = Rtc.GetDateTime();
  
  // Obtener los componentes de fecha y hora
  aA = now.Year();
  mesA = now.Month();
  diaA = now.Day();
  horaA = now.Hour();
  minutoA = now.Minute();

  setMillis(100);

  // Actualizar los componentes de fecha y hora
  a = now.Year();
  mes = now.Month();
  dia = now.Day();
  hora = now.Hour();
  minuto = now.Minute();

  // Mostrar "Colocar tarjeta" en la primera línea del LCD
  lcd.setCursor(0, 0);
  lcd.print("Colocar tarjeta");

  // Mostrar la fecha y hora en la segunda línea del LCD
  lcd.setCursor(0, 1);
  printDoubleDigit(dia);
  lcd.print("/");
  printDoubleDigit(mes);
  lcd.print("/");
  lcd.print(a);
  lcd.print("|");
  printDoubleDigit(hora);
  lcd.print(":");
  printDoubleDigit(minuto);

  // Actualizar la pantalla solo si hay cambios en la fecha o hora
  if ((minutoA != minuto) || (horaA != hora) || (diaA != dia) || (mesA != mes) || (aA != a)) {
    lcd.setCursor(0, 1);
    printDoubleDigit(dia);
    lcd.print("/");
    printDoubleDigit(mes);
    lcd.print("/");
    lcd.print(a);
    lcd.print("|");
    printDoubleDigit(hora);
    lcd.print(":");
    printDoubleDigit(minuto);
  }
}

// Función para imprimir un número de dos dígitos
void printDoubleDigit(int number) {
  if (number < 10) {
    lcd.print("0");
  }
  lcd.print(number);
}

void mainProcess() {
  // Verificar si hay una nueva tarjeta presente en el lector
  if (!mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  // Leer el serial de la tarjeta
  if (!mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  // Inicializar la variable cardValue para almacenar el UID
  cardValue = "";

  // Leer el UID de la tarjeta y almacenarlo en cardValue
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    // Formatear el valor hexadecimal y almacenarlo en el búfer
    sprintf(uidBuffer, "%02X", mfrc522.uid.uidByte[i]);
    // Concatenar el valor del búfer en la variable cardValue
    cardValue += uidBuffer;
  }

  // Imprimir el valor del UID en el Serial Plotter
  serialP(cardValue);

  // Verificar si la tarjeta está registrada
  if (ifIsRegister(cardValue)) {
    ifIsAlreadyIn(cardValue); // Verificar si el usuario ya está adentro
    // Mostrar mensajes en la pantalla y hacer sonidos apropiados
    entryRegis(cardValue);
  } else {
    // Mostrar mensajes en la pantalla y hacer sonidos apropiados
    lcd.noDisplay();
    lcd.clear();
    setMillis(100);
    lcd.display();
    displayMessage("No registrado", "");
    buzzerTone(250, 1000, 0);
    lcd.noDisplay();
    lcd.clear();
    lcd.display();
    displayMessage("Para registrarte", "Apreta el boton");
    setMillis(1000);
    lcd.noDisplay();
    lcd.clear();
    setMillis(100);
    lcd.display();
    clock();
  }

  // Limpiar el valor de la tarjeta para la siguiente lectura
  cardValue = "";
  mfrc522.PICC_HaltA(); // Finalizar la comunicación con la tarjeta
}

void registerButton() {
  valueButton = digitalRead(button); // Leer si el botón está pulsado
  
  // Si el botón está presionado
  if (valueButton == LOW) {
    stateButton = 1;
    cardRead = false;
    
    // Mostrar mensaje en la pantalla para colocar la tarjeta
    displayMessage("Colocar tarjeta", "Para registrarse");
    
    tx = millis(); // Guardar el tiempo actual en 'tx'

    // Esperar hasta que se cumpla el tiempo de registro o se lea una tarjeta
    while (millis() - tx < 10000) {
      toRegis();
      
      // Si se leyó una tarjeta, actualizar la hora en la pantalla y salir del bucle
      if (cardRead == true) {
        clock();
        break;
      }
    }
  }
}

void toRegis() {
  if (cardRead) {
    return;
  }

  // Verificar si hay una nueva tarjeta presente en el lector
  if (!mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  // Leer el serial de la tarjeta
  if (!mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  // Inicializar la variable cardValue para almacenar el UID
  cardValue = "";

  // Leer el UID de la tarjeta y almacenarlo en cardValue
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    // Formatear el valor hexadecimal y almacenarlo en el búfer
    sprintf(uidBuffer, "%02X", mfrc522.uid.uidByte[i]);
    // Concatenar el valor del búfer en la variable cardValue
    cardValue += uidBuffer;
  }

  // Imprimir el valor del UID en el Serial Plotter
  serialP(cardValue);

  // Verificar si la tarjeta está registrada
  if (ifIsRegister(cardValue)) {
    displayMessage("Ya estás", "registrado");
    setMillis(1000);
    displayMessage("Inténtalo", "nuevamente");
    buzzerTone(250, 250, 0);
    cardRead = false;
    return; // Salir de la función si la tarjeta ya está registrada
  }
  
  // Mostrar mensaje en la pantalla y hacer sonidos apropiados
  displayMessage("Registrando", "...");
  toRegister(cardValue);
  setMillis(1000);
  displayMessage("Has sido", "registrado");
  buzzerTone(500, 1000, 1);
  cardRead = true;
  cardValue = "";
}
void setMillis(int wantedTime) {
  tx = millis(); // Guardar el tiempo actual en 'tx' 

  // Esperar hasta que haya pasado el tiempo deseado
  while (millis() - tx < wantedTime) {
    // No se hace nada, simplemente se espera
  }
}

void buzzerTone(int t1, int t2, int mode){
  digitalWrite(buzzerPin, HIGH);
  setMillis(t1);
  digitalWrite(buzzerPin, LOW);
  
  if (mode == 0) {
    setMillis(t1);
    digitalWrite(buzzerPin, HIGH);
    setMillis(t1);
    digitalWrite(buzzerPin, LOW);
  }
  
  setMillis(t2);
}

void displayMessage(const char* line1, const char* line2) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(line1);
  lcd.setCursor(0, 1);
  lcd.print(line2);
}

void toRegister(String uid) {
  // Cerrar el archivo antes de abrirlo nuevamente
  usuarios.close();
  setMillis(100);
  
  // Abre el archivo en modo escritura
  usuarios = SD.open(usuariosF, FILE_WRITE);
  setMillis(100);
  
  if (usuarios) {
    usuarios.print(uid); // Escribe el UID en el archivo
    usuarios.print(",");
    usuarios.flush(); // Verificar que ningún dato quedó a medio camino
    usuarios.close(); // Cierra el archivo después de escribirlo
    Serial.println(F("Datos escritos en el archivo correctamente."));
  } else {
    Serial.println(F("Error al abrir el archivo para escritura."));
  }
}

bool ifIsRegister(String user) {
  usuarios.close();
  setMillis(100);
  
  // Abre el archivo en modo lectura
  usuarios = SD.open(usuariosF, FILE_READ);
  setMillis(100);
  
  if (usuarios) {
    String verifyUser;
    char nextCharacter;

    while (usuarios.available()) {
      nextCharacter = usuarios.read();
      if (nextCharacter == ',') {
        if (verifyUser == user) {
          usuarios.close();
          return true;
        }
        verifyUser = ""; // Limpiar la cadena para el siguiente UID
      } else {
        verifyUser += nextCharacter; // Agregar el caracter leído al UID temporal
      }
    }
    
    // Verificar el último UID al final del archivo
    if (verifyUser == user) {
      usuarios.close();
      return true;
    }
    usuarios.close();
  }
  return false; // El archivo no se pudo abrir o el usuario no está registrado
}
void serialP(String message){
  Serial.println(message);
}

void entryRegis(String uid) {
  RtcDateTime now = Rtc.GetDateTime();
  a = now.Year();
  mes = now.Month();
  dia = now.Day();
  hora = now.Hour();
  minuto = now.Minute();
  
  String completeTime = String(hora) + ":" + String(minuto) + " " + String(dia) + "|" + String(mes) + "|" + String(a);
  
  Serial.println(completeTime);

  registro.close();
  setMillis(100);
  
  registro = SD.open(registroF, FILE_WRITE); // Abre el archivo en modo escritura
  
  setMillis(100);
  
  if (registro) {
    registro.print(uid); // Escribe el UID en el archivo
    registro.print(" ");
    registro.print(completeTime); // Agrega la fecha y hora al registro
    registro.print(","); // Agrega una coma para separar los UID
    registro.flush(); // Verificar que ningún dato quedó a medio camino
    registro.close(); // Cierra el archivo después de escribirlo
    Serial.println(F("Datos escritos en el archivo correctamente."));
  } else {
    Serial.println(F("Error al abrir el archivo para escritura."));
  }
}
void ifIsAlreadyIn(String user) {
  entraron.close();
  setMillis(100);
  entraron = SD.open(entraronF, FILE_READ); // Abre el archivo en modo lectura
  setMillis(100);
  if (entraron) {
    String verifyUser;
    char nextCharacter;
    lengthU = user.length()-1;
    while (entraron.available()) {
      nextCharacter = entraron.read();
      toRun = lengthU + entraron.position();
      if (nextCharacter == ',') {
        if (verifyUser == user) {
          entraron.flush();
          entraron.close();
          setMillis(100);
          removeText(lengthU, toRun);
          displayMessage("Hasta luego,", "nos vemos!!");
          buzzerTone(350, 750, 0);
          entraron.flush();
          entraron.close();
        }
        verifyUser = ""; // Limpiar la cadena para el siguiente UID
      } else {
        verifyUser += nextCharacter; // Agregar el caracter leído al UID temporal
      }
    }
    // Verificar el último UID al final del archivo
    if (verifyUser == user) {
      entraron.close();
      removeText(lengthU, toRun);
      displayMessage("Hasta luego,", "nos vemos!!");// El usuario está en la escuela
      buzzerTone(350, 750, 0);
    }
    entraron.close();
  }
  addUser(cardValue);
  displayMessage("Bienvenido!!", "de vuelta");
  buzzerTone(500, 1000, 1); // El usuario no está en la escuela
}
void removeText(int num, int lenghtNum){
  if (!SD.exists(fileF)) {
    file = SD.open(fileF, FILE_WRITE);
    file.close();
    Serial.println(F("fileF ha sido creado"));
  } else {
    Serial.println(F("fileF ya existe"));
  }
  
  entraron.close();
  setMillis(100);
  entraron = SD.open(entraronF, FILE_READ); // Abre el archivo en modo leer
  file = SD.open(fileF, FILE_WRITE); // Abre el archivo en modo escribir
  setMillis(100);
  entraron.seek(0);
  while (entraron.available()){
    int actualPos = entraron.position();
    entraron.seek(actualPos);
    if(actualPos < num || actualPos > lenghtNum+1){
      copy = entraron.read();
      file.print(copy);
    } else if(copy == " ") {
      return;
    } else {
      actualPos++;
    }
  }
  
  entraron.flush();
  entraron.close();
  file.flush();
  file.close();
  entraron = SD.open(entraronF, FILE_WRITE); // Abre el archivo en modo escribir
  file = SD.open(fileF, FILE_READ); // Abre el archivo en modo escribir
  while(file.available()){
    copy = file.read();
    entraron.print(copy);
    if(copy == " ") {
      return;
    }
  }
  
  entraron.flush();
  entraron.close();
  file.flush();
  file.close();
  SD.remove("FILE.TXT");
  Serial.print(F("Text removed"));
}

void addUser(String user){
  entraron.close();
  setMillis(100);
  entraron = SD.open(entraronF, FILE_WRITE); // Abre el archivo en modo escribir
  setMillis(100);
  entraron.print(user);
  entraron.print(",");
  entraron.flush();
  entraron.close();
  Serial.println(user);
  Serial.print(F("User added"));
  }

Este proyecto usa un RFID MC522, RTC DS1302, lector/grabador de sd, buzzer, boton y lcd i2c.


El código aparenta no tener fallas, pero consume demasiados recursos, alguna idea?

  • Memoria Flash: El sketch utiliza 25622 bytes de espacio de almacenamiento de programa, lo que equivale al 79% del espacio máximo disponible de 32256 bytes.
  • Memoria SRAM: Las variables globales utilizan 1512 bytes de memoria dinámica, lo que equivale al 73% de la memoria disponible para variables locales, dejando 536 bytes disponibles de un máximo de 2048 bytes.

¿Y cuál sería el problema?

¿Hay alguna razón válida para hacer la misma pregunta en dos lugares distintos del mismo foro?

https://forum.arduino.cc/t/code-optimization-for-arduino-uno/1158962

perdon amigo, ya mismo saco uno

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.