convertir a texto una hora (SOLUCIONADO)

quiero enviar la hora recibida del ds3231 a la pantalla nextion en formato texto, he probado varias y esta fue la ultima, pero me sigue mandando cualquier cosa. a ver si alguien se da cuenta donde meto la pata.

#include <Nextion.h>
#include "Wire.h"
#include "RTClib.h"
SoftwareSerial HMISerial(2,3);

NexText hora = NexText(0, 7, "hora");

RTC_DS3231 rtc;
void setup() {
nexInit();
}

void loop() {
  DateTime now = rtc.now(); 
  float floathora = now.hour();
  char conversion[2];
  dtostrf(floathora,2,0,conversion);
  
        hora.setText(conversion);
      
        HMISerial.write(0xff);
        HMISerial.write(0xff);
        HMISerial.write(0xff);
}

Que tal de este modo?

void loop() {
  DateTime now = rtc.now();
  
  char conversion[2];
  sprintf(conversion, "%02d", now.hour());
  hora.setText(conversion);
     
  HMISerial.write(0xff);
  HMISerial.write(0xff);
  HMISerial.write(0xff);
}

Gracias surbyte, mañana lo pruebo, nunca tuve en cuenta sprintf(). :frowning:

sprintf es el que te permite siempre presentar cosas ordenadamente.

Si usas %d le da formato a las cosas del mismo modo que hace un Serial.print

Si usas %2d el número reserva dos espacios asi que cualquier cosa entre 0 y 99 será bien presentada. Ahi es donde debes tener claro los límites de tu variable.

Si usas %02d cuando presenta 1 solo digito o sea de 0 a 9, le agrega un 0 a la izquierda y eso resuelve el problema cuando comienzan los segundos.
9 será presentado como 09

Finalmente tienes la opción de incluir el signo por si presentas números positivos y/o negativos y deben mantenerse ordenados o mejor dicho encolumnados.

Esto es fantástico cuando se suma el uso de floats por ejemplo en los ESP8266/ESP32 donde puedes ampliar las cosas usando %f.
En Arduino las limitaciones de flash no lo permiten. Aunque hay quien lo ha hecho, yo nunca logré que funcionara. Sin embargo con otro compilador y sin usar IDE Arduino si se puede.

tu ejemplo me de vuelve lo mismo que las demas pruebas, para mi es el formato que la funcion now.hour() la devuelve. me puse a probar con el sensor bme280, y usando dtostrf(), va muy bien, debe se que la hora en el modulo es ej.1652354 alguna funcion la separa en horas, minutos, seg y recien ahi la muesta.

si yo me fijo en el monitor serial envia bien las 11, pero la nextion recibe 16, y si lo envio como texto igual

otra cosa, surbyte, el programa de nextion tiene la opcion de ver que se esta enviando, si la velocidad del del delay es 1000, veo siempre el 16, peri si lo pongo en 2000, veo las 11 pero va pasando 11 a 16 cada vez que se cumple el ciclo, lo mismo con millis()

¡Cuidado con esto!

  char conversion[2];

Un “vector de 2 caracteres” puede almacenar una cadena de hasta 1 carácter “útil” ya que se ha de reservar uno para indicar el final de la cadena con el carácter nulo (valor numérico cero) según el estándar de cadenas del lenguaje C.

Si quieres una cadena de dos caracteres has de definirla con un tamaño de 3:

  char conversion[3];

Por ejemplo, el siguiente fragmento de programa asignará valores a los primeros veintiún bytes apuntados por buffer. El vigésimo valor será el carácter ’4’ (valor numérico 52), mientras que el vigesimoprimero será el carácter nulo (valor numérico cero).

int hora = 2;
int minuto =34;
sprintf(buffer, "La hora actual %02d:%02d", hora, minuto);

Si se han reservado únicamente 20 bytes para alojar la cadena, el carácter finalizador de la cadena se guardará en una zona de memoria que “no le pertenece” alterando muy posiblemente el valor de otra variable. Esto podría afectar al comportamiento del programa y causar fallos difícilmente localizables. Puede que sea esto lo que te está pasando.

Así que si queremos una cadena de 20 caracteres útiles, hemos de “reservar” 21.

char buffer[21];

Aún así, recomiendo siempre para estos casos ser un poco más “generoso” y reservar algo más de memoria por si accidentalmente la cadena resulta ser un poco más grande de lo previsto. Tomemos como caso el ejemplo anterior en el que la variable minuto llegase a valer 100. Entonces la cadena sería

"La hora actual 02:100"

porque el %02 indica que se quiere que el número sea de al menos dos dígitos (añadiendo ceros por la izquierda si fuera necesario) pero no se “recorta” si tiene más de dos dígitos. Entonces para almacenar esta cadena se necesitan 22 bytes (los 21 “que vemos” más el carácter nulo que indica el final de la cadena en C/C++). Así que, si se han reservado solo 21, volvemos a tener el peligro de que se escriba un valor cero en una zona de memoria que no deba. Corrompiendo tal vez el valor de otra variable.

Pero tampoco nos pasemos a la hora de definir el tamaño de un buffer de estos, que no andamos sobrados de memoria.

Recuerden: el carácter

'A'

es un único byte. Minetras que la cadena

"A"

son dos bytes, el carácter

A

seguido de un carácter nulo.

Despues de escribir y probar, empezo a funcionar, sin necesidad de convertir a texto la hora, realize el void de esta manera, el cambio importante que hice fue lo que hago siempre usar en vez de millis() uso el rtc para los vood loop, siempre que este lleve un rtc.

void datosds3231(){
        DateTime now = rtc.now();
       int hora_actual = now.hour();
       int minu_actual = now.minute();
        if(now.minute()- inicio>=intervalo){
             hora.setValue(hora_actual);
             minu.setValue(minu_actual);
      }

       
        HMISerial.write(0xff);
        HMISerial.write(0xff);
        HMISerial.write(0xff);
        inicio = millis();
      }