// https://github.com/rmorenojr/ElegooTutorial/blob/master/Lesson%2028%20-%204%20Digit%207%20Segment%20Display/4_digit_proper_bb.png

const int dataPin  = 12;  // 74HC595 pin 8 DS
const int latchPin = 11;  // 74HC595 pin 9 STCP
const int clockPin = 9;   // 74HC595 pin 10 SHCP
const int digit0   = 7;   // 7-Segment pin D4
const int digit1   = 6;   // 7-Segment pin D3
const int digit2   = 5;   // 7-Segment pin D2
const int digit3   = 4;   // 7-Segment pin D1

byte table[] =
{ 0x5F,  // = 0
  0x44,  // = 1
  0x9D,  // = 2
  0xD5,  // = 3
  0xC6,  // = 4
  0xD3,  // = 5
  0xDB,  // = 6
  0x45,  // = 7
  0xDF,  // = 8
  0xC7,  // = 9
  0xCF,  // = A
  0xDA,  // = b
  0x1B,  // = C
  0xDC,  // = d
  0x9B,  // = E
  0x8B,  // = F
  0x00   // blank
};
byte digitDP = 32;
byte controlDigits[] = { digit0, digit1, digit2, digit3 };
byte displayDigits[] = { 0, 0, 0, 0, 0 };
unsigned long onTime = 0;
bool switchView = false;
unsigned int counter = 0;
int digitDelay = 50;
int brightness = 90;
unsigned int ShowSegCount = 250;
//bool commonCathode = true;

void setup() {
  //DDRD = 0xff;
  //DDRB = 0xff;
  //PORTD = 0xf0;

  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  for (int x = 0; x < 4; x++) {
    pinMode(controlDigits[x], OUTPUT);
    digitalWrite(controlDigits[x], LOW);
  }
}

void DisplaySegments() {
  for (int x = 0; x < 4; x++) {
    for (int j = 0; j < 4; j++) {
      digitalWrite(controlDigits[j], LOW);
    }
    digitalWrite(latchPin, LOW);
    if (bitRead(displayDigits[4], x) == 1) {
      shiftOut(dataPin, clockPin, MSBFIRST, displayDigits[x]);
    } else {
      shiftOut(dataPin, clockPin, MSBFIRST, table[displayDigits[x]]);
    }

    digitalWrite(latchPin, HIGH);
    digitalWrite(controlDigits[x], HIGH);
    delay(1);
  }
  for (int j = 0; j < 4; j++) {
    digitalWrite(controlDigits[j], LOW);
  }
}

void HexCounter() {
  byte Letter = B00011011;
  bool incrementValue = true;
  for (int d = 0; d < 3; d++) {
    int x = int(displayDigits[d]);
    if (incrementValue == true) {
      x++;
      incrementValue = false;
      if (x > 15) {
        displayDigits[d] = 0;
        incrementValue = true;
      } else {
        displayDigits[d] = byte(x);
      }
    }
  }
  displayDigits[3] = Letter;
  displayDigits[4] = B1000;

  if ((displayDigits[0] == 0) && (displayDigits[1] == 0) && (displayDigits[2] == 0)) {
    switchView = !switchView;
    for (int x = 0; x < 5; x++) {
      displayDigits[x] = 0;
    }
    displayDigits[4] = B0000;
  }
}

void RawDisplay() {

  displayDigits[0] = B01011111;  // 0
  displayDigits[1] = B00011010;  // L
  displayDigits[2] = B11001111;  // A
  displayDigits[3] = B11001110;  // H
  displayDigits[4] = B1111;

  if (counter < ShowSegCount) {
    counter++;
  } else {
    counter = 0;
    switchView = !switchView;
    for (int x = 0; x < 5; x++) {
      displayDigits[x] = 0;
    }
    displayDigits[4] = B0000;
  }
}

void loop() {
  DisplaySegments();
  delayMicroseconds(1638 * ((100 - brightness) / 10));
  unsigned long nowValue = millis() - onTime;
  if (nowValue >= long(digitDelay)) {
    onTime = millis();
    if (switchView == true) {
      RawDisplay();
    } else {
      HexCounter();
    }
  }
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
sevseg1:A
sevseg1:B
sevseg1:C
sevseg1:D
sevseg1:E
sevseg1:F
sevseg1:G
sevseg1:DP
sevseg1:DIG1
sevseg1:DIG2
sevseg1:DIG3
sevseg1:DIG4
sevseg1:COM
sevseg1:CLN
r5:1
r5:2
r6:1
r6:2
r7:1
r7:2
r8:1
r8:2
r9:1
r9:2
r10:1
r10:2
r11:1
r11:2
r12:1
r12:2
74HC595
sr1:Q1
sr1:Q2
sr1:Q3
sr1:Q4
sr1:Q5
sr1:Q6
sr1:Q7
sr1:GND
sr1:Q7S
sr1:MR
sr1:SHCP
sr1:STCP
sr1:OE
sr1:DS
sr1:Q0
sr1:VCC
PN2222Breakout
chip4:E
chip4:B
chip4:C
PN2222Breakout
chip5:E
chip5:B
chip5:C
PN2222Breakout
chip6:E
chip6:B
chip6:C
PN2222Breakout
chip7:E
chip7:B
chip7:C
r1:1
r1:2
r2:1
r2:2
r3:1
r3:2
r4:1
r4:2
vcc1:VCC
vcc2:VCC
gnd1:GND
gnd2:GND
gnd3:GND