void init_port()
{
volatile char *ddrf = (char *)0x30; // DDRF – data direction for rows
volatile char *ddrk = (char *)0x107; // DDRK – data direction for columns
volatile char *portk = (char *)0x108; // PORTK – to enable pull-ups
volatile char *ddra=(char *)0x21;
volatile char *ddrd=(char *)0x2A;
*ddrf = 0x0F; // Lower 4 bits as output (rows)
*ddrk = 0x00; // All PORTK pins as input (columns)
*portk = 0xFF; // Enable pull-ups
*ddra=0x0FF;
*ddrd=0xFF;
}
char output(char data)
{
volatile char *pout= (char *)0x31;
*pout=data;
}
char input()
{
volatile char *pinK = (char *)0x106; // PIN register for PORTK
char input_d = ~(*pinK); // Invert since active low
return input_d;
}
int keymap[4][4] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7','8','9', 'C'},
{'*', '0','#','D'}
};
char getkeyr() {
int row, col;
char value;
for (row = 0; row < 4; row++) {
output(~(1 << row)); // Make one row low at a time (active low)
delay(1); // Small delay for signal stabilization
value = input();
if (value != 0x00) { // A key was pressed in this row
for (col = 0; col < 4; col++) {
if (value & (1 << col)) {
// Return the mapped key
delay(200); // Debounce delay
return keymap[row][col];
}
}
}
}
return 0; // No key press detected
}
void setup() {
init_port();
Serial.begin(9600);
Serial.println("choose option after entering values");
Serial.println("A : ADDITION");
Serial.println("B : SUBTRACTION");
Serial.println("C : MULTIPLICATION");
Serial.println("D : DIVISION");
Serial.println("# : clear inputs");
Serial.println("range : <=9999 ");
}
volatile char *portd = (char *)0x2B;
volatile char *porta = (char *)0x22;
int seg_pattern[10] = {
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F // 9
};
void out(char x)
{
volatile char *out;
out = 0x2B;
*out = 0x0F;
out = 0X22;
x=0x00;
*out = x;
}
int count = 0;
char digits[8] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '};
char operation = ' ';
bool showResult = false;
void loop() {
char key = getkeyr();
if (key >= '0' && key <= '9' && count < 8) {
digits[count++] = key;
delay(200);
}
// Wait for operation key after 8 digits are entered
if (count == 8 && (key == 'A' || key == 'B' || key == 'C' || key == 'D')) {
operation = key;
int num1 = (digits[0] - '0') * 1000 + (digits[1] - '0') * 100 +
(digits[2] - '0') * 10 + (digits[3] - '0');
int num2 = (digits[4] - '0') * 1000 + (digits[5] - '0') * 100 +
(digits[6] - '0') * 10 + (digits[7] - '0');
int result = 0;
switch (operation) {
case 'A': result = num1 + num2; break;
case 'B': result = num1 - num2; break;
case 'C': result = num1 * num2; break;
case 'D': result = (num2 != 0) ? num1 / num2 : 0; break;
}
Serial.println(operation);
// Display only 4 digits of result
digits[0] = (result / 1000) % 10 + '0';
digits[1] = (result / 100) % 10 + '0';
digits[2] = (result / 10) % 10 + '0';
digits[3] = result % 10 + '0';
showResult = true;
delay(500);
}
// Reset system with '#' key
if (key == '#') {
count = 0;
showResult = false;
operation = ' ';
for (int i = 0; i < 8; i++) digits[i] = ' ';
delay(300);
}
// Display logic
for (int i = 0; i < 4; i++) {
char val = showResult ? digits[i] : (count <= 4 ? digits[i] : digits[i + 4]);
if (val >= '0' && val <= '9') {
*porta = seg_pattern[val - '0'];
} else {
*porta = 0x00;
}
switch (i) {
case 0: *portd = 0x0E; break;
case 1: *portd = 0x0D; break;
case 2: *portd = 0x0B; break;
case 3: *portd = 0x07; break;
}
delay(5);
*portd = 0xFF;
}
}