ESP32 Automated Industrial Counter & Runtime Tracker Complete Hardware Setup, Circuit Wiring, Source Code & Operational Guide 1. Project Overview This project presents an automated, non-contact industrial object counter and machine runtime monitor designed around the high-performance ESP32 microcontroller . Using a laser diode aligned with a Photoresistor (LDR) sensor, the system accurately detects passing objects by registering light interruption events. The system tracks both real-time total production count and operational machine runtime displayed on a 16x2 I2C LCD screen with zero processing lag. 2. Components & Tools Required COMPONENT NAME SPECIFICATION / TYPE QTY PRIMARY ROLE ESP32 Development Board 38-Pin DOIT ESP32 DevKit V1 1 Main Microcontroller Unit (MCU) LDR Sensor / Module 5mm Light Dependent Resistor 1 Light level detection (Photoresistor) Laser Diode Module 5V 650nm Red Dot Laser (5mW) 1 Focus light beam emitter 16x2 LCD Display HD44780 with PCF8574 I2C Adapter 1 Displays count & live running time Resistor 10kΩ (for LDR) & 220Ω (for LED) 2 Pull-down / Current limiting Indicator LED 5mm Red / Green LED 1 Visual pulse indicator on object detection Breadboard & Jumper Wires Full-size MB-102 & Male-to-Female Wire set 1 Set Prototyping circuit connections 5V Power Supply Micro-USB Cable / 5V 2A Adapter 1 System power supply TOOLS REQUIRED PURPOSE / DESCRIPTION Soldering Iron & Solder Wire For permanent header pin soldering on sensors/modules Multimeter For verifying voltage levels, continuity, and resistance thresholds Wire Stripper & Cutter Preparing custom jumper wires and connections Arduino IDE / PlatformIO Programming and flashing code to the ESP32 ESP32 Industrial Counter Report Page 1 of 4 3. Circuit Wiring & Connections 4. Working Principle & Operating Procedure 5. Complete Embedded C++ Source Code #include <Wire.h> #include <LiquidCrystal_I2C.h> #define LDR_PIN 34 // Analog pin connected to Photoresistor (LDR) #define LED_PIN 4 // Digital pin connected to Indicator LED // Initialize LCD (Address 0x27, 16 Cols, 2 Rows) LiquidCrystal_I2C lcd(0x27, 16, 2); const int DARK_THRESHOLD = 1200; // Threshold for object detection int count = 0; bool itemDetected = false; COMPONENT PIN ESP32 BOARD PIN SIGNAL TYPE / DESCRIPTION I2C LCD - SDA GPIO 21 I2C Data Communication Line I2C LCD - SCL GPIO 22 I2C Clock Line I2C LCD - VCC / GND VIN (5V) / GND Power supply for LCD Module LDR Signal Pin GPIO 34 (ADC1_CH6) Analog Voltage Input from LDR Divider LED Anode (+) GPIO 4 (via 220Ω resistor) Digital Output for Detection Pulse LED Cathode (-) GND Ground Connection Laser VCC / GND 5V / GND Continuous 5V power supply to Laser Module 1 System Startup & Calibration: Upon power-up, ESP32 initializes GPIOs, configures I2C at 400kHz Fast Mode, and prints baseline labels ("Count: 0", "Time: 00:00:00") on the LCD. 2 Laser Beam Alignment: The laser diode continuously shines a focused beam directly onto the photoresistor (LDR). Under constant light illumination, LDR resistance remains low and output voltage stays high. 3 Light Interruption (Object Pass): When an object passes through the chute, it blocks the laser beam. The sudden drop in light causes the LDR resistance to spike, dropping the analog voltage below DARK_THRESHOLD (1200). 4 Pulse Trigger & Non-blocking Timer: ESP32 instantly registers the dark state, increments the total count by +1, blinks the indicator LED, and updates the LCD display without interrupting the 1-second background runtime clock. ESP32 Industrial Counter Report Page 2 of 4 unsigned long startMillis = 0; unsigned long lastSensorRead = 0; int lastPrintedSecond = -1; String formatTwoDigits(int number) { if (number < 10) return "0" + String(number); return String(number); } void setup() { Serial.begin(115200); pinMode(LDR_PIN, INPUT); pinMode(LED_PIN, OUTPUT); // Quick startup LED flash digitalWrite(LED_PIN, HIGH); delay(300); digitalWrite(LED_PIN, LOW); // Set I2C Communication Speed to 400kHz (Fast Mode) Wire.begin(21, 22); Wire.setClock(400000); lcd.init(); lcd.backlight(); // Draw static interface UI lcd.setCursor(0, 0); lcd.print("Count: 0"); lcd.setCursor(0, 1); lcd.print("Time : 00:00:00"); startMillis = millis(); } void loop() { unsigned long currentMillis = millis(); // 1. Fast Sensor Reading (Every 15ms) if (currentMillis - lastSensorRead >= 15) { lastSensorRead = currentMillis; int ldrValue = analogRead(LDR_PIN); // Object Blocks Laser (Dark State) if (ldrValue < DARK_THRESHOLD && !itemDetected) { count++; itemDetected = true; digitalWrite(LED_PIN, HIGH); lcd.setCursor(7, 0); lcd.print(count); lcd.print(" "); } // Object Passes (Light Restored) else if (ldrValue > (DARK_THRESHOLD + 200) && itemDetected) { itemDetected = false; digitalWrite(LED_PIN, LOW); } } // 2. Real-Time Seconds Timer Calculation unsigned long elapsedTimeSec = (currentMillis - startMillis) / 1000; int seconds = elapsedTimeSec % 60; if (seconds != lastPrintedSecond) { lastPrintedSecond = seconds; ESP32 Industrial Counter Report Page 3 of 4 int hours = elapsedTimeSec / 3600; int minutes = (elapsedTimeSec % 3600) / 60; String timeString = formatTwoDigits(hours) + ":" + formatTwoDigits(minutes) + ":" + formatTwoDigits(seconds); lcd.setCursor(7, 1); lcd.print(timeString); } } 6. Key Benefits & Real-World Use Cases 🏭 Industrial Production & Conveyor Belts Deploys seamlessly on injection molding chutes or bottling lines to automatically log manufactured units, eliminating human tallying errors. ⏱️ Overall Equipment Effectiveness (OEE) Monitoring Tracks active machine uptime alongside production counts, enabling plant managers to identify idle periods and optimize efficiency. 📦 Batch Packaging & Dispatch Systems Integrates into shipping docks or carton packing lines to automatically notify workers when a target quantity (e.g., 50 or 100 units) is reached. ⚡ Low-Cost Non-Contact Automation Utilizes affordable components to build a robust, wear-free optical counting solution with minimal maintenance requirements. ESP32 Industrial Counter Report Page 4 of 4