[SOLUCIONADO]Sevseg hh:mm:ss 6 display error desde 3:27:59 [aparece un guion]

estoy creando un reloj multiplexado con 6 pantallas de cátodo común y 7 segmentos (no uso los leds de los puntos).

mi problema surge en el momento que van transcurridas 3 hrs 27min y 59 seg, al siguiente segundo el reloj deja de funcionar y aparece un guion y una cuenta cercana al valor en pantalla que empieza a decrecer. intente revisar la biblioteca sevseg.h por si encontraba alguna forma de evitar esto pero aun soy nuevo y no supe encontrar la solución.

les comento características del circuito después del código y adjunto foto con el problema en pantalla.

#include "SevSeg.h"




SevSeg sevseg;       //Instanciamos el object
//se genera un problema a partir del valor 32759
int hora=3;
int minuto=27;
int segundo=55;
unsigned long tiempo1=0;  
unsigned long tiempo2=0;
long actual=0;


void setup() 
{
   byte hardwareConfig = N_TRANSISTORS;  //Indica que es cátodo común con NPN
   byte numDigits = 6;
   byte digitPins[] = {8,9,10,11,12,13}; //transistores
   byte segmentPins[] = {1,2,3,4,5,6,7,0};
   bool resistorsOnSegments = true;     //true indica que resistencia esta en el pin de segmento
   bool updateWithDelays = false;       //Recomendado
   bool leadingZeros = true;            //true muestra ceros a izquierda
  
   sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
   sevseg.setBrightness(60);            //Establece brillo a 90%
}


void loop()
{
 
un_seg (); //void un seg

   
contador(); //void contador
actual= ((hora*10000)+(minuto*100)+(segundo));  
sevseg.setNumber(actual,6); //convierte los valores hora, minuto y segundo en un unico valor permitiendo su uso con set number
sevseg.refreshDisplay(); // Must run repeatedly; don't use blocking code (ex: delay()) in the loop() function or this won't work right
}


void un_seg()
{
tiempo2=(millis()/1000);    
if ( tiempo1 != tiempo2 ) {
 tiempo1=tiempo2;
 segundo++;      
 }     
}
 
void contador(){

//rutina segundos 
if ( segundo == 61 ) {
segundo =0;
segundo++;} 
 
if ( ( segundo == 60 ) ) {
segundo =0;
minuto++;} 
 
 
// Rutina para los minutos
 
if (minuto == 61 ) {
minuto =0;
minuto++; } 
 
if ( ( minuto == 60 ) ) {
minuto =0;     
hora++;} 

// Rutina para las horas
 
if ( hora == 25 ) {
hora =0;
hora++; } 
 
if ( (hora == 24) ) {
hora =0;
minuto =0;
segundo =0; 
 } 
}

-6 transistores npn controlados con los terminales 8,9,10,11,12,13, la corriente esta limitada con resistencias de 1k.

-los 7 pines a,b,c,d,e,f,g están limitados con resistencias de 300ohm, los pines usados son 1,2,3,4,5,6,7.

-el arduino utilizado es un wemos atmega 2560 con wifi incluido(el cual lo desactive) con 32mb de memoria

requisitos que me fije como meta:
-multiplexar.
-usar solo 6 pantallas de 7 segmentos
-ya que solo existen ejemplos de relojes hh:mm o mm:ss me plantee crear uno con los 3 datos.
-no requiero usar rtc, tan solo cargar a arduino con las variables hora minuto y segundo ya inicializadas.
-no necesito de exactitud temporal.

No hice grandes cambios pero quiero saber como se comporta este código

#include "SevSeg.h"

SevSeg sevseg;       //Instanciamos el object
//se genera un problema a partir del valor 32759
int hora              =  3;
int minuto            = 27;
int segundo           = 55;
unsigned long tiempo1 = 0;  
unsigned long tiempo2 = 0;
unsigned long actual  = 0;
byte hardwareConfig = N_TRANSISTORS;  //Indica que es cátodo común con NPN
byte numDigits      = 6;
byte digitPins[]    = {8,9,10,11,12,13}; //transistores
byte segmentPins[]  = {1,2,3,4,5,6,7,0};
bool resistorsOnSegments  = true;     //true indica que resistencia esta en el pin de segmento
bool updateWithDelays     = false;       //Recomendado
bool leadingZeros   = true;            //true muestra ceros a izquierda

void setup() { 
 
   sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
   sevseg.setBrightness(60);            //Establece brillo a 90%
}


void loop()
{
  contador(); //void contador
  actual= (unsigned long) hora*10000 + minuto*100+ segundo;  
  sevseg.setNumber(actual,6); //convierte los valores hora, minuto y segundo en un unico valor permitiendo su uso con set number
  sevseg.refreshDisplay(); // Must run repeatedly; don't use blocking code (ex: delay()) in the loop() function or this won't work right
}


void contador(){

  if (millis() - tiempo1 >= 1000 ) {
      segundo++;      
      //rutina segundos 
      if ((segundo >= 60 ) ) {
          segundo = 0;
          minuto++;
      } 
         
      // Rutina para los minutos
      if (( minuto >= 60 ) ) {
          minuto = 0;     
          hora++;
      } 

      // Rutina para las horas
      if (hora >= 24) {
          hora    = 0;
          minuto  = 0;
          segundo = 0; 
      }   
      tiempo1 = millis();
  }      
}

:slight_smile: Muchas gracias por tu ayuda, paso a comentar.
Cargue el codigo modificado en arduino, pero no logro avanzar del mismo numero :(. mantuvo el mismo comportamiento que tenia hasta ahora, puedo dar fe que logra avanzar esas 3hrs 30 min sin ningun bug, ya que le di valores 0 a las 3 variables de tiempo.

Otro medio que intente ocupar fue el uso de :

#define MAXIMUNDIGITS 8

Pero en ambos codigos no genero cambios.
Leyendo vi que de alguna forma es posible usar lineas de codigo asi

#include "SevSeg.h"
byte digitPins_1[] = {8,9,10,11};//Digits pins
byte digitPins_2[] = {12,13};
byte segmentPins[] = {1,2,3,4,5,6,7}; //segment pins
SevSeg disp1;
SevSeg disp2;

Quizas asi deben quedar esas líneas de codigo pero modificar el resto del codigo me resulto dificil, y siento que puede generar algun problema de multiplexado.
Quedo atento a sus comentarios :wink:

Prueba a poner una L mayúscula al 10000 y que la línea de código quede así:

actual= ((hora*10000L)+(minuto*100)+(segundo));

El motivo es que hora, minuto, segundo, 10000 y 100 son todos valores de tipo int. Con lo que el resultado de la operación es también de tipo int. Es decir: todos son enteros con signo de 16 bits y sus valores sólo pueden ir de -32768 a 32767. Un valor mayor que 32767 hace que se "desborde" y pase a contar a partir de -32768. Ese resultado "desbordado" es el que se asigna a la variable actual, pese a poder guardar valores mayores por ser de tipo long (entero con signo de 32 bits).

Si en lugar de multiplicar por 10000 multiplicamos por 10000L, esa L le indica al compilador que ese 10000 es de tipo long, con lo que el resultado de la multiplicación será de ese tipo y el resto de valores al sumarse se convertirán a long, aunque sean de tipo int.

Ahora sí que se almacenará en actual un valor mayor que 32767 y se ha de mostrar correctamente. El long puede tener valores entre el -2147483648 y el 2147483647.

:slight_smile: :slight_smile: :slight_smile: :slight_smile:
muchas gracias, funciono completamente tu solución, básicamente el problema era el tipo de variable y el como hacerle entender a la librería que era de tipo LONG.

a continuación pongo el código funcionando y espero a varias personas les sirva, ahora veré como hacer para ir sumando valores con botones físicos a las variables minuto y hora para poder cambiar la hora, comprobé que con analogread me genera una pausa en la multipexacion, así que veré si con un arduino nano pro como esclavo soluciono esto o simplemente uso algún puerto digital en el mega

#include "SevSeg.h"




SevSeg sevseg;       //Instanciamos el object
//se genera un problema a partir del valor 32759
int hora=13;
int minuto=57;
int segundo=30;
unsigned long tiempo1=0;  
unsigned long tiempo2=0;
long actual=0;


void setup() 
{
   byte hardwareConfig = N_TRANSISTORS;  //Indica que es cátodo común con NPN
   byte numDigits = 6;
   byte digitPins[] = {8,9,10,11,12,13}; //transistores
   byte segmentPins[] = {1,2,3,4,5,6,7,0};
   bool resistorsOnSegments = true;     //true indica que resistencia esta en el pin de segmento
   bool updateWithDelays = false;       //Recomendado
   bool leadingZeros = true;            //true muestra ceros a izquierda
  
   sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
   sevseg.setBrightness(60);            //Establece brillo a 90%
}


void loop()
{
 
un_seg (); //void un seg

   
contador(); //void contador
actual= ((hora*10000L)+(minuto*100)+(segundo)); 
sevseg.setNumber(actual,6); //convierte los valores hora, minuto y segundo en un unico valor permitiendo su uso con set number
sevseg.refreshDisplay(); // Must run repeatedly; don't use blocking code (ex: delay()) in the loop() function or this won't work right
}


void un_seg()
{
tiempo2=(millis()/1000);    
if ( tiempo1 != tiempo2 ) {
 tiempo1=tiempo2;
 segundo++;      
 }     
}
 
void contador(){

//rutina segundos 
if ( segundo == 61 ) {
segundo =0;
segundo++;} 
 
if ( ( segundo == 60 ) ) {
segundo =0;
minuto++;} 
 
 
// Rutina para los minutos
 
if (minuto == 61 ) {
minuto =0;
minuto++; } 
 
if ( ( minuto == 60 ) ) {
minuto =0;     
hora++;} 

// Rutina para las horas
 
if ( hora == 25 ) {
hora =0;
hora++; } 
 
if ( (hora == 24) ) {
hora =0;
minuto =0;
segundo =0; 
 } 
}