#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
// LCD Settings (set to your I2C address)
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Keypad Settings
const byte ROWS = 4; // four rows
const byte COLS = 4; // four columns
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = { 8, 7, A5, A4 }; // connect to the row pinouts of the keypad
byte colPins[COLS] = { A3, A2, A1, A0 }; // connect to the column pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Relay and LED pins
const int relayPin = 9;
const int ledPin = 11;
char Frequency[9]; // stores the Frequency
char enteredFrequency[9]; // stores user-entered Frequency for validation
int FrequencyIndex = 0;
boolean FrequencySet = false;
int setTime = 0; // duration in seconds
boolean repeatAllowed = false;
int RechargingTime = 0; // cool down time in seconds
boolean deviceArmed = false;
// Custom character for solid block
byte solidBlock[8] = {
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111
};
void setup() {
lcd.begin(20, 4); // Initialize the LCD with 20 columns and 4 rows
lcd.backlight(); // Turn on the backlight for the LCD
pinMode(relayPin, OUTPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(relayPin, LOW);
digitalWrite(ledPin, LOW);
lcd.setCursor(0,1);
lcd.print(" Device");
lcd.setCursor(0,2);
lcd.print(" Initializing");
delay(2000);
lcd.clear();
// Create custom character for solid block
lcd.createChar(0, solidBlock);
// Setup phase
setupDevice();
// Play phase
playDevice();
}
void loop() {
// Empty loop since the device will run once through the play section
}
// Setup phase: Create Frequency, Set Timer, Allow Repeat, Set Recharging
void setupDevice() {
createFrequency(); // Menu 1: Create Frequency
setGameTime(); // Menu 2: Set Game Timer
if (confirmAction("Allow Repeat?")) {
repeatAllowed = true;
setRechargingTime(); // Menu 3: Set Cool Down Time
} else {
repeatAllowed = false; // Set to false if not allowed
}
}
// Play phase: Run the device based on setup parameters
void playDevice() {
while (true) { // Infinite loop for repeated activation
if (FrequencySet) {
// Enter Frequency to Activate Device
if (enterFrequencyToActivate()) {
deviceActive();
// If repeat is allowed, go into Recharging and return to frequency check
if (repeatAllowed) {
// Wait for Recharging
lcd.clear();
unsigned long coolStartTime = millis();
unsigned long coolTimeElapsed = 0;
while (coolTimeElapsed < (RechargingTime * 1000)) {
int progress = map(coolTimeElapsed, 0, RechargingTime * 1000, 0, 20);
lcd.setCursor(0, 1);
lcd.print("Recharging: ");
lcd.setCursor(0, 3); // Move to where the bar starts
for (int i = 0; i < progress; i++) {
lcd.write(byte(0)); // Use the custom solid block character
}
delay(1000); // Update every second
coolTimeElapsed = millis() - coolStartTime;
}
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(" Device Ready");
}
}
}
}
}
// Function to prompt Y/N (A for Yes, B for No)
boolean confirmAction(String message) {
lcd.clear();
lcd.print(message + " Y/N");
while (true) {
char key = keypad.getKey();
if (key == 'A') { // 'A' means Yes
return true;
} else if (key == 'B') { // 'B' means No
return false;
}
}
}
// Menu 1: Frequency Setup
void createFrequency() {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(" Enter Frequency:");
lcd.setCursor(0, 2);
lcd.print(" 000.000");
FrequencyIndex = 0;
// Array to hold cursor positions for each digit
int positions[6] = {6, 7, 8, 10, 11, 12}; // LCD cursor positions for each digit, skipping the decimal
while (FrequencyIndex < 6) {
char key = keypad.getKey();
if (key) {
Frequency[FrequencyIndex] = key;
FrequencyIndex++;
lcd.setCursor(positions[FrequencyIndex - 1], 2); // Move cursor to the correct position
lcd.print(key); // Show the actual input number
}
}
Frequency[6] = '\0'; // Null-terminate the Frequency
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(" Confirm Frequency:");
lcd.setCursor(0, 2);
lcd.blink();
lcd.print(" 000.000");
FrequencyIndex = 0;
while (FrequencyIndex < 6) {
char key = keypad.getKey();
if (key) {
enteredFrequency[FrequencyIndex] = key;
FrequencyIndex++;
lcd.setCursor(positions[FrequencyIndex - 1], 2); // Move cursor to the correct position
lcd.print(key); // Show the actual input number
}
}
enteredFrequency[6] = '\0';
lcd.noBlink();
if (strcmp(Frequency, enteredFrequency) == 0) {
FrequencySet = true;
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(" Frequency Set!");
delay(2000);
lcd.clear();
} else {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(" Frequencies");
lcd.setCursor(0, 2);
lcd.print(" do not match");
delay(2000);
createFrequency(); // Restart Frequency setup
}
}
// Menu 2: Set Game Timer (in mm:ss format)
void setGameTime() {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Set Time (mm:ss):");
lcd.setCursor(0, 2);
lcd.print(" 00:00"); // Initialize with 00:00
// Array to hold cursor positions for each digit (skipping the colon)
int positions[4] = {6, 7, 9, 10}; // LCD cursor positions for each digit
String timeInput = "";
int minutes = 0;
int seconds = 0;
char key;
int cursorPosition = 0; // To track the cursor position in timeInput
lcd.setCursor(positions[cursorPosition], 2); // Move cursor to the correct position
while (true) {
key = keypad.getKey();
if (key && isDigit(key)) {
// Only allow 4 digits (2 for minutes, 2 for seconds)
if (timeInput.length() < 4) {
timeInput += key; // Append the digit to timeInput
lcd.setCursor(positions[cursorPosition], 2); // Set cursor to current position
lcd.print(key); // Display the digit
cursorPosition++; // Move to the next cursor position
// Check if we need to print the colon
if (cursorPosition == 2) {
lcd.setCursor(8, 2); // Set cursor after the first two digits
lcd.print(":");
}
}
// When we've entered 4 digits
if (timeInput.length() == 4) {
minutes = timeInput.substring(0, 2).toInt(); // Extract minutes
seconds = timeInput.substring(2, 4).toInt(); // Extract seconds
// Validate the time range
if (minutes <= 15 && seconds <= 59) {
setTime = (minutes * 60) + seconds; // Convert to seconds
break; // Exit the loop
} else {
lcd.clear();
lcd.print("Invalid Time");
delay(2000);
setGameTime(); // Restart if invalid
return; // Ensure we exit the function to avoid endless loop
}
}
}
}
// Clear and display the set time
lcd.clear();
lcd.print("Time Set: ");
lcd.print(minutes);
lcd.print("m ");
lcd.print(seconds);
lcd.print("s");
delay(2000);
}
// Menu 3: Set Cool Down Time
void setRechargingTime() {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(" Set Recharging:");
lcd.setCursor(0, 1);
String RechargingInput = "";
int minutes = 0;
int seconds = 0;
char key;
while (true) {
key = keypad.getKey();
if (key && isDigit(key)) {
RechargingInput += key;
lcd.print(key);
if (RechargingInput.length() == 2) { // After 2 digits for minutes
lcd.print(":");
}
if (RechargingInput.length() == 4) { // After 2 more digits for seconds
minutes = RechargingInput.substring(0, 2).toInt(); // Extract minutes
seconds = RechargingInput.substring(2, 4).toInt(); // Extract seconds
if (minutes <= 5 && seconds <= 59) { // Ensure valid time range
RechargingTime = (minutes * 60) + seconds; // Convert to seconds
// Confirm Recharging time
if (confirmAction("Recharging Set: " + String(minutes) + "m " + String(seconds) + "s")) {
lcd.clear();
lcd.setCursor(0,1);
lcd.print(" Recharging Set!");
delay(2000);
break;
}
} else {
lcd.clear();
lcd.setCursor(0,1);
lcd.print(" Invalid Time");
delay(2000);
setRechargingTime();
}
}
}
}
}
// Menu 4: Enter Frequency to Activate Device
boolean enterFrequencyToActivate() {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(" Enter Frequency:");
lcd.setCursor(0, 2);
lcd.print(" 000.000");
FrequencyIndex = 0;
int positions[6] = {6, 7, 8, 10, 11, 12}; // LCD cursor positions for each digit, skipping the decimal
while (FrequencyIndex < 6) {
char key = keypad.getKey();
if (key && isDigit(key)) {
enteredFrequency[FrequencyIndex] = key;
lcd.setCursor(positions[FrequencyIndex], 2); // Move cursor to the correct position
lcd.print(key); // Display the entered digit
FrequencyIndex++;
}
}
enteredFrequency[6] = '\0';
if (strcmp(Frequency, enteredFrequency) == 0) {
return true;
} else {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Wrong Frequency!");
delay(2000);
return false;
}
}
// Device Active Function
void deviceActive() {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(" Jammer Active!");
digitalWrite(relayPin, HIGH);
digitalWrite(ledPin, HIGH);
delay(setTime * 1000); // Activate device for set time
digitalWrite(relayPin, LOW);
digitalWrite(ledPin, LOW);
}