Smart trash can: ultrasonic on 8 and 7, servo lid on 9, on an Arduino Uno
An HC-SR04 with TRIG on pin 8 and ECHO on 7 watches for a hand; closer than 20 cm and the servo on pin 9 swings the lid open, then closes it a moment after the hand has gone. The whole build, an Arduino Uno and 2 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
Teaching? Assign it to your class in one click.
Intermediate About 20 minutes to build and run. Runs in your browser. Free, and no account needed.
The parts retail for about $36. On Mokxi they're free.
What you'll learn
- Measuring distance with ultrasound
- Timing a pulse with pulseIn
- Controlling a servo with the Servo library
- Using millis for a delay without stopping the sketch
- Difficulty: Intermediate
- Time: About 20 minutes
- Board: Arduino Uno R3
- Parts: 4
How it works
An HC-SR04 ultrasonic sensor watches for a hand. The Uno pulses TRIG on pin 8, the sensor sends a burst of sound, and ECHO on pin 7 stays HIGH until the echo returns. About 58 microseconds means 1 centimeter.
When something is closer than OPEN_CM, 20 cm, the servo on pin 9 turns the lid to the open angle of 0 degrees. When nothing has been there for a second, the lid goes back to 90 degrees, closed.
Drag the distance slider under 20 cm to wave a hand.
Parts list
4 parts, plus the jumper wires. They retail for about $36; on Mokxi they're free.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × Half breadboard
- 1 × Ultrasonic rangerIn Halloween Prop Kit.
- 1 × Hobby servoIn Halloween Prop Kit, Christmas Lights Kit, Starter Projects Kit.
Kits that can build it
These 9 starter kits have every part in the circuit. Each kit's page lists what else it can build.
Wiring table
Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.
| Part and pin | Connects to |
|---|---|
| Ultrasonic ranger pin GND | Arduino Uno R3 pin GND |
| Hobby servo pin GND | Arduino Uno R3 pin GND |
| Hobby servo pin PWM | Arduino Uno R3 pin 9 |
| Ultrasonic ranger pin TRIG | Arduino Uno R3 pin 8 |
| Ultrasonic ranger pin ECHO | Arduino Uno R3 pin 7 |
| Ultrasonic ranger pin VCC | Arduino Uno R3 pin 5V |
| Hobby servo pin VCC | Arduino Uno R3 pin 5V |
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// A smart trash can: wave a hand over it and the lid opens.
//
// HC-SR04 VCC -> 5V TRIG -> pin 8 ECHO -> pin 7 GND -> GND
// servo signal -> pin 9 red -> 5V brown -> GND
//
// The sensor sends a burst of sound when TRIG is pulsed, and ECHO stays HIGH
// until the echo comes back: about 58 microseconds for every centimeter. When
// something is closer than OPEN_CM, the servo turns to the open angle; once
// nothing has been there for a second, it closes again.
//
// Drag the distance slider on the sensor below 20 cm.
#include <Servo.h>
const int TRIG = 8;
const int ECHO = 7;
const int SERVO_PIN = 9;
const int OPEN_ANGLE = 0;
const int CLOSED_ANGLE = 90;
const int OPEN_CM = 20;
Servo lid;
unsigned long lastSeen = 0;
bool open = false;
long distanceCm() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
long echo = pulseIn(ECHO, HIGH, 30000UL);
return echo / 58;
}
void setup() {
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
lid.attach(SERVO_PIN);
lid.write(CLOSED_ANGLE);
Serial.begin(9600);
Serial.println("Mokxi Uno: smart trash can, sensor on 8 and 7, lid on 9");
}
void loop() {
long cm = distanceCm();
if (cm > 0 && cm < OPEN_CM) {
lastSeen = millis();
if (!open) {
lid.write(OPEN_ANGLE);
open = true;
Serial.println("hand seen: lid open");
}
} else if (open && millis() - lastSeen > 1000) {
lid.write(CLOSED_ANGLE);
open = false;
Serial.println("lid closed");
}
delay(100);
}
Code walkthrough
The key functions of the sketch, and what each one does.
distanceCm sketch.ino
Triggers a measurement. It holds TRIG LOW for 2 microseconds, HIGH for 10, then LOW. pulseIn times how long ECHO stays HIGH, with a 30000 microsecond timeout. Dividing by 58 turns the time into centimeters. A timeout returns 0.
long distanceCm() {
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
long echo = pulseIn(ECHO, HIGH, 30000UL);
return echo / 58;
}setup sketch.ino
Sets TRIG as an output and ECHO as an input, attaches the servo to pin 9 and closes the lid at CLOSED_ANGLE. It opens serial at 9600 baud.
void setup() {
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
lid.attach(SERVO_PIN);
lid.write(CLOSED_ANGLE);
Serial.begin(9600);
Serial.println("Mokxi Uno: smart trash can, sensor on 8 and 7, lid on 9");
}loop sketch.ino
Measures once. If the distance is above 0 and under OPEN_CM, it records the time in lastSeen and opens the lid if it was closed. If the lid is open and a second has passed since lastSeen, it closes it. Then it waits 100 ms.
void loop() {
long cm = distanceCm();
if (cm > 0 && cm < OPEN_CM) {
lastSeen = millis();
if (!open) {
lid.write(OPEN_ANGLE);
open = true;
Serial.println("hand seen: lid open");
}
} else if (open && millis() - lastSeen > 1000) {
lid.write(CLOSED_ANGLE);
open = false;
Serial.println("lid closed");
}
delay(100);
}Troubleshooting
The usual mistakes with this circuit, and the fix for each.
- The lid never opens This project
A reading of 0 means no echo came back. Check TRIG is on pin 8 and ECHO on pin 7. - The lid opens the wrong way This project
SwapOPEN_ANGLEandCLOSED_ANGLE, or turn the servo horn. - Distance reads zero, or never changes. Ultrasonic ranger
Power it from 5 V and share ground. Send a 10 microsecond HIGH pulse on TRIG, then time ECHO with pulseIn. Check TRIG and ECHO are not swapped. - Readings jump around or are wrong on a 3.3 V board. Ultrasonic ranger
ECHO outputs 5 V, so divide it down for 3.3 V boards. Aim at flat, hard surfaces. The range is about 2 cm to 4 m, and soft or angled targets bounce the sound away. - The servo jitters, twitches or resets the board when it moves. Hobby servo
Power it from its own 5 V supply, not the Arduino 5 V pin, and join the grounds. A hobby servo can pull several hundred milliamps. Add a 100 uF to 470 uF capacitor across its supply. - The servo hums at the end of its travel or will not reach full angle. Hobby servo
Stay inside the pulse range, about 1000 to 2000 us for most hobby servos. Pushing past the end stop makes it strain. Calibrate the min and max pulse for your servo. - Upload fails or nothing runs after wiring pins 0 and 1 to a module. Arduino Uno R3
Pins 0 and 1 are the USB serial port. Move the module to other pins, or unplug it while uploading. Also check the right board is selected. - Pins misbehave or the board resets when you power motors or servos from it. Arduino Uno R3
Each I/O pin gives about 20 mA, 40 mA max. Power motors and servos from their own supply and join its ground to the Uno's GND.
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.