How to code a 16x16 led dot display clock efficiently

I want to efficiently code four 8x8 dot displays. I want each 8x8 to display a number. I have done it already, (see attachment:Juno_matrix_pro), but I was using the technique for coding a 7-segment display, which is not very efficient. That older code uses uint8_t dig[14][8] 14x8=112 bytes just for mapping the number 0-9. I want to know if there is a better way to program this clock. Any suggestion will be great. thank you in advance.

These is the new code for displaying the above image. This time I am using led[32]; 32 byte to control these led, but how do I get it to display numbers??

/*
Flyandance March 26 2017
DS1302 (RTC)
Rst= A5 D7 (D25)
I/0= A4 D6 (D24)
Sclk= A3 D5 (D23)

3 buttons >> G0, G1, G2 (26, 27, 36)

buzzer >> G3 (16)

4x 8x8 Ports A, B, C, E
common cathode Port F (Active LOW)

 */

//##########################################################
#include <DS1302.h>
DS1302 rtc(25, 24, 23);
Time t;

#include <button.h> 
button ba(26);  
button bb(27); 
button bc(36); 

//##########################################################

byte led[32]; //32x8=256
byte counter;
unsigned int t1,t2,t3,t4,t5,t6,t7,t8;

//##########################################################
void setup() {
DDRA=0xff;
DDRB=0xff;
DDRC=0xff;
DDRE=0xff;
DDRF=0xff; //Active Low

//for (byte x=0; x<32; x++) led[x]=0xff;

led[0]=0xff;
led[15]=0xff;
led[16]=0xff;
led[31]=0xff;

//PORTA=0xff;
//PORTB=0xff;
//PORTC=0xff;
//PORTE=0xff;
}


//##########################################################
void loop() {

  //ba.buttonWatchbot();
  //bb.buttonWatchbot();
  //bc.buttonWatchbot();    
 

//##########################################################

t1=micros();
if(t1-t2>=5){

  PORTF=0xff;   
  PORTA=led[0+counter];  
  PORTB=led[8+counter];  
  PORTC=led[16+counter];   
  PORTE=led[24+counter];
  PORTF=~(1<<0+counter);  
  
  counter++;
  if( counter==8 ) counter=0;
  t2=t1;  
  
  }
  
}



//##########################################################
//##########################################################

Juno_matrix_pro.ino (7.66 KB)

Each letter to display (if you want to go 7-segment number style) should only require one byte:

Eg. 7 could be:

uint8_t charset[<how many letters>]={
  /...
  0b1110000,//Top, top right, bottom right, bottom, bottom left, top left, center
  /...
}

So, 14 chars, 14 bytes.

Fuzzyzilla:
Each letter to display (if you want to go 7-segment number style) should only require one byte:

Eg. 7 could be:

uint8_t charset[<how many letters>]={

/...
 0b1110000,//Top, top right, bottom right, bottom, bottom left, top left, center
 /...
}




So, 14 chars, 14 bytes.

I see. so there is no way?

Code used 10x8 bytes=80 bytes mapping to display digits.

/*
Flyandance March 26 2017
DS1302 (RTC)
Rst= A5 D7 (D25)
I/0= A4 D6 (D24)
Sclk= A3 D5 (D23)

3 buttons >> G0, G1, G2 (26, 27, 36)

buzzer >> G3 (16)

4x 8x8 Ports A, B, C, E
common cathode Port F (Active LOW)

 */

//##########################################################
#include <DS1302.h>
DS1302 rtc(25, 24, 23);
Time t;

#include <button.h> 
button ba(26);  
button bb(27); 
button bc(36); 


uint8_t dig[10][8]={
{0x00,0x00,0x3c,0x42,0x42,0x3c,0x00,0x00}, //0
{0x00,0x00,0x44,0x42,0x7e,0x40,0x00,0x00}, //1
{0x00,0x00,0x64,0x52,0x4a,0x44,0x00,0x00}, //2
{0x00,0x00,0x42,0x4a,0x4a,0x34,0x00,0x00}, //3
{0x00,0x00,0x18,0x14,0x7e,0x10,0x00,0x00}, //4
{0x00,0x00,0x4e,0x4a,0x4a,0x30,0x00,0x00}, //5
{0x00,0x00,0x3c,0x4a,0x4a,0x30,0x00,0x00}, //6
{0x00,0x00,0x02,0x02,0x7a,0x06,0x00,0x00}, //7
{0x00,0x00,0x34,0x4a,0x4a,0x34,0x00,0x00}, //8
{0x00,0x00,0x0c,0x52,0x52,0x3c,0x00,0x00}, //9
};

//##########################################################

byte led[32]; //32x8=256
byte counter;
unsigned int t1,t2,t3,t4,t5,t6,t7,t8;

//##########################################################
void setup() {
DDRA=0xff;
DDRB=0xff;
DDRC=0xff;
DDRE=0xff;
DDRF=0xff; //Active Low

//for (byte x=0; x<32; x++) led[x]=0xff;

for (byte x=0; x<8; x++) {
  led[x]=dig[1][x];
  led[x+8]=dig[2][x];
  led[x+16]=dig[3][x];
  led[x+24]=dig[4][x];      
}



//led[0]=0xff;
//led[15]=0xff;
//led[16]=0xff;
//led[31]=0xff;

//PORTA=0xff;
//PORTB=0xff;
//PORTC=0xff;
//PORTE=0xff;
}


//##########################################################
void loop() {

  //ba.buttonWatchbot();
  //bb.buttonWatchbot();
  //bc.buttonWatchbot();    
 

//##########################################################

t1=micros();
if(t1-t2>=5){

  PORTF=0xff;   
  PORTA=led[0+counter];  
  PORTB=led[8+counter];  
  PORTC=led[16+counter];   
  PORTE=led[24+counter];
  PORTF=~(1<<0+counter);  
  
  counter++;
  if( counter==8 ) counter=0;
  t2=t1;  
  
  }
  
}



//##########################################################
//##########################################################
for (byte x=0; x<8; x++) {
  led[x]=dig[1][x];
  led[x+8]=dig[2][x];
  led[x+16]=dig[3][x];
  led[x+24]=dig[4][x];      
}

flyandance:
I see. so there is no way?

Code used 10x8 bytes=80 bytes mapping to display digits.

You could make it 40 bytes.

uint8_t dig[10][8]={

{0x00,0x00,0x3c,0x42,0x42,0x3c,0x00,0x00}, //0
{0x00,0x00,0x44,0x42,0x7e,0x40,0x00,0x00}, //1
{0x00,0x00,0x64,0x52,0x4a,0x44,0x00,0x00}, //2
{0x00,0x00,0x42,0x4a,0x4a,0x34,0x00,0x00}, //3
{0x00,0x00,0x18,0x14,0x7e,0x10,0x00,0x00}, //4
{0x00,0x00,0x4e,0x4a,0x4a,0x30,0x00,0x00}, //5
{0x00,0x00,0x3c,0x4a,0x4a,0x30,0x00,0x00}, //6
{0x00,0x00,0x02,0x02,0x7a,0x06,0x00,0x00}, //7
{0x00,0x00,0x34,0x4a,0x4a,0x34,0x00,0x00}, //8
{0x00,0x00,0x0c,0x52,0x52,0x3c,0x00,0x00}, //9
};

There are a lot of zeros in that array.
Try getting rid of the zeros, and using only four bytes (not eight) for each digit. See if that helps.

odometer:
You could make it 40 bytes.
There are a lot of zeros in that array.
Try getting rid of the zeros, and using only four bytes (not eight) for each digit. See if that helps.

works perfectly. never think of this simple thing. thank you for saving me 40 bytes of ram.

for (byte x=0; x<4; x++) {
  led[x+2]=dig[1][x];
  led[x+10]=dig[2][x];
  led[x+18]=dig[3][x];
  led[x+26]=dig[4][x];      
}
/*
Flyandance March 26 2017
DS1302 (RTC)
Rst= A5 D7 (D25)
I/0= A4 D6 (D24)
Sclk= A3 D5 (D23)

3 buttons >> G0, G1, G2 (26, 27, 36)

buzzer >> G3 (16)

4x 8x8 Ports A, B, C, E
common cathode Port F (Active LOW)

 */

//##########################################################
#include <DS1302.h>
DS1302 rtc(25, 24, 23);
Time t;

#include <button.h> 
button ba(26);  
button bb(27); 
button bc(36); 


uint8_t dig[10][8]={
{0x3c,0x42,0x42,0x3c}, //0
{0x44,0x42,0x7e,0x40}, //1
{0x64,0x52,0x4a,0x44}, //2
{0x42,0x4a,0x4a,0x34}, //3
{0x18,0x14,0x7e,0x10}, //4
{0x4e,0x4a,0x4a,0x30}, //5
{0x3c,0x4a,0x4a,0x30}, //6
{0x02,0x02,0x7a,0x06}, //7
{0x34,0x4a,0x4a,0x34}, //8
{0x0c,0x52,0x52,0x3c}, //9
};

//##########################################################

byte led[32]; //32x8=256
byte counter;
unsigned int t1,t2,t3,t4,t5,t6,t7,t8;

//##########################################################
void setup() {
DDRA=0xff;
DDRB=0xff;
DDRC=0xff;
DDRE=0xff;
DDRF=0xff; //Active Low

//for (byte x=0; x<32; x++) led[x]=0xff;

for (byte x=0; x<4; x++) {
  led[x+2]=dig[1][x];
  led[x+10]=dig[2][x];
  led[x+18]=dig[3][x];
  led[x+26]=dig[4][x];      
}



//led[0]=0xff;
//led[15]=0xff;
//led[16]=0xff;
//led[31]=0xff;

//PORTA=0xff;
//PORTB=0xff;
//PORTC=0xff;
//PORTE=0xff;
}


//##########################################################
void loop() {

  //ba.buttonWatchbot();
  //bb.buttonWatchbot();
  //bc.buttonWatchbot();    
 

//##########################################################

t1=micros();
if(t1-t2>=5){

  PORTF=0xff;   
  PORTA=led[0+counter];  
  PORTB=led[8+counter];  
  PORTC=led[16+counter];   
  PORTE=led[24+counter];
  PORTF=~(1<<0+counter);  
  
  counter++;
  if( counter==8 ) counter=0;
  t2=t1;  
  
  }
  
}



//##########################################################
//##########################################################

So, does a digital-style character not work?

My (pseudo)code would save significantly more space, just the characters would look different.

For the code I gave you.

Fuzzyzilla:
So, does a digital-style character not work?

My (pseudo)code would save significantly more space, just the characters would look different.

For the code I gave you.

I am not really sure how you encode/map a 3x5 into a byte, but with a 4x6 (4 bytes), I am able to squeeze 2 more digits into the 16x16 display and while saving 40 bytes. Maybe I can get up to 9 digits on the display with a 3x5, while saving 10 extra bytes with a 3x5 array(3 bytes), but the numbers don't look very look at that low resolution.

for (byte x=0; x<4; x++) {
  led[x+1]=dig[1][x];
  led[x+6]=dig[2][x];
  led[x+11]=dig[3][x];
  led[x+17]=dig[4][x];      
  led[x+22]=dig[5][x];
  led[x+27]=dig[6][x];    
}
/*
Flyandance March 26 2017
DS1302 (RTC)
Rst= A5 D7 (D25)
I/0= A4 D6 (D24)
Sclk= A3 D5 (D23)

3 buttons >> G0, G1, G2 (26, 27, 36)

buzzer >> G3 (16)

4x 8x8 Ports A, B, C, E
common cathode Port F (Active LOW)

 */

//##########################################################
#include <DS1302.h>
DS1302 rtc(25, 24, 23);
Time t;

#include <button.h> 
button ba(26);  
button bb(27); 
button bc(36); 


uint8_t dig[10][4]={
{0x3c,0x42,0x42,0x3c}, //0
{0x44,0x42,0x7e,0x40}, //1
{0x64,0x52,0x4a,0x44}, //2
{0x42,0x4a,0x4a,0x34}, //3
{0x18,0x14,0x7e,0x10}, //4
{0x4e,0x4a,0x4a,0x30}, //5
{0x3c,0x4a,0x4a,0x30}, //6
{0x02,0x02,0x7a,0x06}, //7
{0x34,0x4a,0x4a,0x34}, //8
{0x0c,0x52,0x52,0x3c}, //9
};

//##########################################################

byte led[32]; //32x8=256
byte counter;
unsigned int t1,t2,t3,t4,t5,t6,t7,t8;

//##########################################################
void setup() {
DDRA=0xff;
DDRB=0xff;
DDRC=0xff;
DDRE=0xff;
DDRF=0xff; //Active Low

//for (byte x=0; x<32; x++) led[x]=0xff;

for (byte x=0; x<4; x++) {
  led[x+1]=dig[1][x];
  led[x+6]=dig[2][x];
  led[x+11]=dig[3][x];
  led[x+17]=dig[4][x];      
  led[x+22]=dig[5][x];
  led[x+27]=dig[6][x];    
}



//led[0]=0xff;
//led[15]=0xff;
//led[16]=0xff;
//led[31]=0xff;

//PORTA=0xff;
//PORTB=0xff;
//PORTC=0xff;
//PORTE=0xff;
}


//##########################################################
void loop() {

  //ba.buttonWatchbot();
  //bb.buttonWatchbot();
  //bc.buttonWatchbot();    
 

//##########################################################

t1=micros();
if(t1-t2>=5){

  PORTF=0xff;   
  PORTA=led[0+counter];  
  PORTB=led[8+counter];  
  PORTC=led[16+counter];   
  PORTE=led[24+counter];
  PORTF=~(1<<0+counter);  
  
  counter++;
  if( counter==8 ) counter=0;
  t2=t1;  
  
  }
  
}



//##########################################################
//##########################################################

I posted in my first post how you could do it.

It is not a bitmap. It is an encoded... thingy?

If the "top" bit is true, draw the top segment.
If the "top left" bit is true, draw the top-left segment.

Fuzzyzilla:
I posted in my first post how you could do it.

It is not a bitmap. It is an encoded... thingy?

If the "top" bit is true, draw the top segment.
If the "top left" bit is true, draw the top-left segment.

Can you also help me out a little bit. How to decode your encoded thingy? I am not really sure how.

For my bitmap, this is all I need to print out the led number 1-6;

for (byte x=0; x<4; x++) {
  led[x]=dig[1][x];
  led[x+5]=dig[2][x];
  led[x+12]=dig[3][x];
  
  led[x+16]=dig[4][x];      
  led[x+21]=dig[5][x];
  led[x+28]=dig[6][x];    
}