The classic first "real" build: a car-style distance sensor. Green means clear, yellow means you're getting close (with the beep speeding up as you do), red plus a continuous tone means stop. One sensor, three LEDs, a buzzer, and no libraries.
Verification: the wiring below is the app's audited table, and the sketch's pins are checked against it automatically. The four zones are green >100 cm · yellow 100–40 cm · red 40–20 cm · continuous tone <20 cm. It has not yet been run on physical hardware — build it, tell us it works via support@infinitxlabs.com, and we'll credit you here.
tone(), so either works)| From | To (UNO) | Notes |
|---|---|---|
| HC-SR04 VCC | 5V | 5 V sensor — happy on the UNO |
| HC-SR04 GND | GND | |
| HC-SR04 TRIG | D9 | |
| HC-SR04 ECHO | D10 | Direct is fine on a 5 V board. On 3.3 V boards (ESP32/Pico) use a voltage divider. |
| Green LED (+) | D2 | via 220 Ω, cathode to GND. 150–470 Ω all work. |
| Yellow LED (+) | D3 | via 220 Ω, cathode to GND |
| Red LED (+) | D4 | via 220 Ω, cathode to GND |
| Buzzer (+) | D5 | active or passive — the sketch uses tone(), so either works |
| Buzzer (−) | GND |
Every pin on this page is the same one the Robot Maker Toolkit app shows for this
project — not by hand, but because the app's build script refuses to publish unless the
sketch.ino and diagram.json served here are byte-for-byte the app's own
(build_projects.py --site). The HC-SR04 pins (TRIG→D9, ECHO→D10) come from the
app's audited module table.
Try the whole build before you buy a single part — no login, nothing to install:
Those two files are the ones the Robot Maker Toolkit app ships for this project, byte for byte — what you simulate is what the app tells you to wire.
pulseIn() times the echo. Distance = time × speed of sound ÷ 2.millis() schedule rather than with delay(), so distance keeps updating while it beeps — the difference between a sensor that reacts and one that feels stuck.pulseIn() stalls the loop for a full second whenever nothing is in front of the sensor./*
Parking sensor — Robot Maker Toolkit
Arduino UNO + HC-SR04 + 3 LEDs + buzzer
Distance drives a traffic light and a beep that speeds up as you close in,
exactly like a car's reversing sensor.
Pins follow the HC-SR04 page in the app (TRIG D9, ECHO D10).
Zones:
> 100 cm green, silent
40 - 100 cm yellow, slow beep
20 - 40 cm red, fast beep
< 20 cm red, solid tone (STOP)
*/
const int TRIG_PIN = 9;
const int ECHO_PIN = 10;
const int LED_GREEN = 2;
const int LED_YELLOW = 3;
const int LED_RED = 4;
const int BUZZER_PIN = 5;
// 25 ms ~= 4.3 m. Caps how long pulseIn() can stall the loop when nothing
// is in front of the sensor; without a timeout it blocks for a full second.
const unsigned long ECHO_TIMEOUT_US = 25000UL;
const float ZONE_STOP_CM = 20.0;
const float ZONE_CLOSE_CM = 40.0;
const float ZONE_NEAR_CM = 100.0;
unsigned long lastBeepToggle = 0;
bool beepOn = false;
void setup() {
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_YELLOW, OUTPUT);
pinMode(LED_RED, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
Serial.begin(9600);
}
// One reading, in cm. Returns -1 when nothing echoes back in time.
float readDistanceCm() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
unsigned long us = pulseIn(ECHO_PIN, HIGH, ECHO_TIMEOUT_US);
if (us == 0) return -1.0;
// 343 m/s = 0.0343 cm/us, halved because the pulse travels there and back.
return (us * 0.0343) / 2.0;
}
// Median of three. A single HC-SR04 reading occasionally returns a wild
// value off a soft or angled surface; the median throws those away without
// the lag that averaging adds.
float readDistanceStable() {
float a = readDistanceCm();
delay(15);
float b = readDistanceCm();
delay(15);
float c = readDistanceCm();
if (a < 0 || b < 0 || c < 0) return -1.0;
float hi = max(a, max(b, c));
float lo = min(a, min(b, c));
return a + b + c - hi - lo;
}
void showZone(int green, int yellow, int red) {
digitalWrite(LED_GREEN, green);
digitalWrite(LED_YELLOW, yellow);
digitalWrite(LED_RED, red);
}
// Non-blocking beep: toggles on its own schedule so distance keeps updating.
// interval 0 = silent, -1 = solid tone.
void updateBuzzer(long interval) {
if (interval == 0) {
noTone(BUZZER_PIN);
beepOn = false;
return;
}
if (interval < 0) {
tone(BUZZER_PIN, 2000);
beepOn = true;
return;
}
if (millis() - lastBeepToggle >= (unsigned long)interval) {
lastBeepToggle = millis();
beepOn = !beepOn;
if (beepOn) tone(BUZZER_PIN, 2000); else noTone(BUZZER_PIN);
}
}
void loop() {
float cm = readDistanceStable();
if (cm < 0) {
// Out of range or no echo — treat as clear.
showZone(HIGH, LOW, LOW);
updateBuzzer(0);
Serial.println("no echo");
} else if (cm > ZONE_NEAR_CM) {
showZone(HIGH, LOW, LOW);
updateBuzzer(0);
} else if (cm > ZONE_CLOSE_CM) {
showZone(LOW, HIGH, LOW);
updateBuzzer(400);
} else if (cm > ZONE_STOP_CM) {
showZone(LOW, LOW, HIGH);
updateBuzzer(120);
} else {
showZone(LOW, LOW, HIGH);
updateBuzzer(-1);
}
if (cm >= 0) {
Serial.print(cm, 1);
Serial.println(" cm");
}
delay(50);
}
{
"version": 1,
"author": "Infinitx Labs",
"editor": "wokwi",
"parts": [
{ "type": "wokwi-arduino-uno", "id": "uno", "top": 130, "left": 0, "attrs": {} },
{ "type": "wokwi-hc-sr04", "id": "dist", "top": -60, "left": 100, "attrs": { "distance": "80" } },
{ "type": "wokwi-led", "id": "ledGreen", "top": 20, "left": 320, "attrs": { "color": "green" } },
{ "type": "wokwi-led", "id": "ledYellow", "top": 20, "left": 370, "attrs": { "color": "yellow" } },
{ "type": "wokwi-led", "id": "ledRed", "top": 20, "left": 420, "attrs": { "color": "red" } },
{ "type": "wokwi-resistor", "id": "rGreen", "top": 120, "left": 320, "attrs": { "value": "220" } },
{ "type": "wokwi-resistor", "id": "rYellow", "top": 160, "left": 370, "attrs": { "value": "220" } },
{ "type": "wokwi-resistor", "id": "rRed", "top": 200, "left": 420, "attrs": { "value": "220" } },
{ "type": "wokwi-buzzer", "id": "buzzer", "top": 20, "left": 200, "attrs": { "volume": "0.1" } }
],
"connections": [
[ "dist:VCC", "uno:5V", "red", [] ],
[ "dist:GND", "uno:GND.1", "black", [] ],
[ "dist:TRIG", "uno:9", "blue", [] ],
[ "dist:ECHO", "uno:10", "purple", [] ],
[ "uno:2", "rGreen:1", "green", [] ],
[ "rGreen:2", "ledGreen:A", "green", [] ],
[ "ledGreen:C", "uno:GND.2", "black", [] ],
[ "uno:3", "rYellow:1", "gold", [] ],
[ "rYellow:2", "ledYellow:A", "gold", [] ],
[ "ledYellow:C", "uno:GND.2", "black", [] ],
[ "uno:4", "rRed:1", "red", [] ],
[ "rRed:2", "ledRed:A", "red", [] ],
[ "ledRed:C", "uno:GND.2", "black", [] ],
[ "uno:5", "buzzer:1", "orange", [] ],
[ "buzzer:2", "uno:GND.3", "black", [] ]
]
}
Want the full reference on your bench? 55+ sensor wiring diagrams, 9 board pinouts, shield maps and maker calculators — all offline.
Get it onGoogle Play