[SOLVED] Multiplexing 2 digit 7-segment with 74LS47

Hello,

The code works ok but there are some problems.

  1. The increments just when units reach 9, so if it's 18 then next increment would be 29 instead of 19. Then it goes to 20.

  2. I want to turn off the display completely so it appears that there are no multiplexing going on.

This is my code:

#define DIGIT_1ON_2OFF 0x20
#define DIGIT_2ON_1OFF 0x10

unsigned long refresh_display_start;
unsigned long refresh_display_current;
unsigned long refresh_display_period=1000;

unsigned long delay_start;
unsigned long delay_current;
unsigned long delay_period=1000;

byte units,tens;
void setup() {
  DDRB=0xFF;   
  refresh_display_start = millis();
}

void loop() {
  
  PORTB = (units%10)|DIGIT_1ON_2OFF;
  PORTB = (tens%10)|DIGIT_2ON_1OFF;    

  refresh_display_current = millis();
  if(refresh_display_current - refresh_display_start >= refresh_display_period){
     units++;
     if((units%10)==9)tens++;
     refresh_display_start = millis();
  }
}

Well, for point #1 when you do

     units++;
     if((units%10)==9)tens++;

instead of just incrementing the tens you should also reset the units to 0...(don’t forget the {} in the if)

For your second point, just don’t display anything if à condition is met...

OK, I figured it out:

// This program is to drive 2-Digit 7-seg common anode
// With 74LS47 BCD IC
#define DIGIT_1ON_2OFF 0x20
#define DIGIT_2ON_1OFF 0x10

byte units,tens;

unsigned long refresh_display_start;
unsigned long refresh_display_current;
unsigned long refresh_display_period=1000;

unsigned long delay_start;
unsigned long delay_current;
unsigned long delay_period=1;

void refersh_displays(void);


void setup() {
  DDRB=0xFF;   
  refresh_display_start = millis();
  delay_start = millis();
}

void loop() {

  delay_current = millis();
  if(delay_current - delay_start >= delay_period){
    PORTB = (units%10)|DIGIT_1ON_2OFF;
    delay_start = millis();
  }

  delay_current = millis();
  if(delay_current - delay_start >= delay_period){ 
    PORTB = (tens%10)|DIGIT_2ON_1OFF;    
    delay_start = millis();
  }

  refersh_displays();
}
  //PORTB = 0x30;
  
void delay_displays(void){
  
}

void refersh_displays(void){
    refresh_display_current = millis();
  if(refresh_display_current - refresh_display_start >= refresh_display_period){
     units++;
     if(((units-1)%10)==9)tens++;
     refresh_display_start = millis();
  }
}

Hope that helps :slight_smile:

J-M-L:
Well, for point #1 when you do

     units++;

if((units%10)==9)tens++;


instead of just incrementing the `tens` you should also reset the `units` to 0...(don’t forget the {} in the `if`)

I used % with 10 ==> to not reset any counter

For your second point, just don’t display anything if à condition is met...

I used millis for that and now it works perfectly.

You should have just one integer as a counter , the. Counting will be much easier

int counter =0, units = 0, tens =0;
...
if (++counter >= 100) counter =0;
tens = counter / 10;
units = counter % 10;