#include <Keypad.h>
#include <LiquidCrystal.h>
#include <EEPROM.h>
// Keypad configuration
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] = {6, 7, 8, 9}; // Row pinouts
byte colPins[COLS] = {A0, A1, A2, A3}; // Column pinouts
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// LCD configuration (RS, E, D4, D5, D6, D7)
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // RS to Pin 12, E to Pin 11
// Pin for potentiometer
const int potPin = A4; // Connect potentiometer to A4
// Pin for buzzer
const int buzzerPin = 10; // Buzzer connected to digital pin D10
// Pin for alarm reset button
const int resetButtonPin = A5; // Button connected to A5
// Variables
String weightInput = ""; // String to hold weight input for calibration
bool inputMode = false; // Flag to indicate if we are in input mode
float calibrationWeight = 0.0; // User inputted control weight for calibration
float currentWeight = 0.0; // Current weight reading from potentiometer
float calibrationOffset = 0.0; // Offset to apply after calibration
// EEPROM address for storing calibration weight
const int CALIBRATION_ADDR = 0;
// Variables for buzzer control
bool buzzerActive = false; // Flag to indicate if buzzer is active
unsigned long buzzerStartTime = 0; // Start time of buzzer
bool alarmRegistered = false; // Flag to check if alarm has been registered
bool alarmSuppressed = false; // Flag to indicate if alarm is suppressed
unsigned long suppressEndTime = 0; // Time to end the alarm suppression
unsigned long displayResetMessageEndTime = 0; // Time to end the reset message display
void setup() {
Serial.begin(9600); // Initialize serial communication
lcd.begin(16, 2); // Initialize the LCD's columns and rows
lcd.clear(); // Clear the LCD
pinMode(buzzerPin, OUTPUT); // Set buzzer pin as output
pinMode(resetButtonPin, INPUT_PULLUP); // Set reset button pin as input with internal pull-up resistor
// Retrieve the last calibration weight from EEPROM
EEPROM.get(CALIBRATION_ADDR, calibrationWeight);
if (calibrationWeight == 0) {
lcd.print("Calibrate first!"); // Prompt for calibration if not set
} else {
lcd.print("Weight:");
}
}
void loop() {
char key = keypad.getKey(); // Get the pressed key
// Check if the reset button is pressed
if (digitalRead(resetButtonPin) == LOW && buzzerActive) {
buzzerActive = false; // Deactivate buzzer
digitalWrite(buzzerPin, LOW); // Turn off the buzzer
alarmSuppressed = true; // Suppress the alarm for 2 seconds
suppressEndTime = millis() + 2000; // Set the suppression end time
displayResetMessageEndTime = millis() + 1000; // Set the reset message display time (1 second)
lcd.clear();
lcd.print("Alarm Reset!"); // Display alarm reset message
}
// Check if it's time to stop displaying the reset message
if (alarmSuppressed && millis() >= displayResetMessageEndTime) {
lcd.clear();
lcd.print("Weight:"); // Return to normal weight display
}
// Check if the alarm suppression time is over
if (alarmSuppressed && millis() >= suppressEndTime) {
alarmSuppressed = false; // Re-enable alarm after 2 seconds
}
if (key) { // Check if a key is pressed
if (key == 'C' && !inputMode) { // If 'C' is pressed
inputMode = true; // Enter input mode
weightInput = ""; // Clear previous input
lcd.clear();
lcd.print("Enter Control:");
lcd.setCursor(0, 1); // Move to the second line
}
else if (inputMode) { // If we are in input mode
if (key >= '0' && key <= '9') { // Check if the key is a digit
weightInput += key; // Append the digit to weightInput
lcd.print(key); // Display the digit
}
else if (key == '#') { // If '#' is pressed (Backspace functionality)
if (weightInput.length() > 0) {
weightInput.remove(weightInput.length() - 1); // Remove the last character
lcd.clear();
lcd.print("Enter Control:");
lcd.setCursor(0, 1); // Move to the second line
lcd.print(weightInput); // Display the updated weight input
}
}
else if (key == 'D') { // If 'D' is pressed to confirm calibration
inputMode = false; // Exit input mode
calibrationWeight = weightInput.toFloat(); // Convert input to float
// Calculate the offset based on the current potentiometer reading
calibrationOffset = currentWeight - calibrationWeight;
// Save the calibrated value to EEPROM
EEPROM.put(CALIBRATION_ADDR, calibrationWeight);
lcd.clear();
lcd.print("Calibrated to: ");
lcd.setCursor(0, 1);
lcd.print(calibrationWeight); // Display the calibration weight
delay(2000); // Show confirmation for 2 seconds
lcd.clear(); // Clear the display
lcd.print("Weight:"); // Prompt for weight input
}
}
}
// Get current weight reading based on potentiometer
currentWeight = analogRead(potPin); // Read potentiometer value
currentWeight = map(currentWeight, 0, 1023, 0, 1000); // Map to 0-1000 kg
// Apply the calibration offset to the weight reading
float displayedWeight = currentWeight - calibrationOffset;
// Update the weight display on LCD when not in input mode
if (!inputMode && !alarmSuppressed) {
lcd.setCursor(0, 1);
lcd.print("Weight: ");
lcd.setCursor(0, 8);
lcd.print(displayedWeight, 2); // Display weight with 2 decimal places
lcd.print(" kg");
delay(500); // Update every half second
}
// Buzzer logic, if alarm is not suppressed
if (!alarmSuppressed && (displayedWeight < 50 || displayedWeight > 950)) { // If weight is out of range
if (!buzzerActive) {
buzzerActive = true; // Activate buzzer
buzzerStartTime = millis(); // Record the time buzzer started
alarmRegistered = false; // Reset alarm registration for each new trigger
}
// Toggle buzzer ON and OFF for 1 second intervals
if ((millis() - buzzerStartTime) % 2000 < 1000) {
digitalWrite(buzzerPin, HIGH); // Turn on the buzzer for 1 second
} else {
digitalWrite(buzzerPin, LOW); // Turn off the buzzer for 1 second
}
// If buzzer has been active for more than 5 seconds, register alarm and display message
if (millis() - buzzerStartTime >= 5000 && !alarmRegistered) {
lcd.clear();
lcd.print("Alarm Registered!");
alarmRegistered = true; // Mark the alarm as registered
delay(2000); // Display message for 2 seconds
lcd.clear();
lcd.print("Weight:"); // Return to normal weight display
}
// If buzzer has been active for more than 5 seconds, reset
if (millis() - buzzerStartTime >= 5000) {
buzzerActive = false; // Deactivate buzzer
digitalWrite(buzzerPin, LOW); // Make sure buzzer is off
}
}
else if (!alarmSuppressed) { // If weight is within the acceptable range
digitalWrite(buzzerPin, LOW); // Turn off the buzzer
buzzerActive = false; // Reset buzzer flag
alarmRegistered = false; // Reset the alarm registration once weight is back in range
}
// Print to Serial Monitor for debugging
Serial.print("Current Weight: ");
Serial.println(displayedWeight);
}