#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define IR_PIN 33
#define BUZZER_PIN 32
#define FAN_RELAY_PIN 25
#define LIGHT_RELAY_PIN 26
#define BUTTON_UP_PIN 14
#define BUTTON_DOWN_PIN 12
LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address to 0x27 for a 16x2 display
int productCount = 0;
int maxProducts = 10; // Default maximum products allowed
unsigned long buzzerStartTime = 0;
bool buzzerOn = false;
bool buzzerTriggered = false; // New flag to track if the buzzer has already been triggered
// States for input transition detection
bool irState = LOW;
bool lastIrState = LOW;
// Button states
bool buttonUpState = HIGH;
bool lastButtonUpState = HIGH;
bool buttonDownState = HIGH;
bool lastButtonDownState = HIGH;
// Timer for IR state
unsigned long irLowStartTime = 0;
bool irWasLow = false; // Track if IR was previously low
bool exitout = false;
void setup() {
Serial.begin(115200); // Start serial communication for debugging
pinMode(IR_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(FAN_RELAY_PIN, OUTPUT);
pinMode(LIGHT_RELAY_PIN, OUTPUT);
pinMode(BUTTON_UP_PIN, INPUT_PULLUP);
pinMode(BUTTON_DOWN_PIN, INPUT_PULLUP);
digitalWrite(FAN_RELAY_PIN, LOW); // Initially fan is off
digitalWrite(LIGHT_RELAY_PIN, LOW); // Initially light is off
digitalWrite(BUZZER_PIN, LOW); // Initially buzzer is off
lcd.init();
lcd.backlight();
updateDisplay();
Serial.println("Setup complete. Initial state:");
Serial.print("Product Count: "); Serial.println(productCount);
Serial.print("Max Products: "); Serial.println(maxProducts);
}
void loop() {
handleProductCounting();
handleMaxProductAdjustment();
handleUtilitiesControl();
handleBuzzer();
}
void handleProductCounting() {
irState = digitalRead(IR_PIN); // Read IR sensor state
// Detect transition from LOW to HIGH (product passing through)
if (irState != lastIrState) {
if (irState == HIGH) {
Serial.println("IR detected obstruction (HIGH).");
if (productCount < maxProducts && !exitout) {
productCount++;
Serial.print("Product count increased: "); Serial.println(productCount);
updateDisplay();
}
if (productCount > 0 && exitout) {
productCount--; // Decrease count after 10 seconds of being LOW
Serial.print("Product count decreased (exitout): "); Serial.println(productCount);
updateDisplay();
if (productCount == 0) {
exitout = false;
}
}
// Reset the low timer since we detected obstruction
irWasLow = false;
} else { // irState is LOW
Serial.println("IR detected no obstruction (LOW), starting timer.");
irLowStartTime = millis(); // Start the timer for low state
irWasLow = true;
for(int ii = 0; ii < 2; ii++) {
tone(BUZZER_PIN, 1000);
delay(100);
noTone(BUZZER_PIN);
delay(100);
}
}
lastIrState = irState; // Update last IR state
}
// Check if IR has been LOW for 10 seconds
if (irWasLow && (millis() - irLowStartTime >= 10000)) {
Serial.println("IR has been LOW for 10 seconds, enabling exitout.");
exitout = true;
irWasLow = false; // Reset low state tracking
}
}
void handleMaxProductAdjustment() {
buttonUpState = digitalRead(BUTTON_UP_PIN);
buttonDownState = digitalRead(BUTTON_DOWN_PIN);
// Detect button press (transition from HIGH to LOW)
if (buttonUpState != lastButtonUpState && buttonUpState == LOW) {
maxProducts++;
Serial.print("Max products increased: "); Serial.println(maxProducts);
updateDisplay();
lastButtonUpState = buttonUpState; // Update last button up state
}
if (buttonDownState != lastButtonDownState && buttonDownState == LOW && maxProducts > 1) {
maxProducts--;
Serial.print("Max products decreased: "); Serial.println(maxProducts);
updateDisplay();
lastButtonDownState = buttonDownState; // Update last button down state
}
// Update states for debouncing purposes
lastButtonUpState = buttonUpState;
lastButtonDownState = buttonDownState;
}
void handleUtilitiesControl() {
if (productCount > 0) {
digitalWrite(FAN_RELAY_PIN, HIGH); // Turn on fan
digitalWrite(LIGHT_RELAY_PIN, HIGH); // Turn on light
} else {
digitalWrite(FAN_RELAY_PIN, LOW); // Turn off fan
digitalWrite(LIGHT_RELAY_PIN, LOW); // Turn off light
}
}
void handleBuzzer() {
if (productCount >= maxProducts && !buzzerTriggered) {
buzzerOn = true;
buzzerTriggered = true; // Set buzzerTriggered to true to avoid re-triggering
buzzerStartTime = millis();
tone(BUZZER_PIN, 1000);
Serial.println("Buzzer ON (max products reached).");
}
if (buzzerOn && millis() - buzzerStartTime >= 2000) {
buzzerOn = false;
noTone(BUZZER_PIN);
Serial.println("Buzzer OFF (2 seconds passed).");
}
// Reset the buzzer trigger if product count goes below maxProducts
if (productCount < maxProducts) {
buzzerTriggered = false;
}
}
void updateDisplay() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Count: ");
lcd.print(productCount);
lcd.setCursor(0, 1);
lcd.print("Max: ");
lcd.print(maxProducts);
// Debug output for the display
Serial.print("LCD Update - Products: "); Serial.print(productCount);
Serial.print(", Max Products: "); Serial.println(maxProducts);
}