lcgamboa / picsimlab

PICsimLab - Programmable IC Simulator Laboratory
GNU General Public License v2.0
442 stars 85 forks source link

PICGenios 4 digit 7 segment multiplexing uneven contrast #75

Closed eagl1 closed 1 year ago

eagl1 commented 1 year ago

Hi,

I'm trying to write the proper code to write data to the 4 digit 7 segment modules.

This is my code:

#define DIG_4H_321L     0b00100000
#define DIG_4L_321H     0b00011100
#define DIG_3H_421L     0b00010000
#define DIG_3L_421H     0b00101100
#define DIG_2H_431L     0b00001000
#define DIG_2L_431H     0b00110100
#define DIG_1H_432L     0b00000100
#define DIG_1L_432H     0b00111000
#define ALL_OFF         0b00000000
#define ALL_ON          0b00111100

const uint8_t numbers[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0xFF, 0x6F};

void seven_segment_display(uint16_t num){

  uint8_t ones, tens, hundreds, thousands;
  ones = num % 10;
  tens = (num / 10) % 10;
  hundreds = (num / 100) % 10;
  thousands = (num / 1000) % 10;

  PORTA = DIG_4H_321L;
  PORTD = numbers[ones];
  __delay_ms(40);
  PORTA = DIG_4L_321H;

  PORTA = DIG_3H_421L;
  PORTD = numbers[tens];
  __delay_ms(30);
  PORTA = DIG_3L_421H;

  PORTA = DIG_2H_431L;
  PORTD = numbers[hundreds];
  __delay_ms(20);
  PORTA = DIG_2L_431H;

  PORTA = DIG_1H_432L;
  PORTD = numbers[thousands];
  __delay_ms(10);
  PORTA = DIG_1L_432H;
}

I tried to set the delay time to a constant value between all the 4 stages, but there's flickering. So with modifications I concluded to this setup, there's no flickering but there are the first digit has good brightness and the last one is the least brightness.

image

Do you have a solution for this ?

Thank you,

lcgamboa commented 1 year ago

To avoid flickering the refresh rate must be greater than 30 fps. Soon the sum of delays must be smaller than 1/30 s (33.33 ms/4 = 8.33ms). If you set all delays to 5ms the code will work without flicker. If you use different delays for each display the brightness will be different between the displays.

eagl1 commented 1 year ago

OK, I did it but how to show a static number for example ? or count on specific timing ?

Because now it's too fast.

lcgamboa commented 1 year ago

You can try:

unsigned int time=0;
unsigned int count=0;

while(1){
  seven_segment_display(count);  // 20ms total delay ;
  time += 20; //increment 20 ms
  if( time >= 1000 ){  //each 1 second
     time=0;
     count++;
  }
}
eagl1 commented 1 year ago

Thank you so much :)

Problem solved.

bye