ACTUALIZADA: Visita también la nueva librería para gestionar fecha y hora con el módulo RTC DS3231 y Arduino con mejoras como la hora estacional.
El funcionamiento de los IC de relojes en tiempo real (RTC) más populares que se controlan utilizando el bus I2C suele ser muy similar. Además, la librería Wire de Arduino simplifica mucho las comunicaciones con dispositivos Two-wire Serial Interface (TWI), I2C, en concreto.
A grandes rasgos, el proceso consiste en
-
Iniciar las comunicaciones como esclavo (slave) o maestro (master, establecidas por defecto) con la función Wire.begin(dirección). Si se omite «dirección» se inician las comunicaciones siendo el μC el maestro del bus I2C.
-
Activar la comunicación I2C con el dispositivo a través de la dirección de memoria en la que se encuentre, usando la orden Wire.beginTransmission(dirección).
-
Escribir una orden en el bus I2C para indicar al dispositivo la operación que se desea que realice, usando Wire.write(orden), en la que «orden» es el código de la operacíon.
-
Desactivar las comunicaciones para liberar el bus I2C con la función Wire.endTransmission().
-
Solicitar al dispositivo el envío de cierta cantidad de datos que corresponden con la operación que se ha solicitado (en este caso, la fecha y la hora) con la función Wire.requestFrom(dirección,cantidad).
-
Esperar a que estén disponibles para su lectura los datos solicitados con la función Wire.available(), que devuelve el número de datos que ya se han recibido y pueden leerse.
-
Leer los datos enviados por el dispositivo (el reloj en tiempo real, en este caso) usando la función Wire.read() tantas veces como bytes indique Wire.available() que están disponibles.
-
Normalmente los datos se envían en formatos muy compactos así que es muy probable que sea necesario interpretar los datos recibidos de manera que correspondan con la representación de los datos que se haga en el programa que usa el dispositivo.
En lo que se refiere al DS3231 (y a los compatibles de la misma serie, como el DS3232) y a la interpretación de los datos, según las especificaciones del integrado, por ejemplo, los valores de los distintos dígitos que representan la hora se representan en decimal codificado en binario (BCD) que será más cómodo expresar como un valor decimal (un byte) para usarlo en Arduino
En la misma línea, la temperatura se expresa como un byte en complemento a dos para la parte entera y dos bits para el paso, con una resolución de un cuarto de grado, de la parte decimal. En el código de la librería que se incluye a continuación se han comentado de forma exhaustiva estos y otros aspectos de la representación de los datos en el reloj DS3231
Para consultar la temperatura con esta librería basta con usar el método leer_temperatura() del objeto DS3231 instanciado al empezar. Para leer la fecha y la hora en primer lugar se cargan y después se solicita en uno de los formatos (compacto, humano…) disponibles para distintos usos, documentados en el documento de cabecera de la librería del código de abajo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
//DS3231.h #if defined(ARDUINO) && ARDUINO>=100 #include "Arduino.h" #else #include "WProgram.h" #endif #include <Wire.h> #define TEMPERATURA_MAXIMA_DS3231 85.0 // Máxima temperatura que se puede medir con un DS3231 (70 grados en la versión comercial / no-industrial) #define TEMPERATURA_MINIMA_DS3231 -40.0 // Mínima temperatura que se puede medir con un DS3231 (0 grados en la versión comercial / no-industrial) #define DIRECCION_DS3231 B1101000 // Según datasheet #define TIMEOUT_I2C_DS3231 200 // Máximo tiempo de espera del bus I2C del DS3231 #define NUMERO_ELEMENTOS_FECHA 7 // Número de elementos (un byte por elemento) que tiene la matriz con los datos de la fecha #define NUMERO_BYTES_TEMPERATURA 2 // Número de bytes con los que se representa la temperatura (uno para la parte entera y el signo y otro para la parte decimal representada con una resolución de 0.25 grados) #define RESOLUCION_DECIMALES_DS3231 0.25 // Grados de cada paso de la parte decimal #define ROTACION_DECIMALES 6 // Rotación necesaria hasta llegar a los bits que contienen la parte que representa los decimales de la temperatura (rotar 6 corresponde a atender a los bits 7 y 8) #define MASCARA_DECIMALES B11000000 // Máscara para eliminar con una operación and la parte no significativa. En el caso el DS3231 no hace nada ya que al rotar queda sólo la parte relevante. class DS3231 { private: char valor_fecha_hora_DS3231[7]; // Matriz de valores numéricos (7 char) de la fecha y la hora. El índice 0 representa los segundos, el 1 los minutos, el 2 las horas (en formato de 24), el 3 el día de la semana empezando en el domingo que es 1, el 4 el día del mes, el 5 el número del mes y el 6 los dos últimos dígitos del año char hora_humana_DS3231[11]; // Hora en el formato hh:mm:ss siendo hh la hora (en formato de 24) representada con 2 dígitos, mm los minutos con 2 dígitos y ss los segundos con 2 dígitos char fecha_humana_DS3231[11]; // Fecha en formato DD/MM/AAAA siendo DD el día representado con 2 dígitos, MM el mes con 2 dígitos y AAAA el año con 4 dígitos char fecha_hora_MySQL_DS3231[20]; // Fecha en formato AAAA-MM-DD hh:mm:ss (estilo MySQL) siendo AAAA el año representado con 4 dígitos, MM el mes con 2 dígitos, DD el día con 2 dígitos, hh la hora (en formato de 24) con 2 dígitos, mm los minutos con 2 dígitos y ss los segundos con 2 dígitos char fecha_hora_compacta_DS3231[13]; // Fecha en formato compacto (como la anterior pero sin adornos y dos dígitos para el año) para escribir en log y en bases de datos char bcd_a_decimal(char bcd); // Convertir de BCD a decimal char decimal_a_bcd(char decimal); // Convertir de decimal a BCD protected: public: DS3231(); ~DS3231(); void cargar_fecha_hora(); void grabar_fecha_hora(char *fecha); char *valor_fecha_hora(); char *hora_humana(); // Hora en el formato hh:mm:ss siendo hh la hora (en formato de 24) representada con 2 dígitos, mm los minutos con 2 dígitos y ss los segundos con 2 dígitos unsigned int reloj_4_digitos_7_segmentos(); // La hora tal como la esperan la mayoría de relojes de cuatro dígitos LED de 7 segmentos char *fecha_humana(); // Fecha en formato DD/MM/AAAA siendo DD el día representado con 2 dígitos, MM el mes con 2 dígitos y AAAA el año con 4 dígitos char numero_dia_semana(); // Eso y empezando en domingo que es el 1 char *fecha_hora_MySQL(); // Fecha en formato AAAA-MM-DD hh:mm:ss (estilo MySQL) siendo AAAA el año representado con 4 dígitos, MM el mes con 2 dígitos, DD el día con 2 dígitos, hh la hora (en formato de 24) con 2 dígitos, mm los minutos con 2 dígitos y ss los segundos con 2 dígitos char *fecha_hora_compacta(); // Fecha en formato compacto (como la anterior pero sin adornos y dos dígitos para el año) para escribir en log y en bases de datos double leer_temperatura(); double temperatura_minima(); double temperatura_maxima(); }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
//DS3231.cpp #include "DS3231.h" DS3231::DS3231() { //Wire.begin(); // Dependiendo de la versión del IDE puede ser maestro por defecto o no y habrá que activar en la librería o en la aplicación que la use (en el ejemplo se activa desde la aplicación, lo que permite un uso más genérico) } DS3231::~DS3231() { } void DS3231::cargar_fecha_hora() { unsigned long timeout_i2c; byte contador; Wire.beginTransmission(DIRECCION_DS3231); // Comunicar con el DS3231 en la dirección correspondiente Wire.write(0x00); // pedir registros desde la primera dirección Wire.endTransmission(); // Liberar el bus I2C Wire.requestFrom(DIRECCION_DS3231,NUMERO_ELEMENTOS_FECHA); // esperar NUMERO_ELEMENTOS_FECHA bytes timeout_i2c=millis()+TIMEOUT_I2C_DS3231; while(Wire.available()<NUMERO_ELEMENTOS_FECHA&&millis()<timeout_i2c){} // Esperar a que lleguen los datos o a que pase el tiempo mínimo de espera // Para usar sin espera: if(Wire.available()) for(contador=0;contador<NUMERO_ELEMENTOS_FECHA;contador++) { valor_fecha_hora_DS3231[contador]= Wire.read(); // Leer todos los datos sin discriminar aunque luego tendrán distinto tratamiento } valor_fecha_hora_DS3231[0]=bcd_a_decimal(valor_fecha_hora_DS3231[0]); // segundos en BCD valor_fecha_hora_DS3231[1]=bcd_a_decimal(valor_fecha_hora_DS3231[1]); // minutos en BCD valor_fecha_hora_DS3231[2]=((valor_fecha_hora_DS3231[2]&B00110000)>>4)*10+(valor_fecha_hora_DS3231[2]&B00001111); // BCD en modo de 24 horas valor_fecha_hora_DS3231[3]=valor_fecha_hora_DS3231[3]&B00000111; // Número de día de la semana empezando en 1 que es domingo valor_fecha_hora_DS3231[4]=((valor_fecha_hora_DS3231[4]&B00110000)>>4)*10+(valor_fecha_hora_DS3231[4]&B00001111); // Número del día del mes valor_fecha_hora_DS3231[5]=((valor_fecha_hora_DS3231[5]&B00010000)>>4)*10+(valor_fecha_hora_DS3231[5]&B00001111); // Número de mes (sin MSB) valor_fecha_hora_DS3231[6]=bcd_a_decimal(valor_fecha_hora_DS3231[6]); // Año en BCD (dos últimos dígitos) } char *DS3231::valor_fecha_hora() { //cargar_fecha_hora(); return valor_fecha_hora_DS3231; } char *DS3231::hora_humana() { //cargar_fecha_hora(); sprintf ( hora_humana_DS3231, "%02d:%02d:%02d", valor_fecha_hora_DS3231[2], valor_fecha_hora_DS3231[1], valor_fecha_hora_DS3231[0] ); return hora_humana_DS3231; } unsigned int DS3231::reloj_4_digitos_7_segmentos() { //cargar_fecha_hora(); return (int)valor_fecha_hora_DS3231[2]*100+(int)valor_fecha_hora_DS3231[1]; } char *DS3231::fecha_humana() { //cargar_fecha_hora(); sprintf ( fecha_humana_DS3231, "%02d/%02d/20%02d", // Formato de fecha y hora estilo español ¡Olé! valor_fecha_hora_DS3231[4], valor_fecha_hora_DS3231[5], valor_fecha_hora_DS3231[6] ); return fecha_humana_DS3231; } char DS3231::numero_dia_semana() { //cargar_fecha_hora(); return valor_fecha_hora_DS3231[3]; } char *DS3231::fecha_hora_compacta() { //cargar_fecha_hora(); sprintf ( fecha_hora_compacta_DS3231, "%02d%02d%02d%02d%02d%02d", // Formato de fecha y hora compacta para log y base de datos valor_fecha_hora_DS3231[6], valor_fecha_hora_DS3231[5], valor_fecha_hora_DS3231[4], valor_fecha_hora_DS3231[2], valor_fecha_hora_DS3231[1], valor_fecha_hora_DS3231[0] ); return fecha_hora_compacta_DS3231; } char *DS3231::fecha_hora_MySQL() { //cargar_fecha_hora(); sprintf ( fecha_hora_MySQL_DS3231, "20%02d-%02d-%02d %02d:%02d:%02d", // Formato de fecha y hora estilo MySQL valor_fecha_hora_DS3231[6], valor_fecha_hora_DS3231[5], valor_fecha_hora_DS3231[4], valor_fecha_hora_DS3231[2], valor_fecha_hora_DS3231[1], valor_fecha_hora_DS3231[0] ); return fecha_hora_MySQL_DS3231; } void DS3231::grabar_fecha_hora(char *fecha) { byte contador; Wire.beginTransmission(DIRECCION_DS3231); // Comunicar con el DS3231 en la dirección correspondiente Wire.write(0x00); // Empezar el envío en la primera dirección for(contador=0;contador<NUMERO_ELEMENTOS_FECHA;contador++) { Wire.write(decimal_a_bcd(fecha[contador])); // Escribir cada valor expresándolo en BCD } Wire.endTransmission(); // Liberar el bus I2C } double DS3231::leer_temperatura() { byte msb; // El byte más significativo contiene la parte entera de la temperatura (en complemento a 2 para poder representar temperaturas bajo cero) byte lsb; // El byte menos significatico contiene la parte decimal con una resolución de un cuarto de grado float temperatura=TEMPERATURA_MAXIMA_DS3231+1.0; // Un número mayor que el máximo como aviso de que algo va mal boolean negativo=false; // Inicialmente se considera postivo unsigned long timeout_i2c; Wire.beginTransmission(DIRECCION_DS3231); // Preparar el dispositivo Wire.write(0x11); // Solicitar temperatura (empieza en 11h y termina en 12h) Wire.endTransmission(); Wire.requestFrom(DIRECCION_DS3231,NUMERO_BYTES_TEMPERATURA); // Esperar temperatura: pedir dos bytes en la dirección del integrado timeout_i2c=millis()+TIMEOUT_I2C_DS3231; while(Wire.available()<NUMERO_BYTES_TEMPERATURA&&millis()<timeout_i2c){}// Esperar a que lleguen los datos o pase el tiempo de espera máximo // Para usar sin espera: if(Wire.available()) msb=Wire.read(); // parte entera con signo en complemento a dos lsb=Wire.read(); // parte fraccional con resolución de 0.25 grados negativo=msb>B01111111; // Es negativo si el primer dígito es uno temperatura=msb&B01111111; // revertir complemento a dos temperatura+=((lsb&MASCARA_DECIMALES)>>ROTACION_DECIMALES)*RESOLUCION_DECIMALES_DS3231; // atender sólo a los bits que contienen la parte decimal (7 y 8), multiplicar por el paso de la resolución y sumar a la parte entera de la temperatura if(negativo) { temperatura*=-1; // Cambiar el signo } return temperatura; } double DS3231::temperatura_minima() { return TEMPERATURA_MINIMA_DS3231; } double DS3231::temperatura_maxima() { return TEMPERATURA_MAXIMA_DS3231; } char DS3231::bcd_a_decimal(char bcd) // Convertir de BCD a decimal { return ((bcd&B11110000)>>4)*10+(bcd&B00001111); } char DS3231::decimal_a_bcd(char decimal) // Convertir de decimal a BCD { return decimal/10*16+(decimal%10); } |
El siguiente es un código de ejemplo para mostrar cómo usar la librería. Como se decía más arriba, la temperatura se lee simplemente con la función
del objeto de la clase pero, para ignorar errores en la lectura, se utilizan dos constantes que almacenan, respectivamente, la temperatura máxima y mínima del dispositivo según la hoja de datos y que se leen con las funciones correspondientes.La lectura de la temperatura se realiza en dos tiempos: en primer lugar se carga el valor, con lo que diferentes usos de la fecha o la hora serán coherentes (no mostrarán un valor mayor en casos desfavorables) y en segundo lugar se usa conforme al formato que se necesite. En el programa de ejemplo (que no es muy práctico, aunque explica todas las posibilidades) se muestran todos los formatos disponibles
-
La función char (bytes) que contiene los siete valores numéricos que representan la fecha y la hora en un reloj DS3231 convertidos a decimal (están en BCD en el dispositivo)
que devuelve un puntero a una matriz de -
Usando la función
se obtiene un valor que corresponde con el número del día de la semana empezando en domingo. Para mostrarlo como texto se utiliza una matriz y se resta uno para empezar en el índice cero, domingo. -
Para consultar la fecha en un formato «local» (español) se usa la función
, que entrega un puntero a una cadena en la que se representa la fecha en formato DD/MM/AAAA, siendo DD el día representado con 2 dígitos, MM el mes con 2 dígitos y AAAA el año con 4 dígitos. -
La función
devuelve la hora en el formato hh:mm:ss, siendo hh la hora (en formato de 24) representada con 2 dígitos, mm los minutos con 2 dígitos y ss los segundos con 2 dígitos. -
Para usar fácilmente la fecha y la hora en archivos de registro (log) se ha programado la función , que entrega el valor de la fecha y la hora en el formato AAMMDDhhmmss siendo AA el año representado con los 2 últimos dígitos, MM el mes con 2 dígitos, DD el día con 2 dígitos, hh la hora (en formato de 24) con 2 dígitos, mm los minutos con 2 dígitos y ss los segundos con 2 dígitos. Este formato, aún siendo de texto, ocupa poco y permite una ordenación alfabética muy sencilla.
-
La función MySQL (o la nueva y más libre MariaDB) AAAA-MM-DD hh:mm:ss, siendo AAAA el año representado con 4 dígitos, MM el mes con 2 dígitos, DD el día con 2 dígitos, hh la hora (en formato de 24) con 2 dígitos, mm los minutos con 2 dígitos y ss los segundos con 2 dígitos.
sirve para presentar la fecha y la hora en el formato que usa el gestor de bases de datos
Aunque son muchos formatos con los que representar la fecha y la hora, puede que no esté el que necesitas, pero seguro que basándote en alguno de los que hay y usándolo como ejemplo, será sencillo añadir un nuevo método conforme a otras especificaciones. Por favor, si añades nuevas funciones, comparte el código (¡libéralo!) y explícanos cómo funciona, así vamos haciendo mejor la librería poco a poco ¡Gracias!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
#define INTERVALO_MEDICION 100000 // Medir temperatura cada 100 segundos (se renueva internamente en el DS3231 cada 64 segundos) #define ESPERA_ERROR 1000 // Tiempo de espera antes de volver a medir si se ha producido un error #define ELEMENTOS_MATRIZ_FECHA 7 #include "DS3231.h" #include <Wire.h> char buffer_fecha[ELEMENTOS_MATRIZ_FECHA]; char *puntero_fecha; float temperatura; unsigned long cronometro; byte contador; String dia_semana[]={"lunes","martes","miércoles","jueves","viernes","sábado","domingo"}; DS3231 reloj; void setup() { Serial.begin(9600); Wire.begin(); // Inicializar Wire sólo si no se hace dentro del constructor (de la librería) Este método, hacerlo en la aplicación, supone que se usa Wire para comunicar con otros dispositivos, no sólo con el DS3231 cronometro=0; // para que empiece inmediatamente } void loop() { if(millis()>cronometro) { temperatura=reloj.leer_temperatura(); if(temperatura>reloj.temperatura_maxima()||temperatura<reloj.temperatura_minima()) { cronometro=millis()+ESPERA_ERROR; } else { cronometro=millis()+INTERVALO_MEDICION; reloj.cargar_fecha_hora(); puntero_fecha=reloj.valor_fecha_hora(); for(contador=0;contador<ELEMENTOS_MATRIZ_FECHA;contador++) { buffer_fecha[contador]=*(puntero_fecha+contador); Serial.println("Contenido de la posición "+String(contador,DEC)+" del buffer de la fecha -> "+String(int(buffer_fecha[contador]),DEC)); } Serial.print("El día "); Serial.print(reloj.fecha_humana()); Serial.print(", "); Serial.print(dia_semana[reloj.numero_dia_semana()-1]); Serial.print(", a las "); Serial.println(reloj.hora_humana()); Serial.print("("); Serial.print(reloj.reloj_4_digitos_7_segmentos()); Serial.print(" en un reloj de 4 dígitos y "); Serial.print(reloj.fecha_hora_MySQL()); Serial.print(" según MySQL o "); Serial.print(reloj.fecha_hora_compacta()); Serial.println(" abreviadamente)"); Serial.print("la temperatura era de "); Serial.print(temperatura); // Mostrar la temperatura Serial.println(" grados centígrados"); } } } |
La salida del anterior programa de ejemplo podría ser algo parecido a lo que se muestra en la siguiente imagen: una lista de 7 valores (segundos, minutos, hora, día de la semana, día del mes, mes y año) la fecha y la hora expresadas de forma «humana» (según el estilo español) la hora como un número entero en el formato de los relojes de cuatro dígitos, la fecha y la hora en formato de la base de datos MySQL, la fecha y la hora en formato compacto (para logs) y la temperatura interna del DS3231.
mikael
como puedo descargar estas librerias
gracias
Víctor Ventura
Hola, Mikael.
Aquí puedes descargar la librería Arduino para el DS3231
¡Que te sea útil!
mikael
muchas gracias me sera muy util
mikael
Siento la molestia pero al tratar de compilar el codigo de ejemplo que pones aqui me de error de compilacion.
adjunto copia de los errores
Arduino:1.6.5 (Windows Vista), Placa:»Arduino Uno»
DS3231\DS3231.cpp.o: In function
DS3231::DS3231()':
DS3231::DS3231()’C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire/Wire.h:73: multiple definition of
DS3231.cpp.o:C:\Users\Mikael\AppData\Local\Temp\build5789158021410268843.tmp/DS3231.cpp:5: first defined here
DS3231\DS3231.cpp.o: In function
DS3231::DS3231()':
DS3231::DS3231()’C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire/Wire.h:73: multiple definition of
DS3231.cpp.o:C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire/Wire.h:73: first defined here
collect2.exe: error: ld returned 1 exit status
Multiple libraries were found for «DS3231.h»
Used: C:\Users\Mikael\Documents\Arduino\libraries\DS3231
Not used: C:\Program Files (x86)\Arduino\libraries\DS3231
Error de compilación
This report would have more information with
«Show verbose output during compilation»
activala desde Archivo > Preferencias
Víctor Ventura
Hola, Mikael.
Parece que ya has cargado la librería Wire en tu programa (a lo mejor otra librería que también usas es la que lo hace
De ser así puedes editar el documento «DS3231.h» y borrar (o mejor, comentar) la línea 9 en la que se carga Wire para comunicar con el DS3231.
Saludos y suerte con tu proyecto.
mikael
muchas gracias pero sigue sin funcionar.
comento la linea 9 como me dices anulando la carga de wire desde ds3221.h
al comprobar me dice que wire no esta declarado en 3231.ccp
Adjunto errores :
Arduino:1.6.5 (Windows Vista), Placa:»Arduino Uno»
DS3231.cpp: In member function ‘void DS3231::cargar_fecha_hora()’:
DS3231.cpp:18: error: ‘Wire’ was not declared in this scope
Wire.beginTransmission(DIRECCION_DS3231); // Comunicar con el DS3231 en la dirección correspondiente
^
DS3231.cpp: In member function ‘void DS3231::grabar_fecha_hora(char*)’:
DS3231.cpp:120: error: ‘Wire’ was not declared in this scope
Wire.beginTransmission(DIRECCION_DS3231); // Comunicar con el DS3231 en la dirección correspondiente
^
DS3231.cpp: In member function ‘double DS3231::leer_temperatura()’:
DS3231.cpp:136: error: ‘Wire’ was not declared in this scope
Wire.beginTransmission(DIRECCION_DS3231); // Preparar el dispositivo
^
Multiple libraries were found for «DS3231.h»
Used: C:\Users\Mikael\Documents\Arduino\libraries\DS3231
Not used: C:\Program Files (x86)\Arduino\libraries\DS3231
‘Wire’ was not declared in this scope
Arduino Version: 1.6.5-r2
¿puede ser problema de las direcciones I2C ?
soy muy nuevo en esto lo siento
Víctor Ventura
Hola, Mikael.
Las direcciones I2C no tienen nada que ver con esto.
Por el texto de error que mandas está claro que no era el problema que te decía, así que lo de comentar la línea que carga la librería Wire (línea 9) no es; toca «descomentarla» y volver a empezar.
¿Puedes dar alguna pista más de cómo es tu código y/o de cómo estás usando la librería? Así a ciegas nos podemos pasar meses hasta saber qué puede ser 🙂
Saludos.
mikael
todo esto me pasacon el programa de ejemplo que tienes aqui mismo
Víctor Ventura
Pues esa es una pedazo de pista porque ese ejemplo me funcionó perfectamente, que lo probé antes de publicarlo 🙂
mikael
a ver te cuento
copio el codigo de ejemplo tal cual y pego
en la misma carpeta que guardo el .ino con el codigo tengo la libreria tanto .h como .ccp
tambien estan en la carpeta de librerias de arduino
el ide de arduino es el 1.6.5
no se que mas datos darte
Víctor Ventura
Lo de que lo usas con el programa de prueba y la versión del IDE parece relevante. Voy a descargar y probar, que normalmente trabajo con el IDE estable de la distribución, y te cuento.
mikael
por cierto saludos y muchas gracias
que los lunes mi educacion esta de baja
Víctor Ventura
De nada, y ánimo con ese lunes, en unas horas tu educación se recupera y ya te veo poniendo los tenedores y los cuchillos en su lado de la mesa y todo eso 😀
mikael
na los lunes se come con las manos 🙂
Víctor Ventura
Hola, Mikael.
Tengo una buena-mala noticia: he descargado el IDE 1.6.5 y he compilado el programa de prueba correctamente.
Puedes descargar la prueba por si te aclara algo o hasta te funciona (avisa en tal caso, por favor)
La verdad es que no se me ocurre qué problema puede ser (a ciegas…) Si me das alguna pista más a lo mejor puedo seguir investigando por otro lado.
Saludos y otra vez suerte.
mikael
he descargado la prueba y da el mismo error
por si las moscas he desisntalado el ide he borrado manualmente las carpetas residuales y he vuelto a instalar
sige igual 🙁
¿pudiera ser algun residuo de otras instalaciones ? ni idea
Víctor Ventura
¿Mismo-mismo error? A lo mejor no está claro (culpa mía) cómo usar lo que te he mandado: descárgalo, descomprímelo, graba el contenido en una carpeta que se llame «prueba_libreria_DS3231» (que no le gusta a Arduino que el sketch esté en una carpeta con distinto nombre) y ejecútalo. Es decir: no grabes la librería en la carpeta de librerías (para empezar a probar)
mikael
asi lo he echo
pero nada
estoy pasando cleaner a ver
D4n1
Hola, muy buena la librería.
El problema que tengo es que no he podido poner el reloj en hora la primera vez.
Supongo que tengo que usar la función grabar_fecha_hora(*fecha) pero no lo consigo.
¿Como sería?
Muchas gracias.
un saludo
Víctor Ventura
Hola, D4N1.
En efecto, para «poner en hora» el DS3231 con esta librería hay que usar la función
grabar_fecha_hora
y pasarle como parámetro una matriz dechar
que represente la fecha y la hora en el formato que indico en la declaración devalor_fecha_hora_DS3231
, es decir, el valor del índice 0 representa los segundos, el 1 los minutos, el 2 las horas (en formato de 24), el 3 el día de la semana empezando en el domingo que es 1, el 4 el día del mes, el 5 el número del mes y el 6 los dos últimos dígitos del año.Un error (típico) podría ser expresar el parámetro que representa la fecha y la hora como un texto en lugar de un vector (matriz) de valores, pero para poder decírtelo con seguridad necesitaría ver la parte del programa que no te funciona. Si con esta pista no te ayudo no tengas inconveniente en mandarme el código que te da problemas para que le eche un vistazo a ver si encuentro el error.
¡Gracias a ti por visitar el blog!
D4n1
Gracias por contestar tan rápido.
Estoy usando tu mismo código, la única modificación es:
he declarado la variable con la fecha char setHora[]={0,52,16,2,4,1,16};
en el setup llamo a la función reloj.grabar_fecha_hora(setHora);
el resultado que muestra por el serial es:
Contenido de la posicion 0 del buffer de la fecha -> -91
Contenido de la posicion 1 del buffer de la fecha -> -91
Contenido de la posicion 2 del buffer de la fecha -> 45
Contenido de la posicion 3 del buffer de la fecha -> 7
Contenido de la posicion 4 del buffer de la fecha -> 45
Contenido de la posicion 5 del buffer de la fecha -> 25
Contenido de la posicion 6 del buffer de la fecha -> -91
El dia 45/25/20-91, , a las 45:-91:-91
(4409 en un reloj de 4 digitos y 20-91-25-45 45:-91:-91 segun MySQL o 45:-91 abreviadamente)
la temperatura era de -127.75 grados centigrados
No se si es por la llamada a reloj.grabar_fecha_hora que la estoy haciendo mal o puede ser un problema con el reloj porque en la parte de leer la temperatura me da error aunque el led rojo del reloj se enciende cada vez que hace una lectura.
Muchas gracias.
Un saludo.
Víctor Ventura
Hola, D4N1.
Parece que el problema no está relacionado con el establecimiento de la fecha y la hora ¿Has verificado que la hora se va incrementando aunque empiece mal?
Me da la impresión de que no está comunicando bien por I2C ¿En alguna parte del programa inicializas el bus con
Wire.begin
? Suele ser un problema habitual, por ejemplo, cuando se trabaja con varios componentes I2C.Otro problema podría ser la dirección del dispositivo I2C, normalmente se inicializa sin indicarla, con
Wire.begin()
, pero según cómo sea tu circuito (el módulo con el DS3231) puede ser necesario indicarla expresamente.¿Eso te ayuda? No tengas inconveniente en seguir preguntando si te hace falta.
D4n1
Hola Víctor,
Me funciona perfectamente, el problema era que el cable GND no hacía contacto en la placa de prototipado. Ahora el led del reloj ya está fijo.
Ya he trasladado la librería a mi proyecto y funciona muy bien haciendo un cast en el menú de configurar la hora.
char setHora[]={0,(char)minute,(char)hour,(char)dayOfWeek,(char)dayOfMonth,(char)month,(char)year};
reloj.grabar_fecha_hora(setHora);
Muchísimas gracias por la librería y por la ayuda prestada.
Un saludo
Víctor Ventura
¡¡Estupendo!! Gracias por contárnoslo, así se aprende mucho 🙂
David
Hola, muy buena la librería del RTC, una pregunta, habría alguna manera con su libreria de hacer esto: if(Reloj.IsLater( 7,15 ) && Reloj.IsPrevious( 13,18 ));
Un saludo y muchas gracias
Víctor Ventura
Hola, David.
La librería que explico en este artículo pretende principalmente controlar el DS3231 y explicar un poco su funcionamiento y su uso junto con la entrada sobre las comunicaciones I2C con el reloj en tiempo real DS3231.
Como habrás visto, en los ejemplos he optado por incluir recursos para presentar la hora en un display o almacenarla en una base de datos MySQL, pero no he incluido otras para comparar fechas (lo que tú pides, si lo he entendido bien) ni otras para actualizar el cambio de horario en verano, por ejemplo (algo, por cierto, muy demandado también)
Tomo nota tanto de tu sugerencia para comparar fechas y horas, como de la modificación de la hora estacional y como de otras (algunas muy interesantes, la verdad) y seguramente las desarrollaré y las publicaré (ojalá que pronto)
Dicho lo anterior, aprovecho para comentar unas cuestiones que creo que no estoy dejando muy claro en mis artículos y que lleva a los lectores de polaridad.es a confusión.
Muchos lectores me preguntaban por la descarga de las librerías y me extrañaba ¿Por qué no copian y pegan lo que necesitan? Después entendí que buscaban soluciones finales y aunque ahora suelo facilitar las descargas, cosa que puede confundir en su objetivo, sigo con la misma filosofía, en general más didáctica que de explotación.
Ni mucho menos digo que tu caso sea el del último punto pero, por si mi experiencia puede ayudarte con carácter general, en el contexto que he planteado es útil tratar de resolver primero el problema (ver si una fecha es mayor que otra o si está vigente el horario estacional) con los recursos disponibles (comparar año, comparar mes, comparar día…) y luego considerar si procede la generalización (incorporar una nueva función a una librería)
Muchas gracias por tu aportación ¡Espero ver más por aquí! ¡Hasta pronto!
Luis
Hola, felicidades por el tutorial sobre las librerias.
Lla verdad es que se aprende bastante viendo las distintas librerias que hay de cada RTC. Tengo una libreria (no creacion mia)que aporta algo similar a lo que David pide por asi decirlo, la unica pega es que por alguna razon no reconoce las horas comprendidas entre 00 y 10 y salta el programa. seria un buen aporte complementar una con la otra o adaptar su libreria a esa peticion, ya que actualmente hay muy pocas librerias para RTC con esa aportacion extra. Un saludo y siga asi compartiendo y enseñando. Mis felicitaciones
Víctor Ventura
Hola, Luis.
Pues si es os parece tan interesante, en cuanto tenga un rato libre publico algo al respecto y si es posible añado y/o comento los otros aspectos que sobre la fecha y hora están en el aire.
Gracias por aportar tu opinión ¡Hasta pronto!
gustavo
Hola.
Victor, tanto con esta libreria como otras que encontre por el google. cuando pasa 1 segundo a esta hora: 24:59:29 (h:m:s) el reloj pone: 25:0:0 (25 horas….) que estoy haciendo mal en todo este quilombete? la pila esta bien (ya le medi con un multimetro). gracias
salva
Hola me parece genial como esta Todo explicado.
Pero tengo una duda.
Puedo llamar directamente a la instrucción grabar _ hora o similar directamente por ejemplo grabar_hora (10,23,45,3,12,02,16);
Víctor Ventura
Hola, Salva.
Para llamar a
grabar_fecha_hora
hay que pasarle un vector dechar
con los datos en lugar de cada dato por separado (es decir, tu ejemplo no valdría)Como parece que es una petición bastante habitual voy a ver si saco un poco de tiempo y añado una función que lo haga como dices en tu comentario y de camino añado otras sugerencias como la hora estacional.
¡Gracias por visitar polaridad.es!
salvador
gracias
ya esta solucionado
char setHora[]={0,06,10,7,19,3,16};
reloj.grabar_fecha_hora(setHora);
pero una pregunta bueno dos por una parte he visto la libreria cpp que es una libreria hecha en c++? y otra que el objeto reloj no encuentro donde lo has creado.
bamos que la libreria al principio no me funcionaba por que no habia puesto reloj.etc
lo demas he programado algo de c# y mas de c y lo entiendo pero estoy empezando en arduino que vengo de muchos años con el pic con el c de ccs y me gusta mas la interaccion de arduuino
pero el objeto reloj me ha creado dudas
DS3231 reloj;
Y nuevamente enhorabuena por tu Pagina me parece maravillosa animo y publica mas cosas
Víctor Ventura
Hola, Salvador.
La librería está programada en C++ usando las librerías correspondientes de Arduino. Podríamos decir que está «programada en Arduino» XD
El objeto reloj se crea (vacío) al declararlo en la línea 14 del ejemplo.
Gracias por tus halagos. Claro que publicaré más cosas ¡y espero que te gusten!
¡Vuelve pronto!
salvador
DE NADA despues de grabar la fecha_hora puede ser que se quede parado el reloj y haiga que ponerlo en podo run
Víctor Ventura
Hola, Salvador.
No, después de ponerlo en hora puede usarse inmediatamente. Lo que no necesariamente funciona al empezar a usarlo es la temperatura, que tarda un poco desde que se conecta (esto es por el DS3231, no por el programa)
¡Saludos!
salva
Hola Victor tengo un problema tengo el reloj funcionando pero cuando grabo la hora despues de 17 pasa a 10 si voy subiendo.
Gasto Clock.setHour (hour)
He probado a poner que fubcione en 12h y 24h y lo mismo lo que si lo dejas si que rebasa el mismo los 17 y narca 21, etc
Víctor Ventura
Hola, Salva.
No entiendo tu pregunta ¿Puede ser que te refieras a otra librería?
En la que yo he hecho, lo acabo de verificar, pasa de las 17 a las 18 sin problemas (tampoco tengo muy claro si te refieres a eso)
Por cierto, he publicado una actualización de la librería DS3231 y otra de la gestión de fecha y hora.
Saludos.
salva
Lo he probado de todas formas
Víctor Ventura
Hola, Salva.
La librería que yo he desarrollado no tiene ningún método setHour() No tengo la menor idea de lo que has probado. A lo mejor si nos das más información te podemos ayudar.
Saludos.
salvador
gracias ahora mismo lo miro y cambio la libreria para probar
salvador
DE TODAS FORMAS UNA PREGUNTA
COMO PODRIA LEER EL BYTE DE LA DIRECCION 0X02 QUE CORRESPONDE A LA HORA PARA VER TODO EL DATO SOLO CON WIRE.
Wire.begin();
Wire.requestFrom(2, 1);
while(Wire.available())
{
char Datos = Wire.read(); // Leemos un byte y lo pasamos a una variable de tipo char
Serial.print(Datos); // Lo mostramos en el puerto serie
}
Víctor Ventura
Hola, Salvador.
Creo que esto es lo que pides:
Espero que te sirva.
Saludos.
salva
Gracias grande tus aportes
Desde luego que eres bueno
salvador
mira estoy modificando mi programa para tu libreria he tenido que borrar bastantes cosas pero lo he dejado para que solo muestre los datos por el lcd.
pero me da error de libreria mira:
C:\Users\PRESID~1\AppData\Local\Temp\buildcd51d280c9b80e87bc7b542d5b5b3525.tmp\sketch\PROGRAMADOR_LED.ino.cpp.o: In function
REFRESCO()':
C:\Users\Presidente\Documents\Arduino\PROGRAMADOR_LED/PROGRAMADOR_LED.ino:561: undefined reference to DS3231::cargar_fecha_hora()’
C:\Users\PRESID~1\AppData\Local\Temp\buildcd51d280c9b80e87bc7b542d5b5b3525.tmp\sketch\PROGRAMADOR_LED.ino.cpp.o: In function
loop':
C:\Users\Presidente\Documents\Arduino\PROGRAMADOR_LED/PROGRAMADOR_LED.ino:449: undefined reference to DS3231::cargar_fecha_hora()’
C:\Users\Presidente\Documents\Arduino\PROGRAMADOR_LED/PROGRAMADOR_LED.ino:408: undefined reference to
DS3231::cargar_fecha_hora()'
C:\Users\Presidente\Documents\Arduino\PROGRAMADOR_LED/PROGRAMADOR_LED.ino:482: undefined reference to DS3231::cargar_fecha_hora()’
C:\Users\PRESID~1\AppData\Local\Temp\buildcd51d280c9b80e87bc7b542d5b5b3525.tmp\sketch\PROGRAMADOR_LED.ino.cpp.o: In function
__static_initialization_and_destruction_0':
C:\Users\Presidente\Documents\Arduino\PROGRAMADOR_LED/PROGRAMADOR_LED.ino:40: undefined reference to DS3231::~DS3231()’
C:\Users\PRESID~1\AppData\Local\Temp\buildcd51d280c9b80e87bc7b542d5b5b3525.tmp\sketch\PROGRAMADOR_LED.ino.cpp.o: In function
setup':
C:\Users\Presidente\Documents\Arduino\PROGRAMADOR_LED/PROGRAMADOR_LED.ino:84: undefined reference to DS3231::cargar_fecha_hora()’
collect2.exe: error: ld returned 1 exit status
y el program,a es este
#include
#include // F Malpartida’s NewLiquidCrystal library
#include «DS3231.h»
#include
#define I2C_ADDR 0x27 // Direccion I2C para PCF8574A que es el que lleva nuestra placa diseñada por MJKDZ
#define INTERVALO_MEDICION 10000
#define ESPERA_ERROR 1000
#define LONGITUD_BUFFER_DS3231 7
#define LONGITUD_FECHA_FORMATEADA 18
//definimos las constantes para esta placa
#define MENU 4
#define ENTER 7
#define SUBE 6
#define BAJA 5
//////////////////////////////////////////////////////////////////////////////////
char buffer_fecha[LONGITUD_BUFFER_DS3231];
char *puntero_fecha;
char buffer_fecha_formateada[LONGITUD_FECHA_FORMATEADA];
unsigned long cronometro;
//////////////////////////////////////////////////////////////////////////////////
float temperatura;
bool subir,bajar,ON;
bool ActualizaHora=false,ActualizaMinutos=false;
bool ActualizaLCD =LOW;
int ActualizacionLCD=9,escape=0;
int INTERRUPCION1=0;
byte var=0;
byte act=0;
String Dia;
// addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(I2C_ADDR, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
DS3231 reloj;
void DiaSemanal(void);
void MENU_PULSADO(void);
void REFRESCO(void);
void setup()
{
Serial.begin(9600);
lcd.begin (16,2);
pinMode(MENU,INPUT);
pinMode(ENTER,INPUT);
pinMode(SUBE,INPUT);
pinMode(BAJA,INPUT);
attachInterrupt( 0,RELOJ,CHANGE);
/*
//Se establece el modo horario en 12 horas (false = 24h)
Clock.setClockMode(true);
//Se establece el año
Clock.setYear((byte)(16));
//Mes
Clock.setMonth((byte)03);
//Dia de la semana (no lo estoy considerando)
//Clock.setDoW((byte)dia);
//Día
Clock.setDate((byte)22);
//Hora
Clock.setHour((byte)11);
//Minutos
Clock.setMINUTO((byte)07);
//Segundos
Clock.setSecond((byte)0);
*/
// inicializar lcd
// Activamos la retroiluminacion
lcd.setBacklight(HIGH);
lcd.clear();
Wire.begin();
Wire.beginTransmission(104);
//select control register
Wire.write(0x0e);
//set square wave @ 1 Hz (setup square wavew at choice of 0=1Hz/8=1024Hz/16=4096Hz/24=8192Hz)
// code shows 1 Hz selection ;
Wire.write(0); // <======(code shows 1 Hz selection ; )(change value to "8" for 1khz)
Wire.endTransmission();
// Clock.setClockMode(false);
puntero_fecha=reloj.cargar_fecha_hora();
delay(100);
///////////////////////////ACTUALIZAMOS EL LCD CON LA FECHA Y HORA
lcd.setCursor(0,0);
lcd.print(HORA);
lcd.print(":");
lcd.print(MINUTO);
lcd.print(" ");
lcd.print(DIA);
lcd.print("/");
lcd.print(MES);
lcd.print("/20");
lcd.print(ANO);
lcd.print(" ");
delayMicroseconds(100000);
}
void loop()
{
if (digitalRead(MENU)==HIGH) {
delay(200);
while(digitalRead(MENU)==HIGH){
}
MENU_PULSADO();
}
//PROCEDEMOS A PROGRAMAR LA HORA
while(ActualizaHora==true){
puntero_fecha=reloj.cargar_fecha_hora();
lcd.setCursor(0,0);
if(HORA<10) lcd.print("0");
lcd.print(HORA);
lcd.print(":");
if(MINUTO100){
escape=0;
break;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
if(act==2 && var==1){
escape=0;
REFRESCO();
lcd.setCursor(0,2);
lcd.print(«Set Minutos «);
delay(1000);
var = var+1;
while(1){
if(digitalRead(SUBE) == HIGH) {
delay(500);
escape=0;
REFRESCO();
}
if(digitalRead(BAJA) == HIGH) {
delay(500);
escape=0;
REFRESCO();
}
if (digitalRead(MENU)==HIGH) {
delay(200);
while(digitalRead(MENU)==HIGH){
}
MENU_PULSADO();
break;
}
delay(100);
escape++;
if(escape>100){
escape=0;
break;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
if(act==3 && var==2){
escape=0;
REFRESCO();
lcd.setCursor(0,2);
lcd.print(«Set Dia «);
delay(500);
var = var+1;
while(1){
if(digitalRead(SUBE) == HIGH) {
delay(500);
escape=0;
REFRESCO();
}
if(digitalRead(BAJA) == HIGH) {
delay(500);
escape=0;
REFRESCO();
}
if (digitalRead(MENU)==HIGH) {
delay(200);
while(digitalRead(MENU)==HIGH){
}
MENU_PULSADO();
break;
}
delay(100);
escape++;
if(escape>100){
escape=0;
break;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
if(act==4 && var==3){
REFRESCO();
escape=0;
lcd.setCursor(0,2);
lcd.print(«Set Mes «);
delay(1000);
var = var+1;
while(1){
if(digitalRead(SUBE) == HIGH) {
delay(500);
escape=0;
REFRESCO();
}
if(digitalRead(BAJA) == HIGH) {
delay(500);
escape=0;
REFRESCO();
}
if (digitalRead(MENU)==HIGH) {
delay(200);
while(digitalRead(MENU)==HIGH){
}
MENU_PULSADO();
break;
}
delay(100);
escape++;
if(escape>100){
escape=0;
break;
}
}
}
if(act==5 && var==4){
escape=0;
REFRESCO();
lcd.setCursor(0,2);
lcd.print(«Set Año «);
delay(1000);
var = var+1;
while(1){
if(digitalRead(SUBE) == HIGH) {
delay(500);
escape=0;
REFRESCO();
}
if(digitalRead(BAJA) == HIGH) {
delay(500);
escape=0;
lcd.setCursor(0,0);
lcd.print(HORA);
lcd.print(«:»);
lcd.print(MINUTO);
lcd.print(» «);
lcd.print(DIA);
lcd.print(«/»);
lcd.print(MES);
lcd.print(«/20»);
if(ANO100){
escape=0;
break;
}
}
}
if(act==6 && var==5){
escape=0;
lcd.clear();
lcd.setCursor(0,0);
DiaSemanal();
lcd.print(SEMANA);
lcd.setCursor(0,1);
lcd.print(«Set Dia semanal «);
delay(1000);
var = var+1;
delay(100);
while(1){
if(digitalRead(SUBE) == HIGH) {
delay(1000);
escape=0;
lcd.setCursor(0,0);
DiaSemanal();
lcd.print(SEMANA);
lcd.print(» «);
delay(100);
}
if(digitalRead(BAJA) == HIGH) {
delay(1000);
escape=0;
lcd.setCursor(0,0);
DiaSemanal();
lcd.print(SEMANA);
lcd.print(» «);
delay(100);
}
if (digitalRead(MENU)==HIGH) {
delay(200);
while(digitalRead(MENU)==HIGH){
}
escape=0;
MENU_PULSADO();
break;
}
delay(100);
escape++;
if(escape>100){
escape=0;
break;
}
}
}
act=0;
var=0;
delay(1000);
ActualizaHora=LOW;
delay(1000);
attachInterrupt( 0,RELOJ,CHANGE);
////////////////////////////////////////////////////////
lcd.clear();
lcd.setCursor(0,0);
if(HORA<10) lcd.print("0");
lcd.print(HORA);
lcd.print(":");
if(MINUTO3){
ActualizaLCD=HIGH;
ActualizacionLCD=0;
}
}
void MENU_PULSADO(){
INTERRUPCION1=1;
detachInterrupt(0);
delayMicroseconds(1000);
ActualizaHora=true;
act=act+1;
}
void REFRESCO(){
puntero_fecha=reloj.cargar_fecha_hora();
lcd.setCursor(0,0);
//
if(HORA<10) lcd.print("0");
lcd.print(HORA);
lcd.print(":");
lcd.print(MINUTO);
lcd.print(" ");
lcd.print(DIA);
lcd.print("/");
lcd.print(MES);
lcd.print("/20");
lcd.print(ANO);
lcd.print(" ");
delay(100);
}
salvador
no se que es lo que tengo mal
salvador
DISCULPA LO HE COMPILADO PARA EL ARDUINO UNO EN VEZ DE PARA EL MEGA Y SI FUNCIONA
salvador
joder con el tio pepe
le he puesto formato pero el reloj no funciona siempre muestra lo mismo pero si que actua y me puedo comunicar
Alfonso de Tavernes
No sé quue mas decir de lo que ya se ha dicho, pero por mi parte MUCHÍSIMAS GRACIAS,por este supertrabajo que compartes con nosotros sin pedir nada a cambio.
Todavía, no lo he probado, perogracias por adelantado y en cuanto lo pruebe te comento.
Víctor Ventura
Gracias a ti por visitar el blog 🙂
Alfonso de Tavernes
Hola Victor:
He probado y no consigo que me funcione bien.
Primero no me saca nada por el puerto serie, pero el puerto funciona que lo he probado.
Comentando este trozo de código, ya me imprime en el puerto serie, pero esto es lo que me sale:
Contenido de la posicion 0 del buffer de la fecha -> -91
Contenido de la posicion 1 del buffer de la fecha -> -91
Contenido de la posicion 2 del buffer de la fecha -> 45
Contenido de la posicion 3 del buffer de la fecha -> 7
Contenido de la posicion 4 del buffer de la fecha -> 45
Contenido de la posicion 5 del buffer de la fecha -> 25
Contenido de la posicion 6 del buffer de la fecha -> -91
El dia 45/25/20-91, domingo, a las 45:-91:-91
(4409 en un reloj de 4 digitos y 20-91-25-45 45:-91:-91 segun MySQL o -91254545-91-91 abreviadamente)
la temperatura era de -127.75 grados centigrados
H probado con dos ordenadores distintos, con dos arduinos distintos y con dos DS3231 y siempre me hace lo mismo.
Si me puedes orientar, te lo agradezco.
Víctor Ventura
Hola, Alfonso.
La salida que me muestras tiene pinta de no tener un valor correcto en el DS3231, no está en hora o no se ha leído correctamente. Pueden ser muchas cosas, la más típica es un bus I2C mal configurado o mal conectado. Pero me haría falta más información para poder orientarte.
¿Qué parte del código has comentado? ¿Por qué la has comentado, es que daba algún error? De ser así ¿Qué error mostraba?
Alfonso de Tavernes
Ante todo gracias y perdón por la tardanza, el trabajo no me deja mas tiempo.
El código comentado es este
y lo comenté porque no me sacaba nada por el puerto serie.
Víctor Ventura
Hola, Alfonso.
Empezando por el final: no te salía nada por el puerto serie porque la temperatura es incorrecta. Como el DS3231 necesita unos segundos para estabilizarse y solamente después da lecturas correctas, el ejemplo verifica que la temperatura esté entre los márgenes correctos para verificar que sea correcta. Como las lecturas que estás obteniendo no son correctas, no las mostraba (ni la temperatura ni la fecha y la hora).
Supongo que, por simplificar, no has incluido las líneas 58 y 59, que también deben estar comentadas o no compila. Lo incluyo corregido por si sirve de ayuda a alguien que nos lea, aunque no aconsejo que se utilice este código para nada que no sea experimentar.
Por la salida que mostraba tu comentario anterior y por lo que ahora explicas de las líneas comentadas, tengo claro que el problema es el DS3231; puede que no esté en hora, pero lo que es casi seguro es que la comunicación I2C no está funcionando. Puede ser hardware (lo más probable) ya sea porque el módulo está averiado, ya sea porque está mal conectado (cables confundidos). Puede ser software (mucho más raro) porque la librería no sea la correcta (versión, placa usada…)
Espero que esto te ayude un poco. Gracias por participar en polaridad.es
Alfonso de Tavernes
Gracias a tí, seguiréprobando
Fernando
Muy bueno tu blog. Saludos desde Chile.
Por favor publica la libreria wire.h que no la he podido bajar.
Víctor Ventura
Hola, Fernando.
La librería Wire es parte de Arduino, no hay que descargarla por separado.
Gracias a ti por participar en polaridad.es ¡Vuelve pronto! 🙂
Hugo Nuñez Diaz
Estimado.
Agradezco tu valiosa ayuda para ir introduciéndose cada día más en el fascinante mundo de la programación de Arduino.
Tengo una consulta : Cuando realizo la compilación del primer programa, me da el siguiente mensaje de error;
C:\Users\EMPERA~1\AppData\Local\Temp\build1096300866751125727.tmp/core.a(main.cpp.o): In function
main':
setup’C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/main.cpp:40: undefined reference to
C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/main.cpp:43: undefined reference to `loop’
collect2: error: ld returned 1 exit status
Error de compilación
Me podrías indicar cual puede ser el problema.
Gracias de Antemano.
Saludos.
Víctor Ventura
Hola, Hugo.
El error que mandas es el típico de no estar compilando un programa de Arduino bien formado, no parece tener nada que ver con la librería para el DS3231.
¿Puede ser que estés intentando compilar la librería sin un programa de Arduino que la utilice?
Saludos.
Leovigildo
Interesante blog pero,…¡Qué tipografía tan rara e incómoda de leer!
Víctor Ventura
¡Hola!
Me alegro de que el blog te resulte interesante 🙂 y siento que no te guste la tipografía 🙁 porque es un diseño mío (Tipo de letra Sircuito)
Pero muchas gracias por visitar polaridad.es 😀 ¡Vuelve pronto!
RUDYARD BARCENA DIAZ
HOLA VICTOR TU TRABAJO ES TREMENDO, YA DESCARGUE LA LIBRERIA DEL DS3231
¿QUE TENGO QUE HACER PARA QUE CAMBIE EL HORARIO DE VERANO Y DE INVIERNO EN FORMA AUTOMATICA?
Jesus Corona
Saludos, este website esta excelente. Mi pregunta es: ¿cómo eliminar los decimales de la temperatura en el DS3231?, por el momento los considero innecesarios ya que los datos los estoy mostrando en una LCD 1602 TWi/I2C y dichos decimales me quitan espacio para mostrar unidad de temperatura. Gracias de antemano por la ayuda que puedas prestar.