Gestionar fecha y hora con el módulo RTC DS3231 y Arduino

publicado en: Portada | 22

Desde la publicación en polaridad.es de la librería de Arduino para consultar fecha y temperatura del integrado DS3231 por I2C muchos usuarios han preguntado sobre su uso y sobre cómo gestionar con ella la fecha y la hora, no necesariamente con el RTC DS3231 sino de forma genérica.

Como estas cuestiones parecen necesarias para explotar un reloj en tiempo real, en este artículo trataré de aclararlas con el enfoque didáctico de costumbre, que me parece más valioso que simplemente dar la solución a la descarga aunque, por supuesto, quien lo prefiera, también podrá simplemente descargar las nuevas librerías al final del artículo.

Problemas de conexión

Para empezar aclarando las dudas más sencillas, el principal problema que he encontrado en los usuarios que me consultan está relacionado con la conexión I²C, tanto hardware como software. El problema físico no suele darse cuando se usa el módulo (suponiendo que todo se conecta en su sitio) pero al hacer un circuito con el DS3231 sin otras comunicaciones I²C parece un clásico olvidar las resistencias de pull-up en el bus. Ante la duda, estas resistencias pueden ser de 10 KΩ aunque, como es lógico, se pueden calcular considerando la tensión de alimentación y la intensidad en las patillas correspondientes.

circuito de aplicación para el RTC DS3231 I2C

Por otra parte, el error clásico de software usando Arduino es olvidar iniciar las comunicaciones o hacerlo varias veces si hay varios dispositivos. Para dejarlo definitivamente claro: sólo un Wire.begin() ya esté en el programa principal o el la librería, pero uno y sólo uno.

Optimización de la librería DS3231

Añadir nuevas funcionalidades a la librería va a plantear un problema nuevo: la necesidad de más memoria. Como las series pequeñas de Arduino ya van un poco justas, lo más sensato será optimizar su uso, por un lado para usar lo menos posible y por otro para poder eliminar de la versión de la librería que se use en un proyecto concreto los métodos que no sean necesarios. Esto último resulta una obviedad pero es muy importante y por la comodidad de trabajo que supone el uso de librerías con Arduino se nos olvida frecuentemente… hasta que nos quedamos sin memoria.

Para conseguir este objetivo el primer paso es separar los componentes de la librería de Arduino para el DS3231 de manera que sólo se encargue de la fecha, la hora y la temperatura, y crear una nueva librería, independiente de la anterior, que sirva para la gestión genérica de fecha y hora. Una ventaja añadida al ahorro de memoria es que se podrán usar estas nuevas funciones para otras tareas que no necesariamente impliquen al RTC DS3231 y además será mucho más fácil para los usuarios eliminar los componentes que no necesiten (por ejemplo la gestión de la temperatura) de una y otra librerías para economizar memoria.

Para hacer más compacta la consulta ya no es necesario cargar primero la hora del DS3231 y luego consultar el valor. Ahora la función cargar_fecha_hora() devuelve un puntero al valor de la fecha y la hora. De todas formas, valor_fecha_hora() se conserva por compatibilidad con la versión anterior de la librería de Arduino para el DS3231.

El siguiente código es el de la nueva librería y más abajo un ejemplo de aplicación, por ahora sin usar la librería de gestión de fechas, solo la fecha y hora del RTC DS3231.

Captura de pantalla de la memoria de la nueva librería DS3231 Arduino

Como puede verse en la anterior captura de pantalla, la suma del programa de ejemplo, la librería Wire y la nueva librería ocupan 8340 bytes de programa y 433 bytes de memoria dinámica.

Sincronizar el montaje leyendo la fecha y la hora desde el puerto serie

Otro problema clásico (y consulta habitual de los usuarios) es la primera puesta en hora del DS3231 cuando está alimentado por baterías (se supone que seguirá en hora después) y no dispone de ningún recurso para sincronizarse más que leer «manualmente» la hora.

Una forma sencilla de dar respuesta a esta necesidad es leyendo del puerto serie una entrada con una codificación esquemática de la fecha y la hora. Como ejemplo he elegido el formato {ssmmhhDDMMAA} en el que «ss» representa el valor de los segundos, «mm» el de los minutos, «hh» la hora (en formato de 24/día), «DD» el día del mes, «MM» el número del mes y «AA» el año. Todos los valores usan dos dígitos, completados con un cero a la izquierda si fuera el caso, y del año sólo se usan los dos últimos dígitos supuesto siglo XXI. Para representar, por ejemplo, el 25 de marzo de 2016 a las 17:18:19 se enviaría por el puerto serie el texto {191817250316}

DS3231 ajuste de fecha y hora con el monitor serie de Arduino

Ya que la operación de puesta en hora «manual» no se realiza en el funcionamiento normal he preferido no incluir la función en la librería para el DS3231 aunque nada impide usarla en un montaje definitivo sin más que incluirla en el código como se hace en el ejemplo siguiente.

El código de abajo corresponde con la cabecera y la función que lee la fecha y la hora desde el puerto serie para cambiar «manualmente» la de los registros del DS3231

Librería para gestionar fecha y hora con Arduino

La nueva librería de gestión de fecha y hora debe encargarse de las funciones que se han quitado a la de comunicación con el DS3231: básicamente de la presentación como texto en varios formatos, y de la comparación y modificación de fechas y horas; en concreto, debe ser capaz de establecer si una fecha u hora es igual a otra o mayor que ella (con un wrapper se podrá determinar el caso contrario), de determinar si una está comprendida entre otras dos y de incrementar o decrementar la hora.

Determinar si dos fechas u horas son iguales

La forma más sencilla de comprobar si dos fechas son iguales es ir comparando cada uno de sus componentes; sólo con que uno sea diferente la condición de igualdad no se cumplirá. Con una única función puede realizarse la comprobación de forma genérica y usar luego implementaciones para comparar solamente la hora, solamente la fecha o ambas.

Calcular si una fecha es posterior a otra (más reciente que otra)

Para establecer si una fecha es mayor (posterior) que otra hay que ir comprobando que los componentes sean mayores o iguales empezando por el último (los dos primeros dígitos del año, que en la librería se llaman «siglo» por simplificar) Al encontrar un valor menor en la comparación la fecha no será mayor; hasta ahí no hay ambigüedad pero al llegar al primero de los componentes (el valor de los segundos de la hora o el valore del día según se considere la hora o solo se trabaje con la fecha) debe elegirse cuándo el resultado se considera válido: si la fecha es mayor o igual o solamente si es mayor. Como ya existe en la librería una forma de comprobar si la fecha es igual, he elegido que se valide como cierto el resultado solamente en el caso de ser mayor. Igual que en el caso anterior, una función se ocupa de la comprobación y se usa desde otras para comparar la fecha, la hora…

Comprobar si una fecha está comprendida entre otras dos

Si una fecha es mayor que otra pero menor que una tercera, operaciones que pueden realizarse con la función del apartado anterior, se habrá verificado que está comprendida entre ellas. Solo será necesario implementar el envoltorio (wrapper) para usarlas según se necesite comprobar la fecha, la hora o las dos.

Determinar si un año es bisiesto

Se considera año bisiesto cuando es divisible por 4 pero no lo es por 10 salvo que los sea por 400. Para implementarlo se puede utilizar el operador % que devuelve el resto de la división: si el resultado es cero el número será divisible.

Calcular los días del mes de cierto año

La siguiente función utiliza un entero como una matriz de bits para obtener el número de días del año en función del número del mes. Para calcular si febrero tiene 28 o 29 días se utiliza la función del apartado anterior, los meses largos (31 días) se determinan por los bits con valor uno y los cortos (30 días) cuando el bit correspondiente vale cero.

Buscar el día de la semana de una fecha

La forma convencional de calcular el día de la semana sabiendo el día del mes, el mes y el año es por medio del algoritmo de congruencia de Zeller. La siguiente función para Arduino devuelve el día de la semana empezando en cero, que corresponde al domingo, y usando una versión adaptada del algoritmo de Zeller. Es importante recordar que el reloj en tiempo real DS3231 codifica el día de la semana empezando en uno para el domingo y terminando en siete para el sábado mientras que esta función devuelve cero para el domingo, uno para el lunes…

Disponiendo del número del día de la semana es posible modificar la asignación de la fecha y la hora en el RTC DS3231 de forma que si el día de la semana indicado como parámetro de la misma es cero se calcule automáticamente usando la anterior implementación del algoritmo de Zeller.

Es muy sencillo preparar un vector con los nombres de los meses (y de los días de la semana) para presentar fechas en «formatos humanos» pero es muy importante tener en cuenta que necesitará una buena cantidad de la memoria disponible en una placa Arduino de las series pequeñas. Aunque esta y otras opciones estarán en el documento de la librería que se descarga al final del texto, lo más sensato es eliminar los métodos que no se utilicen para ahorrar memoria.

Adelantar o retrasar la hora

Para cualquier elemento de la fecha y la hora, aumentar o disminuir un dígito supone además verificar que no se supera el máximo o el mínimo de ese dígito, 24 y 0 en el caso de la hora, y arrastrar a los siguientes dígitos el cambio en caso necesario. Las siguientes funciones implementan el proceso para la hora, que será necesaria para el siguiente apartado y que sirve como ejemplo para implementarlo en otros componentes. Como la finalidad es mantener la hora estable en el reloj en tiempo real DS3231 durante el horario estacional, se modifica directamente el vector al leer la hora o grabarla.

Compensar el horario estacional

Según la directiva 2000/84/CE del Parlamento Europeo y del Consejo, que en España se establece por el Real Decreto 236/2002, «período de la hora de verano», lo que llamamos comúnmente «horario de verano», es el período del año durante el cual la hora se adelanta en sesenta minutos respecto a la hora del resto del año. Según este primer artículo del RD, la «hora normal» es la que queda fuera de este intervalo.

Conforme a esta directiva y consiguiente RD, a partir del año 2002, el período de la hora de verano comenzará en todos los estados miembros a la 1 de la madrugada, hora universal, del último domingo de marzo y terminará en todos los Estados miembros a la 1 de la madrugada, hora universal, del último domingo de octubre. Como España ha elegido estar en UTC+1 (aunque geográficamente no sea muy exacto) la hora se cambia a las 2 de la madrugada. Para la gestión de la hora estacional en otros países deberá tenerse en cuenta esta circunstancia.

Para que la la librería de control del reloj en tiempo real DS3231 de Arduino considere el horario estacional es necesario verificar si se encuentra dentro del periodo de verano. De ser así devolvería una hora más de la que almacene o, al cambiar manualmente la hora, almacenaría una hora menos.

Para calcular el último domingo de marzo y de octubre hay que restar de 31 (último día del mes) el valor que devuelve la función dia_semana() para el último día del mes, es decir, los días que «sobran» del domingo. ultimo_domingo=31-dia_semana(31,3,16);

El resto de los métodos de la clase de la librería de Arduino para consultar fecha y temperatura del integrado DS3231 por I2C con los que dar formato a la fecha y la hora para MySQL, registros logs queda tal como en el original con la única diferencia de que ahora se usa un único buffer para formatearla para ahorrar unos bytes de memoria.

Un ejemplo de uso de las nuevas librerías para gestionar fecha y hora con el módulo RTC DS3231 y Arduino, que puedes descargar aquí, quedaría así:

Y esta es código de la nueva librería para gestionar el tiempo con Arduino

Víctor Ventura

Desarrollando aplicaciones para la web conocí el potencial de internet de las cosas, encontré la excusa perfecta para satisfacer la inquietud de aprender electrónica que había tenido desde siempre. Ahora puedo darme el gusto de programar las cosas que yo mismo diseño y fabrico.

Más entradas - Página web

Sígueme:
TwitterLinkedIn

Seguir Víctor Ventura:

Programador multimedia y web + IoT. Mejor con software libre.

Desarrollando aplicaciones para la web conocí el potencial de internet de las cosas, encontré la excusa perfecta para satisfacer la inquietud de aprender electrónica que había tenido desde siempre. Ahora puedo darme el gusto de programar las cosas que yo mismo diseño y fabrico.

22 Respuestas

  1. Chrcntos

    Hola Víctor, un trabajo impresionante.

    Podrias explicarme partiendo de la ultima libreria como se podria incrementar por ejemplo 1 hora ó 1 mes, en el DS3231 sin que esto modifique el resto de variables.

    Probe el codigo:
    fecha[INDICE_HORA]--;

    • Víctor Ventura

      Hola, Chrcntos.

      No estoy seguro de entenderte. Si quieres modificar solamente la hora, es correcto usar fecha[INDICE_HORA]--;, lo que me extraña poderosamente es que quieras hacerlo. Precisamente lo útil de (por ejemplo) del método retrasar_hora() es que «arrastra» al resto de propiedades. Suponiendo que te refieras a lo que me parece más lógico (no a lo que me parece que preguntas), es decir, incrementar el mes (ya que incrementar la hora se haría como describe el método adelantar_hora(), descrito arriba), el código sería algo así:

      Verás que he cambiado el siglo; aunque en el objeto fecha para Arduino no hay ningún problema, el RTC DS3231 solamente funciona en el siglo XXI.

      Si lo que quieres es retrasar un mes, puedes usar un código como el siguiente:

      Por cierto, en la función original, había un error (ya está corregido) al retrasar la hora, además del siglo, se había colado un índice numérico en lugar de una constante que lo enredaba todo. Además de cambiarlo, he puesto algún comentario más para tratar de explicarlo mejor.

      Espero haber sido útil pero, si no he acertado con tu pregunta, no tengas inconveniente en volver a formularla.

      Saludos y gracias por visitar polaridad.es

  2. Chrcntos

    Gracias por tu rapida respuesta Víctor.

    Mi idea es usar 4 interruptores, 2 para moverme por la matriz (hora, min, seg, año, mes, dia) y 2 para aumentar o disminuir el valor del dato seleccionado en el reloj.
    Entiendo que el codigo que me mandas iria implementado en el cpp. ¿Seria posible hacerlo directamente desde el programa .ino?.
    ¿De ser posible podrias poner un ejemplo con minutos o meses, del codigo que habria que usar para pegarlo dentro del programa que pones en tu ejemplo?

    Ejem:

    Epero que puedas ayudarme porque despues de varios intentos, se poner el reloj en hora, pero cuando intento hacerlo solo con un elemento de la matriz o se me pone el resto a 0 o me salta un error como con fecha[INDICE_HORA]--;

    sketch_jun03b:11: error: 'INDICE_HORA' was not declared in this scope

    Un saludo Víctor

    • Víctor Ventura

      Hola, Chrcntos.

      Puedo ponerte un ejemplo para usarlo con todos los elementos, pero me va a llevar un poco de tiempo, y es información de más calado que puede interesar a más lectores así que lo que voy a hacer es, en cuanto saque un rato, añadiré una versión de la librería que tenga métodos para modificar minutos, horas, días…

      El código de ejemplo con el que te respondía al comentario anterior tiene el formato de método de la clase con la que se gestiona el tiempo, así que, en efecto, está pensado para disponerlo en el documento .cpp de la librería pero no sería un problema «versionarlo» para usarlo dentro del sketch de Arduino (documento .ino).

      Como el ejemplo que mandas está incompleto no es raro el error que muestras: no has declarado (o definido) la constante INDICE_HORA (como hago yo en el documento de cabecera .h de la librería).

      Te desaconsejo la forma de esperar que usas en la línea 7, creo que es mejor el estilo que usas en las siguientes: no parar el micro, verificar que ha pasado el tiempo.

      Saludos y gracias por participar en polaridad.es

  3. Chrcntos.

    Ok Víctor pues gracias, quedo a la espera de la nueva libreria.
    Cuando tengas la libreria lista, pones un ejemplo para torpes como yo, con todas estas cosas, como adelantar hora, retrasar un día, cambiar horario verano, etc, en el sketch, eso siempre ayuda.

    Sabia que me ibas a desaconsejar el delay y me ibas a aconsejas millis (o millis y microseconds), pero un delay tiene una gran ventaja y es que se escribe más rapido :p , en mi codigo final tengo que usar millis porque voy a tener varios contadores en marcha.

    Querria adaptar esto en una pantalla con interfaz I2C, y moverme por los menus con un swich case, creo que hay opciones mejores, pero voy a andar justito de espacio en el arduino cuando junte todas las partes del programa.

    Un saludo Víctor
    Gracias por tu trabajo

  4. Angel

    si quiero sincronizar el tiempo por enternet time.nist.govi una vez al dia en vez del puerto de serie se puede.

  5. Roberto Preziuso

    Hola Víctor, estoy tratando de armar con Arduino UNO como hobby, un circuito que accione una puerta a partir de leer fecha y hora en código de barras. Es decir que, si la fecha es correcta y la hora está dentro de los 10 minutos más o menos abre una puerta. Dispongo del Arduino y estoy buscando un lector del código de barras para interconectar. No me dio cuenta de cómo realizar la comparación de los datos, la leída y la interna del Arduino. Espero tus comentarios.

    • Víctor Ventura

      Hola, Roberto.

      No puedo ayudarte mucho 🙁 nunca he utilizado un lector de código de barras desde Arduino. Por lo que sé, normalmente utilizan protocolos HID, así que no debe ser difícil conectarlos por USB o incluso más fácil por PS/2 a Arduino. A lo mejor le echo un vistazo al tema para un futuro artículo.

      ¡Hasta pronto!

  6. Roberto Preziuso

    Victor:

    Gracias por tu pronta respuesta.

    Pero, puedo consultar lo siguiente:
    Los lectores de barra vienen para USB. Entonces al Arduino UNO le instalaré el modulo USB para dicho lector (la impresora de barras imprime fecha y hora) y luego pregunto ¿debería colocar el módulo DS 3231?
    De ser así, al leer la impresión de barra, del puerto serie tendré una entrada DDMMAAAAHHMMSS, luego debería leer la fecha y hora del DS 3231 para comparar si está comprendida dentro del lapso previsto. Es correcto?

    • Víctor Ventura

      Hola, Roberto.

      Sí, la mayoría de los escáneres de códigos de barras (que yo conozco) tienen conexión USB. También hay (todavía) con conexión PS/2, que pueden ser aún más sencillos (y económicos) para conectarlos a una placa Arduino, aunque se pueden quedar antiguos antes, peores si lo quieres usar también para PC.

      Hasta donde sé, los lectores de códigos de barras devuelven un valor equivalente a la pulsación de una tecla, es decir, si distinguen en las barras un número 4 no mandan un valor 4 sino el valor que corresponde a la pulsación de la tecla del 4. Luego está el tema del dígito de control (que también depende de la codificación utilizada) que suele enviar una pulsación de la tecla «enter» (aunque he visto algunos que permiten configurar esto).

      Por lo demás, supongo que sí, que lo que planteas es viable, no sé si lo más adecuado (salvo que lo que quieras sea practicar con lectores de códigos de barras) pero podría funcionar.

      Suerte con tu proyecto y gracias por participar en polaridad.es

  7. Ale

    Hola excelente post!!

    Tengo un problema con este modulo, no mantiene la hora, lo uso para un proyecto donde esta alimentado constantemente pero luego de unos días la hora se pierde y el dispositivo deja de funcionar para lo que fue programado. Cuando voy a revisar la pila esta agotada. No deberia estar agotada ya que se mantenia alimentado a través del conector J1. ¿Que puede estar pasando?

    • Víctor Ventura

      Hola, Ale.

      Lo que te está pasando es muy habitual en las versiones más baratas de estos módulos. La pila se descarga (independiente de que esté alimentando al DS3231 o no) y si es una batería, no se recarga; así que dura unos pocos días cuando, bien gestionada, podría durar meses.

      Creo que es viable repararlos pero, por lo que valen, no merece la pena 🙁 es mejor comprarlos en un proveedor fiable, no todos los módulos (ni por supuesto el integrado) tienen este problema.

      Saludos.

  8. Vladi mir

    Hola Víctor.
    No puedo lograr disparar una determinada acción cada 48 HS .
    Poseo:
    Arduino Nano
    Rtc ds3231

    Gestionó bien cálculos de fecha pero no puedo lograrlo cada 48hs ya que me resulta difícil utilizar la eeprom del Arduino o la del rtc.

    La idea es que no se vea truncado el algoritmo por cortes de energí

    Desde ya muchas gracias

  9. jamt

    hola, cordial saludo
    que pasa si durante el evento ay un cote de energía.
    si programo una lampara para que encienda a las 22h y se pague a las 06h si en ese intervalo de las 8 horas hay un corte de energia al reiniciarse el arduino uno, pero estando el RTC con la hora actual como sincroniza el tiempo que falta y enciende la lampra para terminar el proceso ?
    #include
    #include «RTClib.h»

    RTC_DS1307 RTC;

    DateTime HoraFecha;

    void setup () {
    pinMode(13,OUTPUT);
    Wire.begin();
    RTC.begin();
    Serial.begin(9600);

    }

    void loop () {
    DateTime now = RTC.now();
    if(now.hour() == 15 && now.minute() == 55){
    digitalWrite(13,HIGH);
    }
    else if(now.hour() == 16 && now.minute() == 50){
    digitalWrite(13,LOW);
    }
    delay(2000);

  10. RUDYARD BARCENA DIAZ

    HOLA VICTOR ESTE ES UN TRABAJO MUY BUENO Y TITANICO PERO NO ENTIENDO COMO HACER EL CALMBIO DE HORARIO DE FORMA AUTOMATICO EN Compensar el horario estacional VEO LA LIBRERIA PERO DESCARGUE LA LIBRERIA DEL DS3231 Y NO SE CUAL DE LOS CODIGOS TENGO QUE AGREGAR, O BORRAR EL ORIGINAL QUE TRAE LA LIBRERIA ESPERO ME PUEDAS AYUDAR GRACIAS

  11. FRANCISCO

    Tendras una libreria o ejemplo que cambie el horario estacional en México
    Aqui empieza el primer domingo de abril (se adelanta una hora) y finaliza el ultimo domingo de octubre se atraza 1 hora

  12. Edson Rubio

    Buenas Noches, me podria dar una idea, necesito mostrar en un lcd los numeros no significativos en cuestion de minutos, es decir me aparece, 23:3 (23 horas 3 minutos) y quisiera que me apareciera 23:03, como puedo modifocarlo ??? saludos

  13. Cesar Hidalgo

    Hola como están me podrían ayudar soy nuevo en esto de los arduinos y las codificaciones estoy realizando un ejercicio de temperatura con un DTH11 y necesito programar que en el mismo se me active un ventilador según la temperatura pero a su vez con el RTC que el mismo se active según los días

    Ejemplo dentro de los primeros 10 días el ventilador se active cuando la temperatura sea de 20 grados después de pasar los 15 días el ventilador se active cuando la temperatura este en 30 grados y a los 20 días transcurridos el ventilador se active cuando la temperatura este a los 40 grados.

    Estoy utilizando este código para la temperatura

    #include «DHT.h»

    #define DHTPIN 2 // Pin donde está conectado el sensor

    //#define DHTTYPE DHT11 // Descomentar si se usa el DHT 11
    #define DHTTYPE DHT22 // Sensor DHT22
    #define pventilador 12

    DHT dht(DHTPIN, DHTTYPE);

    void setup() {
    Serial.begin(9600);
    Serial.println(«Iniciando…»);
    dht.begin();
    pinMode(13, OUTPUT);
    }
    long tiempoUltimaLectura=0;; //Para guardar el tiempo de la última lectura
    void loop() {
    //———Lectura del Sensor————————–
    if(millis()-tiempoUltimaLectura>2000)
    {
    float h = dht.readHumidity(); //Leemos la Humedad
    float t = dht.readTemperature(); //Leemos la temperatura en grados Celsius
    float f = dht.readTemperature(true); //Leemos la temperatura en grados Fahrenheit
    //——–Enviamos las lecturas por el puerto serial————-
    Serial.print(«Humedad «);
    Serial.print(h);
    Serial.print(» %t»);
    Serial.print(«Temperatura: «);
    Serial.print(t);
    Serial.print(» *C «);
    Serial.print(f);
    Serial.println(» *F»);
    tiempoUltimaLectura=millis(); //actualizamos el tiempo de la última lectura
    }
    //—-Fin de la lectura—————————

    //———Resto del código del proyecto——–
    //…
    //…
    //…
    digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
    delay(100);
    //——————————-

    }

    if (t < 24.00)
    {
    digitalWrite(pVentilador, HIGH);

    }
    else digitalWrite(pVentilador, LOW);

    }

  14. Antonio

    Hola Víctor.

    Llevo más de media hora leyendo los 3 artículos relacionados con el DS3231.
    Has hecho un trabajo buenísimo.

    Todo muy bien explicado, con ejemplos, aportando soluciones…

    Estoy empezando con arduino y por fin puedo unir mis dos gran pasiones: electrónica e informática.

    Muchas gracias.
    Un saludo desde Murcia.

    pd: voy a leer el artículo del ESP8266 porque he querido empezar ‘fuerte’ y el módulo me está dándo muchos dolores de cabeza.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *