Hola a todos!.
Estoy con un proyecto entre manos y estaba jugando un poco y me he encontrado con un error en la función sprintf.
Os pongo el ejemplo de fallo.
/*
* EJEMPLO DE FALLO DE SPRINTF.
* El reloj simulado se vuelve loco y se acelera.
*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(13,12,5,4,3,2);
struct DATETIME {
uint8_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
};
uint32_t t;
char line[16]; // En esta línea se pinta la información.
DATETIME now = { 24, 10, 17, 16, 41, 0 };
void setup() {
lcd.begin(20,4);
}
void loop() {
// Simulo un reloj, tan solo actualizo los segundos, minutos y horas.
if ( millis()-t >= 1000 ) {
now.second++;
if( now.second>59 ) {
now.second=0;
now.minute++;
if ( now.minute>59 ) {
now.minute=0;
now.hour++;
if ( now.hour>23 ) {
now.hour=0;
}
}
}
t = millis();
}
// Muestro la fecha formateada. Funciona, pero vuelve loco al reloj.
sprintf(line, "%02d/%02d/%02d %02d:%02d:%02d", now.day, now.month, now.year, now.hour, now.minute, now.second);
lcd.setCursor(0,0); lcd.print(line);
}
Básicamente es un reloj que muestra la fecha formateada (DD/MM/YY hh:mm:ss) en la pantalla del LCD, y el formateo se hace correctamente pero el reloj se acelera solo!!
Creo que no le gusta mucho que la variable line sea global y que si llamas a dicha función en el loop "machaca" la variable que le pases. ¿Por qué? Porque al introducir
el código en una función y eliminar la variable global line deja de dar problemas:
/*
* EJEMPLO DE SPRINTF CORREGIDO
*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(13,12,5,4,3,2);
struct DATETIME {
uint8_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
};
uint32_t t;
DATETIME now = { 24, 10, 17, 16, 41, 0 };
void muestraFecha() {
// Muestro la fecha formateada. Funciona, pero vuelve loco al reloj.
char line[16];
sprintf(line, "%02d/%02d/%02d %02d:%02d:%02d", now.day, now.month, now.year, now.hour, now.minute, now.second);
lcd.setCursor(0,0); lcd.print(line);
}
void setup() {
lcd.begin(20,4);
}
void loop() {
// Simulo un reloj, tan solo actualizo los segundos, minutos y horas.
if ( millis()-t >= 1000 ) {
now.second++;
if( now.second>59 ) {
now.second=0;
now.minute++;
if ( now.minute>59 ) {
now.minute=0;
now.hour++;
if ( now.hour>23 ) {
now.hour=0;
}
}
}
t = millis();
muestraFecha();
}
}
Eso unido al problema de que no trabaja bien con float me lleva a recomendaros que si podéis evitar usar esta función, mejor que mejor, ya que puede provocar problemas e incluso colgar el Arduino.
La verdad es que es una pena, porque para formatear cadenas es muy potente y cómoda.