// ავტორი: ზურაბ შერმადინი 4L7ZS
// აკრიბეთ რიცხვი 1 დან 32 მდე და
// დააკლიკეთ * -ს.
// Define the Arduino pins connected to the 74HC595
const int dataPin = 11; // DS (SER) - Serial Data Input
const int clockPin = 12; // SHCP (SRCLK) - Shift Register Clock
const int latchPin = 9; // STCP (RCLK) - Latch Pin
// Keypad pins
const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[ROWS] = {5, 4, 3, 2}; // Connect to row pinouts
byte colPins[COLS] = {8, 7, 6}; // Connect to column pinouts
// We have 4 shift registers = 32 bits
const int numRegisters = 4;
byte registerState[numRegisters]; // Array to hold the state of each register
// Variables for number input
String inputNumber = "";
const int maxDigits = 2; // Maximum 2 digits for numbers 1-32
unsigned long lastKeyPressTime = 0;
const unsigned long debounceTime = 200;
void setup() {
// Set the pins as outputs
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(latchPin, OUTPUT);
// Initialize keypad pins
for (byte r = 0; r < ROWS; r++) {
pinMode(rowPins[r], INPUT_PULLUP);
}
for (byte c = 0; c < COLS; c++) {
pinMode(colPins[c], OUTPUT);
digitalWrite(colPins[c], HIGH);
}
// Initialize serial for debugging
Serial.begin(9600);
// Initialize all outputs to 0 (LOW)
clearRegisters();
writeRegisters();
Serial.println("Enter a number 1-32 to light up corresponding LED");
Serial.println("Press '#' to clear input, '*' to confirm");
}
// Sets all register bits to LOW
void clearRegisters() {
for (int i = 0; i < numRegisters; i++) {
registerState[i] = 0;
}
}
// Writes the states from the registerState array to the shift registers
void writeRegisters() {
// Pull the latch pin LOW to start the update
digitalWrite(latchPin, LOW);
// Shift out the data, starting from the LAST register.
for (int i = numRegisters - 1; i >= 0; i--) {
shiftOut(dataPin, clockPin, MSBFIRST, registerState[i]);
}
// Pull the latch pin HIGH to update the outputs all at once
digitalWrite(latchPin, HIGH);
}
// Light up a specific LED (1-32)
void lightUpLED(int ledNumber) {
if (ledNumber < 1 || ledNumber > 32) {
Serial.println("Invalid LED number! Use 1-32");
return;
}
clearRegisters();
// Convert to 0-based index (0-31)
int index = ledNumber - 1;
int reg = index / 8;
int bit = index % 8;
registerState[reg] = (1 << bit);
writeRegisters();
Serial.print("LED ");
Serial.println(ledNumber);
}
// Scan keypad for input
char getKey() {
char key = '\0';
for (byte c = 0; c < COLS; c++) {
digitalWrite(colPins[c], LOW);
for (byte r = 0; r < ROWS; r++) {
if (digitalRead(rowPins[r]) == LOW) {
key = keys[r][c];
}
}
digitalWrite(colPins[c], HIGH);
delay(1);
}
return key;
}
void processKeypad() {
char key = getKey();
if (key != '\0' && millis() - lastKeyPressTime > debounceTime) {
lastKeyPressTime = millis();
if (key >= '0' && key <= '9') {
// Digit pressed
if (inputNumber.length() < maxDigits) {
inputNumber += key;
Serial.println(inputNumber);
}
}
else if (key == '*') {
// Confirm/Enter
if (inputNumber.length() > 0) {
int number = inputNumber.toInt();
if (number >= 1 && number <= 32) {
lightUpLED(number);
} else {
Serial.println("Number must be 1-32");
}
inputNumber = "";
}
}
else if (key == '#') {
// Clear
inputNumber = "";
clearRegisters();
writeRegisters();
Serial.println("Cleared");
}
}
}
void loop() {
// Check for keypad input
processKeypad();
// Optional: Add a timeout to clear input after inactivity
if (inputNumber.length() > 0 && millis() - lastKeyPressTime > 5000) {
inputNumber = "";
Serial.println("Input timeout - cleared");
}
}