/*
   Project: Four digit 7 segment counter
   Description: Basic counter sketch
   Creation date: 09/20/22
   Author: AnonEngineering

   https://wokwi.com/projects/343382107688534610

   License: Beerware
*/

const int NUM_DIGITS  = 4;
const int DP_PIN      = 11;
//const bool COM_ANODE = true; // common anode = true, common cathode = false
const byte DIGIT_PINS[] = {8, 6, 5, 2}; // digit pins, digits 4 - 1 ( Left to right)
const byte SEG_PINS[]   = {3, 7, 10, 12, 13, 4, 9}; // segment pins A - G
const byte digitSegVals[10][7] {  // [digits 0 - 9], [segments A - G]
  {0, 0, 0, 0, 0, 0, 1}, //0
  {1, 0, 0, 1, 1, 1, 1}, //1
  {0, 0, 1, 0, 0, 1, 0}, //2
  {0, 0, 0, 0, 1, 1, 0}, //3
  {1, 0, 0, 1, 1, 0, 0}, //4
  {0, 1, 0, 0, 1, 0, 0}, //5
  {0, 1, 0, 0, 0, 0, 0}, //6
  {0, 0, 0, 1, 1, 1, 1}, //7
  {0, 0, 0, 0, 0, 0, 0}, //8
  {0, 0, 0, 1, 1, 0, 0}, //9
};
const long interval = 100;

unsigned long prevTime = 0;
int dp = 1; // where to place decimal point

void setup() {
  //Serial.begin(9600);
  for(int segVal = 0; segVal < (sizeof(SEG_PINS) / sizeof(SEG_PINS[0])); segVal++) {
    pinMode(SEG_PINS[segVal], OUTPUT);
  }
  for(int digitVal = 0; digitVal < NUM_DIGITS; digitVal++) {
    pinMode(SEG_PINS[digitVal], OUTPUT); 
  }
  pinMode(DP_PIN, OUTPUT);
}

void loop() {
  static int countVal = 0;
  if(millis() - prevTime >= interval) {
    prevTime = millis();
    showDigits(countVal);
    countVal++;
    if(countVal > 9999) countVal = 0;   // check # of digits
  }
}

void showDigits(int value)  {
  for(int digit = NUM_DIGITS-1; digit >= 0; digit--)  { // High digits first, higher power first
    driveSegments(int(value/pow(10, digit)) % 10);  // setup segment pins
    if (digit == dp) digitalWrite(DP_PIN, LOW);     // turn on DP?
    digitalWrite(DIGIT_PINS[digit], HIGH);          // turn digit on
    digitalWrite(DIGIT_PINS[digit], LOW);           // turn digit & DP off
    digitalWrite(DP_PIN, HIGH); 
  }
}

void driveSegments(int digitVal) {
  for (int segVal = 0; segVal < (sizeof(SEG_PINS) / sizeof(SEG_PINS[0])); segVal++) {
    digitalWrite(SEG_PINS[segVal], digitSegVals[digitVal][segVal]);
  }
}