#include <Keypad.h>

// Define the keypad layout
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

// Define the row and column pin numbers
byte rowPins[ROWS] = {9, 8, 7, 6}; // Rows 0 to 3
byte colPins[COLS] = {5, 4, 3, 2}; // Columns 0 to 3

// Create the Keypad object
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

// BCD IC A (ones digit)
const int bcdA_A = 22 ;
const int bcdA_B = 24 ;
const int bcdA_C = 26 ;
const int bcdA_D = 28 ;

// BCD IC B (tens digit)
const int bcdB_A = 30 ;
const int bcdB_B = 32 ;
const int bcdB_C = 34 ;
const int bcdB_D = 36 ;

// BCD IC C (hundreds digit)
const int bcdC_A = 38 ;
const int bcdC_B = 40 ;
const int bcdC_C = 42 ;
const int bcdC_D = 44 ;

// BCD IC D (thousands digit)
const int bcdD_A = 46 ;
const int bcdD_B = 48 ;
const int bcdD_C = 50 ;
const int bcdD_D = 52 ;

int counterValue = 0; // stores counter value from 0 - 9999

void setup() {
  // Set the pin mode for the BCD ICs here
  // BCD IC A (ones digit)
  pinMode(bcdA_A, OUTPUT);
  pinMode(bcdA_B, OUTPUT);
  pinMode(bcdA_C, OUTPUT);
  pinMode(bcdA_D, OUTPUT);

  // BCD IC B (tens digit)
  pinMode(bcdB_A, OUTPUT);
  pinMode(bcdB_B, OUTPUT);
  pinMode(bcdB_C, OUTPUT);
  pinMode(bcdB_D, OUTPUT);

  // BCD IC C (hundreds digit)
  pinMode(bcdC_A, OUTPUT);
  pinMode(bcdC_B, OUTPUT);
  pinMode(bcdC_C, OUTPUT);
  pinMode(bcdC_D, OUTPUT);

  // BCD IC D (thousands digit)
  pinMode(bcdD_A, OUTPUT);
  pinMode(bcdD_B, OUTPUT);
  pinMode(bcdD_C, OUTPUT);
  pinMode(bcdD_D, OUTPUT);
}

void loop() {
  // Read keypad input
  char key = keypad.getKey();
  
  // If a key is pressed, update counterValue and display it
  if (key != NO_KEY) {
    // Update counterValue with the pressed key
    if (key >= '0' && key <= '9') {
      counterValue = counterValue * 10 + (key - '0');
    }
    else if (key == '#') {
      counterValue = 0; // Reset counterValue if '#' is pressed
    }
    else {
      // Handle other keys if needed
    }
    
    // Ensure counterValue stays within range (0 - 9999)
    counterValue %= 10000;
    
    // Update the display
    displayCounter();
  }
}

void displayCounter() {
  // get each digit in different place
  int ones = (counterValue / 1000) % 10;
  int tens = (counterValue / 100) % 10;
  int hundreds = (counterValue / 10) % 10;
  int thousands = counterValue % 10;
  // Display ones digit
  digitalWrite(bcdA_A, ones & 0b0001);
  digitalWrite(bcdA_B, ones & 0b0010);
  digitalWrite(bcdA_C, ones & 0b0100);
  digitalWrite(bcdA_D, ones & 0b1000);

  // Display tens digit
  digitalWrite(bcdB_A, tens & 0b0001);
  digitalWrite(bcdB_B, tens & 0b0010);
  digitalWrite(bcdB_C, tens & 0b0100);
  digitalWrite(bcdB_D, tens & 0b1000);

  // Display hundreds digit
  digitalWrite(bcdC_A, hundreds & 0b0001);
  digitalWrite(bcdC_B, hundreds & 0b0010);
  digitalWrite(bcdC_C, hundreds & 0b0100);
  digitalWrite(bcdC_D, hundreds & 0b1000);

  // Display thousands digit
  digitalWrite(bcdD_A, thousands & 0b0001);
  digitalWrite(bcdD_B, thousands & 0b0010);
  digitalWrite(bcdD_C, thousands & 0b0100);
  digitalWrite(bcdD_D, thousands & 0b1000);
}
74HC47N ICBreakout
74HC47N ICBreakout
74HC47N ICBreakout
74HC47N ICBreakout