// Static versus Multiplexed signals for 7-segment displays.
//
// 11 May 2024
// Version 1
// by Koepel, Public Domain
//
// The static signals need a lot of wires.
// The multiplexed display needs a delay.

const int staticSegmentPins[4][8] =
{
  {46, 47, 48, 49, 50, 51, 52, 53}, // right display: A B C D E F G DP
  {38, 39, 40, 41, 42, 43, 44, 45},
  {30, 31, 32, 33, 34, 35, 36, 37},
  {22, 23, 24, 25, 26, 27, 28, 29}  // left display
};

const int multiplexSegmentPins[8] =
{
  A8, A9, A10, A11, A12, A13, A14, A15 // A B C D E F G DP
};

const int multiplexDigitPins[4] =
{
  A7, A6, A5, A4       // A7 is for most right digit
};

// Segment A is in bit 0
// Segment B is in bit 1
// and so on.
const int NumbersToSegments[10]
{
  0b00111111,   // 0
  0b00000110,   // 1
  0b01011011,   // 2 
  0b01001111,   // 3
  0b01100110,   // 4
  0b01101101,   // 5
  0b01111101,   // 6
  0b00000111,   // 7
  0b01111111,   // 8
  0b01100111,   // 9
};

int counter;

unsigned long previousMillis;
const unsigned long interval = 600UL;

void setup() 
{
  // Initialize all the pins for the displays with static signals.
  for(int i=0; i<4; i++)
    for(int j=0; j<8; j++)
      pinMode(staticSegmentPins[i][j], OUTPUT);

  // Initialize the pins of the 7 segments for the multiplexed signals.
  for(int i=0; i<8; i++)
    pinMode(multiplexSegmentPins[i], OUTPUT);

  // Initialize the pins of the 4 digits for the multiplexed signals.
  // They are active low, so their default value is high.
  for(int i=0; i<4; i++)
  {
    pinMode(multiplexDigitPins[i], OUTPUT);
    digitalWrite(multiplexDigitPins[i], HIGH);
  }
}

void loop() 
{
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;

    counter++;
    if(counter > 9999)
      counter = 0;

    // For the static signals, set the signals
    // just once. The number will stay on the display.
    ShowStaticNumber(counter);
  }

  // Keep it running all the time, because the actived segments
  // are only actived for a short time.
  ShowMultiplexedNumber(counter);

  // Enable this delay to show the difference.
  // delay(500);
}

// 4 display of 7 segments each makes a total of 28 wires to be set.
void ShowStaticNumber(int number)
{
  for(int display=0; display<4; display++)
  {
    int decimaldigit = number % 10; // get the lowest decimal digit
    number /= 10;                   // prepare for next decimal digit

    for(int segment=0; segment<7; segment++)
    {
      int value = bitRead(NumbersToSegments[decimaldigit], segment) == 1 ? HIGH : LOW;
      digitalWrite(staticSegmentPins[display][segment], value);
    }
  }
}

// There are less wires: 7 + 4 = 11 for all the segments.
// The code temporarily activates the segments of a single digit.
void ShowMultiplexedNumber(int number)
{
  for(int digit=0; digit<4; digit++)
  {
    int decimaldigit = number % 10; // get the lowest decimal digit
    number /= 10;                   // prepare for next decimal digit

    for(int segment=0; segment<7; segment++)
    {
      int value = bitRead(NumbersToSegments[decimaldigit], segment) == 1 ? HIGH : LOW;
      digitalWrite(multiplexSegmentPins[segment], value);
    }

    // Activate this digit.
    // Keep it active for some time to show the activated segments.
    digitalWrite(multiplexDigitPins[digit], LOW);
    delay(10);
    digitalWrite(multiplexDigitPins[digit], HIGH);
  }
}
Static
Multiplexed