SOLUCIONADO..NOVATO con Reloj LCD números grandes

Hola Chicos/as.

Con el fin de seguir aprendiendo, he empezado hace unos días a hacerme un reloj con LCD 20x4 I2c con números grandes.
He encontrado muchos tutoriales y códigos pero ninguno que me funcione.
Cunado esté terminado, la idea es añadirle algún sonido tipo cuco cada 15 minutos y algo con un servo....Está por definir.
Los tutoriales que he encontrado no me sirven ya que utilizan otro LCD u otro modulo reloj. O, lo hacen con números grandes de 2 lineas y el mio es de 4.
Al final me he lanzado a escribir el código desde cero, pero me da la impresión que estoy matando una mosca con los ejércitos de tierra, mar y aire. por ello antes de seguir con el trabajo de chinos en el que me he metido, quizás alguien me sugiera algún atajo para ahorrar trabajo de escritura y copia y pega...
Lo estoy haciendo en base a la info del modulo reloj. Como cada dígito grande se compone de 4 de alto por 4 de ancho, cada uno tiene hasta 32 lineas. una para lcd.setCursor y otra para lcd.write....Esto multiplicado por 24 horas y por 60 minutos....Una burrada...seguro que hay algún atajo, pero a este novato se le escapa por donde buscar....

Utilizo:

  • Arduino NANO.
  • Modulo DS1302
  • LCD20X4 I2c

Primero lo hice funcionar mostrando sin problemas, día de la semana, día del mes, mes, año, hora, minutos y segundos. Tanto en serial como en el LCD.
Mi reloj definitivo solo necesita hora y minutos.

Luego, cree los números del 0 al 9 más los dos puntos.

Al final de este mensaje pongo el código.
Está sin terminar, claro, aunque ya muestra las horas 18 y 19 en grande....Y como referencia provisional, las horas y minutos en tamaño normal...Esto ultimo, lo eliminaré al acabar.

Aquí está el código, gracias de antemano.
Detectado un error en los comentarios... if (myRTC.hours == 21){ // si horas son 21, muestralo en grande. Son horas no minutos.

#include <virtuabotixRTC.h> //Libreria
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// CLK -> 6, DAT -> 7, RST -> 8 Para DS1302

virtuabotixRTC myRTC(6, 7, 8); 
LiquidCrystal_I2C lcd(0x27, 20, 4); 
//caracteres customizados para crear numeros grandes.
byte N[8] = { //Esquina superior izquierda
B00111,
  B01111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111
};
byte A[8] = { // Cuadro entero
B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111
};
byte Y[8] = { ///Esquina inferior izquierda
B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B01111,
  B00111
};
byte L[8] = { //Esquina superior derecha
B11100,
  B11110,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111
};
byte M[8] = { //Esquina inferior dereccha
B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11110,
  B11100
};
byte P[8] = { //Punto bajo
B00000,
  B00000,
  B00000,
  B00000,
  B11111,
  B11111,
  B11111,
  B11111
};
byte cara[8] = { //Punto alto
B11111,
  B11111,
  B11111,
  B11111,
  B00000,
  B00000,
  B00000,
  B00000
};
byte cuerpo[8] = {// punto fino
B00000,
  B00000,
  B00000,
  B00000,
  B00111,
  B00111,
  B00111,
  B00111
};





void setup() {
  Serial.begin(9600);//activa serial
  lcd.init();//inicia lcd
  lcd.backlight();//enciende retroiluminacion

  //creamos los nuevos caracteres
  lcd.createChar (0,N);//esq sup izq
  lcd.createChar (1,A);//full
  lcd.createChar (2,Y);//esqu inf izq
  lcd.createChar (3,L);//esq sup dere
  lcd.createChar (4,M);//esq inf dere
  lcd.createChar (5,P);//Punto bajo
  lcd.createChar (6,cara);//Punto alto
  lcd.createChar (7,cuerpo);//3 de abajo
   
  }

void loop() {
  
  myRTC.updateTime();// Esta función actualiza las variables para obtener resultados actuales

   lcd.clear(); //Here after clearing the LCD we take the time from the module and print it on the screen with usual LCD functions
   myRTC.updateTime();

  Serial.print(myRTC.hours);
  Serial.print(":");
  Serial.print(myRTC.minutes);
  Serial.print(":");
  Serial.println(myRTC.seconds);
  
 lcd.setCursor(15,1);
 lcd.print(myRTC.hours);
 lcd.print(":");
 lcd.print(myRTC.minutes);
 
  lcd.setCursor(9,1);
  lcd.write (byte (7));
  lcd.setCursor(9,2);
  lcd.write (byte (7));

  //// Empiezo con los if....Si las horas son XX, muestralo en caracters grandes...Trabajo de locos

  if (myRTC.hours == 18){  // si minutos son 18, muestralo en grande  
  
  lcd.setCursor(2,0);//Empieza el 1
  lcd.write (byte (1));
  lcd.setCursor(3,0);
  lcd.write (byte (3));
  lcd.setCursor(3,1);
  lcd.write (byte (1));
  lcd.setCursor(3,2);
  lcd.write (byte (1));
  lcd.setCursor(3,3);
  lcd.write (byte (1));
  lcd.setCursor(5, 0);///empieza el 8
  lcd.write (byte (0));
  lcd.setCursor(5,1);
  lcd.write (byte (2));
  lcd.setCursor(5,2);
  lcd.write (byte (0));
  lcd.setCursor(5,3);
  lcd.write (byte (2));
  lcd.setCursor(6,0);
  lcd.write (byte (1));
  lcd.setCursor(6,1);
  lcd.write (byte (5));
  lcd.setCursor(6,2);
  lcd.write (byte (6));
  lcd.setCursor(6,3);
  lcd.write (byte (1));
  lcd.setCursor(7,0);
  lcd.write (byte (1));
  lcd.setCursor(7,1);
  lcd.write (byte (5));
  lcd.setCursor(7,2);
  lcd.write (byte (6));
  lcd.setCursor(7,3);
  lcd.write (byte (1));
  lcd.setCursor(8,0);
  lcd.write (byte (3));
  lcd.setCursor(8,1);
  lcd.write (byte (4));
  lcd.setCursor(8,2);
  lcd.write (byte (3));
  lcd.setCursor(8,3);
  lcd.write (byte (4));
  }

  if (myRTC.hours == 19){  // si minutos son 19, muestralo en grande 
  lcd.setCursor(2,0);//empieza el 1
  lcd.write (byte (1));
  lcd.setCursor(3,0);
  lcd.write (byte (3));
  lcd.setCursor(3,1);
  lcd.write (byte (1));
  lcd.setCursor(3,2);
  lcd.write (byte (1));
  lcd.setCursor(3,3);
  lcd.write (byte (1));
  lcd.setCursor(5, 0);//empieza el 9
  lcd.write (byte (0));
  lcd.setCursor(5, 1);
  lcd.write (byte (1));
  lcd.setCursor(5, 2);
  lcd.write (byte (6));
  lcd.setCursor(5,3);
  lcd.write (byte (2));
  lcd.setCursor(6,0);
  lcd.write (byte (1));
  lcd.setCursor(6,1);
  lcd.write (byte (5));
  lcd.setCursor(6, 2);
  lcd.write (byte (6));
  lcd.setCursor(6,3);
  lcd.write (byte (1));
  lcd.setCursor(7,0);
  lcd.write (byte (1));
  lcd.setCursor(7,1);
  lcd.write (byte (5));
  lcd.setCursor(7, 2);
  lcd.write (byte (6));
  lcd.setCursor(7, 3);
  lcd.write (byte (1));
  lcd.setCursor(8,0);
  lcd.write (byte (3));
  lcd.setCursor(8,1);
  lcd.write (byte (1));
  lcd.setCursor(8, 2);
  lcd.write (byte (1));
  lcd.setCursor(8,3);
  lcd.write (byte (4));
  }
  

  
















 
 delay(1000);


  
}

Gracias y saludos

Sobre las imagenes: Eso es un enlace y por lo tanto no va a funciona correctamente. Puedes pasarte por las NORMAS donde Surbyte muestra como hacerlo con los attachments del foro.

También puedes hacerlo metiendote en el enlace y al hacer click con el botón derecho sobre la imagen seleccionar "copiar la url de la imagen". Así si saldrán:


No sé con que librerias has trabajado, pero no creo que haga falta. Lo que tienes que hacerte es una función de dibujado para cada caracter y luego usarla. También veo que dibujas los dos puntos ":", a esa otra función.

// Le pasamos el digito que queremos mostrar
// y la posición X (columna) en la que empezaremos a 
// dibujar.
void printDigit(int digit, int posx ) {
	switch ( digit ) {
		case 0: // Dibujas el cero.
			break;
	    case 1:
			break;
		case 2:
			break;
		case 3:
			break;
		case 4:
			break;
		case 5:
			break;
		case 6:
			break;
		case 7:
			break;
		case 8:
			break;
		case 9:
			break;
		default:
			break;
	}
}

// Función de dibujado de los dos puntos.
void print2Dot(int posx) {
	// Lo dibujas.
}

Una vez que tengas esta función lo que tienes que hacer es dibujar cada digito del número.

Gracias pero perdona mi ignorancia...Soy todavía demasiado novato para entenderte.
No obstante me quedo con esta linea de tu codigo para buscar informacion...

void printDigit(int digit, int posx ) {
	switch ( digit ) {

Gracias

Es fácil entenderlo. ¿Cómo haces para pintar, por ejemplo un "0" en una posición?

Hola

Como antes he creado una serie de caracteres, le digo que si las horas en el modulo reloj, son por ejemplo 00, entonces en tales posiciones, lcd.write cada uno de los Char para formar un cero...Así:

lcd.setCursor(5, 0);
  lcd.write (byte (0));
  lcd.setCursor(5,1);
  lcd.write (byte (1));
  lcd.setCursor(5,2);
  lcd.write (byte (1));
  lcd.setCursor(5,3);
  lcd.write (byte (2));

  lcd.setCursor(6,0);
  lcd.write (byte (1));
  lcd.setCursor(6,3);
  lcd.write (byte (1));

  lcd.setCursor(7,0);
  lcd.write (byte (1));
  lcd.setCursor(7,3);
  lcd.write (byte (1));

  lcd.setCursor(8,0);
  lcd.write (byte (3));
  lcd.setCursor(8,1);
  lcd.write (byte (1));
  lcd.setCursor(8,2);
  lcd.write (byte (1));
  lcd.setCursor(8,3);
  lcd.write (byte (4));

Precisamente, me gustaría crear una especie de bloque, que incluya estas lineas del 0, para poderle decir lcd.write(el bloque que corresponda al 0) en el sitio estipulado...

Esos bytes 0,1,2,3,4,,5,6,7 son los nombres asignados que conforman cada numero grande:

//caracteres customizados para crear numeros grandes.
byte N[8] = { //Esquina superior izquierda
B00111,B01111,B11111,B11111,B11111,B11111,B11111,B11111};
byte A[8] = { // Cuadro entero
B11111,B11111,B11111,B11111,B11111,B11111,B11111,B11111};
byte Y[8] = { ///Esquina inferior izquierda
B11111,B11111,B11111,B11111,B11111,B11111,B01111,B00111};
byte L[8] = { //Esquina superior derecha
B11100,B11110,B11111,B11111,B11111,B11111,B11111,B11111};
byte M[8] = { //Esquina inferior dereccha
B11111,B11111,B11111,B11111,B11111,B11111,B11110,B11100};
byte P[8] = { //Punto bajo
B00000,B00000,B00000,B00000,B11111,B11111,B11111,B11111};
byte cara[8] = { //Punto alto
B11111,B11111,B11111,B11111,B00000,B00000,B00000,B00000};
byte cuerpo[8] = {// punto fino
B00000,B00000,B00000,B00000,B00111,B00111,B00111,B00111};

En tu código:

  // Primero columna.
  lcd.setCursor(5, 0);
  lcd.write (byte (0));
  lcd.setCursor(5,1);
  lcd.write (byte (1));
  lcd.setCursor(5,2);
  lcd.write (byte (1));
  lcd.setCursor(5,3);
  lcd.write (byte (2));
  // Segunda columna.
  lcd.setCursor(6,0);
  lcd.write (byte (1));
  lcd.setCursor(6,3);
  lcd.write (byte (1));
  // Tercera columna.
  lcd.setCursor(7,0);
  lcd.write (byte (1));
  lcd.setCursor(7,3);
  lcd.write (byte (1));
  // Cuarta columna.
  lcd.setCursor(8,0);
  lcd.write (byte (3));
  lcd.setCursor(8,1);
  lcd.write (byte (1));
  lcd.setCursor(8,2);
  lcd.write (byte (1));
  lcd.setCursor(8,3);
  lcd.write (byte (4));

¿No notas algo? La posición de la columna es la 5, la siguiente 5+1, la siguiente 5+2 y la ultima 5+3...

Podrías hacer entonces una función que le pases como parametro la posición x:

void pintaCero(int x) {
  lcd.setCursor(x, 0);
  lcd.write (byte (0));
  lcd.setCursor(x,1);
  lcd.write (byte (1));
  lcd.setCursor(x,2);
  lcd.write (byte (1));
  lcd.setCursor(x,3);
  lcd.write (byte (2));

  lcd.setCursor(x+1,0);
  lcd.write (byte (1));
  lcd.setCursor(x+1,3);
  lcd.write (byte (1));

  lcd.setCursor(x+2,0);
  lcd.write (byte (1));
  lcd.setCursor(x+2,3);
  lcd.write (byte (1));

  lcd.setCursor(x+3,0);
  lcd.write (byte (3));
  lcd.setCursor(x+3,1);
  lcd.write (byte (1));
  lcd.setCursor(x+3,2);
  lcd.write (byte (1));
  lcd.setCursor(x+3,3);
  lcd.write (byte (4));
}

Con lo cual, cada vez que llames a la función pintaCero(x) pintará el cero desde la columna que le digas.

En la función printDigit que te puse se puede hacer:

void printDigit(int digit, int posx) {
  switch ( digit ) {
    case 0: pintaCero(posx); break;
    case 1: break;
    case 2: break;
    case 3: break;
    case 4: break;
    case 5: break;
    case 6: break;
    case 7: break;
    case 8: break;
    case 9: break;
    default: break;
  }
}

Y ya tienes el cero listo, solo te faltaria hacer una función del 1 al 9.

Que no te asuste el switch, es una forma de evitar muchos if en algo que es númerico. Léelo como: "según el digito, en el caso de que valga 0, hago esto, en el caso de 1 esto otro, etc".

Ahora, cada vez que llames a printDigit(digito, posicion) pintará el digito en la posición que le digas.

Inténtalo y nos cuentas.

Gracias....
Bufff, tengo varios sentimientos encontrados en mi cuerpo a la vez: Agradecimiento, voluntad, vergüenza y cabreo....

Insisto que soy novato...Quizás me haya saltado alguna lección...

Esto lo entiendo: Ahora, cada vez que llames a printDigit(digito, posicion) pintará el dígito en la posición que le digas.
Solo tendría que decirle el dígito que quiero y en que columna empieza...Como si fueran caracteres normales.

Y que si noto algo ??? Claro, de los 4 dígitos de mi reloj, el primero siempre ocupa las columnas 0-1-2-3, el segundo 5-6-7-8, luego los puntos y el tercero 11-12-13-14 y quinto 16-17-18-19. Eso no cambia...
Claro que me gustaría decirle: Colo ca un 2 en la columna 11...

Lo que no entiendo es como darle un nombre, al paquete de caracteres que compone un numero grande...

Okok...vuelvo a leerlo y vale...Te refieres a que lo que automatizo es la posición de todo el bloque que compone un numero....Yo le diría el numero y x sería la columna donde empieza ese numero....
A ver voy a probar....

Mil gracias de nuevo...Con 52 años y una año con arduino, las cosas no me entran como antes...

Tranquilo, soy informático (malo) y aun me falta mucho que aprender.

Okok...vuelvo a leerlo y vale...Te refieres a que lo que automatizo es la posición de todo el bloque que compone un numero....Yo le diría el numero y x sería la columna donde empieza ese numero....
A ver voy a probar....

Exacto! Ese es el objetivo. Y lo mismo que hemos hecho con pintaCero debemos hacer con pintaUno, pintaDos, pinta3, ..., pinta9, para poder pintar cualquier digito decimal.

Luego nos pelearemos con mostrar números de más de un digito.

Nada....Quitando todas las lineas relacionadas con mostrar los numeros grandes de mi codigo, he colocado tu primer trozo de codigo antes de void.setup. Tu segundo trozo de codigo tambien a continuación.
Pantalla en blanco (azul) con solo los puntos que he mantenido...

Pregunta...A tus dos trozos de codigo les tengo que añadir algo para que muestre un 0 ???
No veo de donde coge los datos referentes a crear un numero 0 grande...
En mi codigo está creado el 0, pero tus codigos como los coge ???

Tu código mp hay que tocarlo para casi nada:

#include <virtuabotixRTC.h> //Libreria
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// CLK -> 6, DAT -> 7, RST -> 8 Para DS1302

virtuabotixRTC myRTC(6, 7, 8);
LiquidCrystal_I2C lcd(0x27, 20, 4);
//caracteres customizados para crear numeros grandes.
byte N[8] = { //Esquina superior izquierda
B00111,
  B01111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111
};
byte A[8] = { // Cuadro entero
B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111
};
byte Y[8] = { ///Esquina inferior izquierda
B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B01111,
  B00111
};
byte L[8] = { //Esquina superior derecha
B11100,
  B11110,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111
};
byte M[8] = { //Esquina inferior dereccha
B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11110,
  B11100
};
byte P[8] = { //Punto bajo
B00000,
  B00000,
  B00000,
  B00000,
  B11111,
  B11111,
  B11111,
  B11111
};
byte cara[8] = { //Punto alto
B11111,
  B11111,
  B11111,
  B11111,
  B00000,
  B00000,
  B00000,
  B00000
};
byte cuerpo[8] = {// punto fino
B00000,
  B00000,
  B00000,
  B00000,
  B00111,
  B00111,
  B00111,
  B00111
};

void pintaCero(int x) {
  lcd.setCursor(x, 0);
  lcd.write (byte (0));
  lcd.setCursor(x,1);
  lcd.write (byte (1));
  lcd.setCursor(x,2);
  lcd.write (byte (1));
  lcd.setCursor(x,3);
  lcd.write (byte (2));

  lcd.setCursor(x+1,0);
  lcd.write (byte (1));
  lcd.setCursor(x+1,3);
  lcd.write (byte (1));

  lcd.setCursor(x+2,0);
  lcd.write (byte (1));
  lcd.setCursor(x+2,3);
  lcd.write (byte (1));

  lcd.setCursor(x+3,0);
  lcd.write (byte (3));
  lcd.setCursor(x+3,1);
  lcd.write (byte (1));
  lcd.setCursor(x+3,2);
  lcd.write (byte (1));
  lcd.setCursor(x+3,3);
  lcd.write (byte (4));
}

void printDigit(int digit, int posx) {
  switch ( digit ) {
    case 0: pintaCero(posx); break;
    case 1: break;
    case 2: break;
    case 3: break;
    case 4: break;
    case 5: break;
    case 6: break;
    case 7: break;
    case 8: break;
    case 9: break;
    default: break;
  }
}


void setup() {
  Serial.begin(9600);//activa serial
  lcd.init();//inicia lcd
  lcd.backlight();//enciende retroiluminacion

  //creamos los nuevos caracteres
  lcd.createChar (0,N);//esq sup izq
  lcd.createChar (1,A);//full
  lcd.createChar (2,Y);//esqu inf izq
  lcd.createChar (3,L);//esq sup dere
  lcd.createChar (4,M);//esq inf dere
  lcd.createChar (5,P);//Punto bajo
  lcd.createChar (6,cara);//Punto alto
  lcd.createChar (7,cuerpo);//3 de abajo
  
  }

void loop() {
  myRTC.updateTime();// Esta función actualiza las variables para obtener resultados actuales
  lcd.clear(); //Here after clearing the LCD we take the time from the module and print it on the screen with usual LCD functions
  myRTC.updateTime();

  Serial.print(myRTC.hours);
  Serial.print(":");
  Serial.print(myRTC.minutes);
  Serial.print(":");
  Serial.println(myRTC.seconds);
  
  lcd.setCursor(15,1);
  lcd.print(myRTC.hours);
  lcd.print(":");
  lcd.print(myRTC.minutes);
 
  printDigit(0, 0);
  delay(1000);
}

Como ves solo he quitado el código donde mostrabas el 1 y el 8. Que no es lo que nos interesa de momento.

Tampoco he comprobado que pintaCero funcione correctamente, solo he modificado un poco el código que me pasaste. En vez de llamar a printDigit cambiala por pintaCero(0);

NOTA: No he compilado. No tengo instaladas la libreria RTC ni la del display I2C, y seguro me tira error.

Me he tomado un par de licencias y definido los caracteres un pelín diferentes a cómo tú los definiste. Si no te gustan puedes cambiarlos. Aquí te dejo una propuesta de cómo hacer lo que creo que quieres hacer.

No tengo el RTC, así que he hecho unas pruebas sin él y he puesto el código un poco “a ciegas”, así que no garantizo que funcione a la primera.

#include <virtuabotixRTC.h> //Libreria
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// CLK -> 6, DAT -> 7, RST -> 8 Para DS1302

virtuabotixRTC myRTC(6, 7, 8);
LiquidCrystal_I2C lcd(0x27, 20, 4);

// Caracteres customizados para crear numeros grandes.
uint8_t DEFINICION_CARACTERES[8][8] = {
  { //Esquina superior izquierda
    B00111,
    B01111,
    B11111,
    B00000,
    B11111,
    B11111,
    B11111,
    B11111
  },
  { // Cuadro entero
    B11111,
    B11111,
    B11111,
    B00000,
    B11111,
    B11111,
    B11111,
    B11111
  },
  { ///Esquina inferior izquierda
    B11111,
    B11111,
    B11111,
    B00000,
    B11111,
    B11111,
    B01111,
    B00111
  },
  { //Esquina superior derecha
    B11100,
    B11110,
    B11111,
    B00000,
    B11111,
    B11111,
    B11111,
    B11111
  },
  { //Esquina inferior dereccha
    B11111,
    B11111,
    B11111,
    B00000,
    B11111,
    B11111,
    B11110,
    B11100
  },
  { //Punto bajo
    B00000,
    B00000,
    B00000,
    B00000,
    B11111,
    B11111,
    B11111,
    B11111
  },
  { //Punto alto
    B11111,
    B11111,
    B11111,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000
  },
  {// punto fino
    B00000,
    B00000,
    B00000,
    B00000,
    B11100,
    B11100,
    B11100,
    B11100
  }
};

const char DEFINICION_NUMEROS[10][4][4] = {
  { // Definición del 0
    {  0,  1,  1,  3 },
    {  1, 32, 32,  1 },
    {  1, 32, 32,  1 },
    {  2,  1,  1,  4 }
  },
  { // Definición del 1
    {  0,  1,  1, 32 },
    { 32,  1,  1, 32 },
    { 32,  1,  1, 32 },
    {  2,  1,  1,  4 }
  },
  { // Definición del 2
    {  0,  1,  1,  3 },
    {  5,  5,  5,  1 },
    {  1,  6,  6,  6 },
    {  2,  1,  1,  4 }
  },
  { // Definición del 3
    {  0,  1,  1,  3 },
    { 32,  5,  5,  1 },
    { 32,  6,  6,  1 },
    {  2,  1,  1,  4 }
  },
  { // Definición del 4
    {  0, 32, 32,  3 },
    {  1,  5,  5,  1 },
    {  6,  6,  6,  1 },
    { 32, 32, 32,  4 }
  },
  { // Definición del 5
    {  0,  1,  1,  3 },
    {  1,  5,  5,  5 },
    {  6,  6,  6,  1 },
    {  2,  1,  1,  4 }
  },
  { // Definición del 6
    {  0,  1,  1,  3 },
    {  1,  5,  5,  5 },
    {  1,  6,  6,  1 },
    {  2,  1,  1,  4 }
  },
  { // Definición del 7
    {  0,  1,  1,  3 },
    { 32, 32, 32,  1 },
    { 32, 32, 32,  1 },
    { 32, 32, 32,  4 }
  },
  { // Definición del 8
    {  0,  1,  1,  3 },
    {  1,  5,  5,  1 },
    {  1,  6,  6,  1 },
    {  2,  1,  1,  4 }
  },
  { // Definición del 9
    {  0,  1,  1,  3 },
    {  1,  5,  5,  1 },
    {  6,  6,  6,  1 },
    {  2,  1,  1,  4 }
  },
};

// Función que muestra un dígito a partir de la columna indicada
void mostrarDigito(int digito, int columna) {
  for (int fila = 0; fila < 4; fila++) {
    lcd.setCursor(columna, fila);
    for (int caracter = 0; caracter < 4; caracter++) {
      lcd.print(DEFINICION_NUMEROS[digito][fila][caracter]);
    }
  }
}

void setup() {
  Serial.begin(9600);   // Activa serial
  lcd.init();           // Inicia lcd
  lcd.backlight();      // Enciende retroiluminacion
  lcd.clear();

  // Creamos los nuevos caracteres
  for (int i = 0; i < 8; i++) {
    lcd.createChar(i, DEFINICION_CARACTERES[i]);
  }
}

// Las variable las inicializamos a -1 para asegurarnos que al inicio "detecta un cambio" y "refresca" el valor mostrándolo
int anteriorHora = -1;                  // Para saber cuando cambia la hora y "refrescarla"
int anteriorMinuto = -1;                // Para saber cuando cambia el minuto y "refrescarlo"
int anteriorSegundo = -1;               // Para saber cuando cambia el segundo y saber cuándo se han de mostrar los dos puntos

unsigned long instanteAnterior = 0;     // Para controlar cuando han pasado 500 milisegundos desde que se mostraron los dos puntos
bool esperandoOcultarDosPuntos = false; // Para saber cuando se está esperando a ocultar los dos puntos

void loop() {
  myRTC.updateTime();   // Esta función actualiza las variables para obtener resultados actuales
  if (anteriorHora != myRTC.hours) {    // Si cambia el valor de la hora la muestra
    anteriorHora = myRTC.hours;
    mostrarDigito((myRTC.hours / 10) % 10, 0);
    mostrarDigito(myRTC.hours % 10, 5);
  }
  if (anteriorMinuto != myRTC.minutes) {  // Si cambia el valor de los minutos los muestra
    anteriorMinuto = myRTC.minutes;
    mostrarDigito((myRTC.minutes / 10) % 10, 11);
    mostrarDigito(myRTC.minutes % 10, 16);
  }
  if (anteriorSegundo != myRTC.seconds) { // Si cambia el valor de los segundos, muestra los dos puntos
    anteriorSegundo = myRTC.seconds;
    lcd.setCursor(10, 1);
    lcd.print((char)7);
    lcd.setCursor(10, 2);
    lcd.print((char)7);
    instanteAnterior = millis();          // Guardamos el instante actual para saber cuándo transcurren 500 milisegundos
    esperandoOcultarDosPuntos = true;     // Indicamos que se está esperando a ocultar los dos puntos
  }
  if ((esperandoOcultarDosPuntos == true) && ((millis() - instanteAnterior) >= 500)) {  // Si se está esperando ocultar los dos puntos y han pasado medio segundo
    esperandoOcultarDosPuntos = false;
    lcd.setCursor(10, 1);
    lcd.print(' ');
    lcd.setCursor(10, 2);
    lcd.print(' ');
  }
}

El programa se basa en guardar la definición de los números de 4x4 caracteres en el array DEFINICION_NUMEROS de tres dimensiones. Una dimensión para el dígito (de 0 a 9), otra para la fila (de 0 a 4) y otra para la columna (de 0 a 4) y guardar ahí el carácter que ha de ponerse en esa parte del dígito. El 32 es el valor ASCII correspondiente al espacio. Los valores del 0 al 7 corresponden a los caracteres definidos.

Hola IgnoranteAbsoluto...
Gracias ...luego miro tu codigo.

Victorjam, eliminando los [8], me salta el error:

scalar object 'N' requires one element in initializer

Ignorante Absoluto:

me da este error :

scalar object 'DEFINICION_CARACTERES' requires one element in initializer

¿En qué línea? A mi no me da ningún problema de compilación.

EUREKA...Victorjam....Apareció el 0....
Entendí mal, como tu has quita do de tu codigo lo de [8] en las lineas como esta:

byte N[8] = { //Esquina superior izquierda
B00111,B01111,B11111,B11111,B11111,B11111,B11111,B11111};

Pensé que te referías a ese 8....Lo he vuelto a poner como estaba y añadido la ultima linea printDigit(0, 0);

Ahora aparece el 0 en kas 4 primeras columnas....
Ahora a estudiar como colocar otros numeros grandes en otras posiciones...
Y como decirle a arduino, que cuando sean las 15:23 en el reloj RTC, que use los numeros grandes...

IGNORANTEABSOLUTO:::::: En la linea 11....En esta:

uint8_t DEFINICION_CARACTERES = {

Victorjam:

Entiendo que ahora tengo que crear void pintacero para cada otro numero, void pintauno etc etc

Me pondrías un ejemplo de pintauno y case 1: break; ???

abajo en printDigit(0, 0); entiendo que será printDigit(1, 5); O sea los datos para mostrar un 1 en la 5a columna... Es correcto ???

¿Tienes puesto?

uint8_t DEFINICION_CARACTERES = {

¿O tienes puesto?

uint8_t DEFINICION_CARACTERES[8][8] = {

Tienes razón, no copié bien la linea y me faltaban los [8][8].
Buahhhh, funciona 100%

Mil gracias....

Jolin, que situación...Victorjam, miles de gracias por tu paciencia y ayuda.

Ahora estudiaré el código de Ignorante Absoluto para adaptarlo a mis necesidades...
Y el de Victorjam, lo mismo,,, ahora que ya casi lo teníamos, tengo que tambien seguir por ese camino...
Gracias a los dos...Este foro no falla.
Mil gracias...

Solo como aporte mas allá de felicitarte por tus avances con Arduino, siempre busca alguna librería si es que quieres ahorrarte el trabajo pero muchas veces, lo dificil es dar con las palabras adecuadas en inglés.
En este caso es fácil. LCD Big numbers, asi que pones en google: Arduino LCD Big Numbers y sugen librerías como ésta:

"BigNumbers" - a new Arduino character LCD font

Pero continúa en lo que estas porque es mas ilustrativo y constructivo que ir y usar una librería.