#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Keypad Setup
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'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
const int buttonEnter = 12;
const int buttonPB11 = 11;
const int buttonReset = 10;
int gelang[4] = {-1, -1, -1, -1};
int gelangAktif = 0;
String warna[10] = {
"HITAM", "COKLAT", "MERAH", "ORANGE", "KUNING",
"HIJAU", "BIRU", "UNGU", "ABU2", "PUTIH"
};
unsigned long lastKeyPressTime = 0;
void setup() {
lcd.init();
lcd.backlight();
pinMode(buttonEnter, INPUT_PULLUP);
pinMode(buttonReset, INPUT_PULLUP);
pinMode(buttonPB11, INPUT_PULLUP); // Initialize push button
showOpeningScreen1();
delay(3000);
showOpeningScreen2();
delay(3000);
tampilAwal();
}
void loop() {
char key = keypad.getKey();
if (digitalRead(buttonPB11) == LOW) {
if (millis() - lastKeyPressTime > 1000) {
showOpeningScreen1();
delay(3000);
showOpeningScreen2();
delay(3000);
resetCalculator();
}
} else {
lastKeyPressTime = millis();
}
// Pilih gelang aktif dengan pengecekan error
if (key == 'A' || key == 'B' || key == 'C' || key == 'D') {
handleBandSelection(key);
}
// Input digit 0-9 untuk gelang 1-3
if (key && isDigit(key) && gelangAktif < 3) {
gelang[gelangAktif] = key - '0';
updateLCD();
}
// Input gelang ke-4 (toleransi)
if (key == '*') {
gelang[3] = 5; // Emas
updateLCD();
}
if (key == '#') {
gelang[3] = 10; // Perak
updateLCD();
}
// Tombol ENTER → hitung resistor
if (digitalRead(buttonEnter) == LOW) {
calculateResistor();
}
// Tombol RESET
if (digitalRead(buttonReset) == LOW) {
resetCalculator();
delay(500);
}
}
void handleBandSelection(char key) {
int newGelang = -1;
if (key == 'A') newGelang = 0;
else if (key == 'B') newGelang = 1;
else if (key == 'C') newGelang = 2;
else if (key == 'D') newGelang = 3;
// Cek semua gelang sebelumnya sudah diisi
bool errorFound = false;
for (int i = 0; i < newGelang; i++) {
if (gelang[i] == -1) {
showError(i);
errorFound = true;
break;
}
}
if (!errorFound) {
gelangAktif = newGelang;
updateLCD();
}
}
void calculateResistor() {
if (gelang[0] >= 0 && gelang[1] >= 0 && gelang[2] >= 0 && gelang[3] >= 0) {
long nilai = (gelang[0] * 10 + gelang[1]);
for (int i = 0; i < gelang[2]; i++) {
nilai *= 10;
}
float toleransi = gelang[3] / 100.0;
long min = nilai - (nilai * toleransi);
long max = nilai + (nilai * toleransi);
String nilaiStr = formatResistance(nilai);
String minStr = formatResistance(min);
String maxStr = formatResistance(max);
lcd.setCursor(0, 0);
lcd.print("G1: " + warna[gelang[0]]);
lcd.setCursor(13, 0);
lcd.print(nilaiStr); lcd.print(" \xF4");
lcd.setCursor(0, 1);
lcd.print("G2: " + warna[gelang[1]]);
lcd.setCursor(13, 1);
lcd.print(gelang[3]); lcd.print("%");
lcd.setCursor(0, 2);
lcd.print("G3: " + warna[gelang[2]]);
lcd.setCursor(13, 2);
lcd.print(minStr); lcd.print(" \xF4");
lcd.setCursor(0, 3);
lcd.print(String("G4: ") + (gelang[3] == 5 ? "EMAS " : "PERAK"));
lcd.setCursor(13, 3);
lcd.print(maxStr); lcd.print(" \xF4");
delay(1000);
}
}
String formatResistance(long value) {
if (value >= 1000000) {
float mega = value / 1000000.0;
if (mega == (long)mega) {
return String((long)mega) + "M"; // Contoh: 2000000 → 2M
} else {
String s = String(mega, 3);
while (s.endsWith("0")) s.remove(s.length() - 1);
if (s.endsWith(".")) s.remove(s.length() - 1);
return s + "M";
}
} else if (value >= 1000) {
float kilo = value / 1000.0;
if (kilo == (long)kilo) {
return String((long)kilo) + "K"; // Contoh: 2000 → 2K
} else {
String s = String(kilo, 3);
while (s.endsWith("0")) s.remove(s.length() - 1);
if (s.endsWith(".")) s.remove(s.length() - 1);
return s + "K";
}
} else {
return String(value);
}
}
void showError(int gelangError) {
lcd.setCursor(0, gelangError);
lcd.print("G");
lcd.print(gelangError + 1);
lcd.print(": ERROR! ");
delay(1000);
updateLCD();
}
void showOpeningScreen1() {
lcd.clear();
lcd.setCursor(3, 0); lcd.print("KALKULATOR RES");
lcd.setCursor(6, 1); lcd.print("4 GELANG");
lcd.setCursor(1, 2); lcd.print("MIKROKONTROLLER II");
lcd.setCursor(0, 3); lcd.print("SHEILLA N.V.,ST.,MT.");
}
void showOpeningScreen2() {
lcd.clear();
lcd.setCursor(5, 0); lcd.print("RE2D / 08");
lcd.setCursor(2, 1); lcd.print("HAIDAR FAOZAN A.");
lcd.setCursor(0, 2); lcd.print("MUHAMMAD ALFI KIROM");
lcd.setCursor(3, 3); lcd.print("RIF'AT SUNGKAR");
}
void tampilAwal() {
lcd.clear();
lcd.setCursor(0, 0); lcd.print("G1: ");
lcd.setCursor(0, 1); lcd.print("G2: ");
lcd.setCursor(0, 2); lcd.print("G3: ");
lcd.setCursor(0, 3); lcd.print("G4: ");
}
void updateLCD() {
for (int i = 0; i < 4; i++) {
lcd.setCursor(0, i);
lcd.print("G");
lcd.print(i + 1);
lcd.print(": ");
if (gelang[i] >= 0) {
if (i < 3) {
lcd.print(warna[gelang[i]]);
} else {
lcd.print(gelang[i] == 5 ? "EMAS" : "PERAK");
}
}
// Menampilkan nilai resistor jika gelang sudah diisi
if (i == 0 && gelang[0] >= 0 && gelang[1] >= 0) {
long nilai = (gelang[0] * 10 + gelang[1]);
for (int j = 0; j < gelang[2]; j++) {
nilai *= 10;
}
lcd.setCursor(13, i);
lcd.print(formatResistance(nilai)); // Menampilkan nilai resistor
}
if (i == gelangAktif) {
lcd.print(" <");
}
}
}
void resetCalculator() {
for (int i = 0; i < 4; i++) gelang[i] = -1;
gelangAktif = 0;
tampilAwal();
}