Touchless Hand Sanitizer Dispenser
Contact-free dispensing with a fixed pump time
Aim
To dispense a fixed quantity of sanitizer automatically when a hand is detected, without the user touching the dispenser.
Overview
An IR obstacle sensor (or ultrasonic sensor) detects when a hand is placed under the nozzle. On detection, the Arduino activates a small DC pump through a transistor/relay for a fixed duration (e.g. 2 seconds) and then locks out for a short idle time so one hand motion produces exactly one dose. A status LED shows when the pump is running.
Components Required
- Arduino Uno
- IR obstacle avoidance sensor module (or HC-SR04)
- 5V DC peristaltic pump
- NPN transistor (TIP120/2N2222) or relay module + flyback diode
- Green LED + 220 ohm resistor (pump indicator)
- Breadboard and jumper wires
Circuit Connections
| From | To | Note |
|---|---|---|
| IR sensor VCC | Arduino 5V | - |
| IR sensor GND | Arduino GND | - |
| IR sensor OUT | Arduino D2 | LOW when an object is detected (most modules) |
| Transistor base (via 1k) | Arduino D8 | Switches the pump |
| Pump + | External 5V | - |
| Pump - | Transistor collector, emitter to GND | - |
| LED anode (via 220R) | Arduino D9 | - |
| LED cathode | Arduino GND | - |
Interactive Circuit Diagram
Simulate the circuit: adjust the sensor inputs below and watch the outputs react according to the control logic.
Loading Wokwi components...
Working
- The Arduino continuously polls the IR sensor output.
- When a hand is detected and the system is idle, the pump is switched ON.
- The pump stays ON for PUMP_TIME (fixed dose time).
- After dispensing, a LOCKOUT time ignores new detections so one hand motion gives one dose.
- The indicator LED is ON exactly while the pump runs.
Control Logic
IF (hand detected) AND (state == IDLE): run pump for PUMP_TIME, then enter LOCKOUT for 1 s. The lockout prevents repeated dosing when the hand lingers under the sensor.
Arduino Code
1// Practical 4: Touchless Hand Sanitizer Dispenser2const int IR_PIN = 2; // IR sensor output (LOW = hand detected)3const int PUMP_PIN = 8; // Transistor / relay driving the pump4const int LED_PIN = 9; // Pump status LED56const unsigned long PUMP_TIME = 2000; // ms - fixed dose duration7const unsigned long LOCKOUT = 1000; // ms - ignore hands after dosing89enum State { IDLE, DISPENSING, WAIT };10State state = IDLE;11unsigned long stateStart = 0;1213void pumpOn() {14 digitalWrite(PUMP_PIN, HIGH);15 digitalWrite(LED_PIN, HIGH);16}1718void pumpOff() {19 digitalWrite(PUMP_PIN, LOW);20 digitalWrite(LED_PIN, LOW);21}2223void setup() {24 pinMode(IR_PIN, INPUT);25 pinMode(PUMP_PIN, OUTPUT);26 pinMode(LED_PIN, OUTPUT);27 Serial.begin(9600);28}2930void loop() {31 bool handDetected = digitalRead(IR_PIN) == LOW;32 unsigned long now = millis();3334 switch (state) {35 case IDLE:36 if (handDetected) { // Hand under the nozzle37 state = DISPENSING;38 stateStart = now;39 pumpOn();40 Serial.println("HAND -> PUMP ON");41 }42 break;4344 case DISPENSING:45 if (now - stateStart >= PUMP_TIME) { // Dose complete46 pumpOff();47 state = WAIT;48 stateStart = now;49 Serial.println("DOSE DONE -> LOCKOUT");50 }51 break;5253 case WAIT:54 if (now - stateStart >= LOCKOUT) {55 state = IDLE;56 }57 break;58 }59}