This workshop takes you from zero Arduino experience to building a real sensor-controlled mechanical system. Each session builds on the last, introducing new concepts through hands-on circuit construction.
| # | Start | Session | Duration | Key Concepts |
|---|---|---|---|---|
| 0 | 0:00 | Introduction & Setup | 15 min | IDE, board anatomy, first upload |
| 1 | 0:15 | Basic LED Blink | 20 min | pinMode, digitalWrite, delay |
| 2 | 0:35 | LED Pulse & Multi-Blink | 25 min | PWM, analogWrite, millis() |
| 3 | 1:00 | Single Traffic Light | 30 min | Sequencing, helper functions |
| 4 | 1:30 | Two-Way Traffic Lights | 45 min | Coordination, safety logic |
| 5 | 2:15 | Ultrasonic Sensor + Servo Gate | 45 min | Sensors, Servo lib, map(), constrain() |
| — | 3:00 | Wrap-Up & Challenges | open | Extensions & Q&A |
| Component | Spec | Qty | Purpose |
|---|---|---|---|
| Arduino Uno | Rev 3 or compatible clone | 1 | Microcontroller brain |
| USB Cable | Type-A to Type-B | 1 | Programming & power |
| Breadboard | Full or half size (830/400 tie) | 1 | Prototype circuits without soldering |
| Jumper Wires | Male-to-Male mixed colours | 20+ | All circuit connections |
| LEDs | Red × 2, Amber × 2, Green × 2 | 6 | Traffic light outputs |
| LEDs | Any colour (status/alert) | 2 | Sensor & gate indicators |
| Resistors | 220Ω (Red-Red-Brown) | 8 | Current limiting for LEDs |
| HC-SR04 Sensor | Ultrasonic distance module | 1 | Session 5 — distance input |
| Servo Motor | SG90 or MG90S (5V hobby) | 1 | Session 5 — mechanical output |
| Laptop + Arduino IDE | v1.8+ or v2.x | 1 | Code editor & uploader |
Tools → Board → Arduino Uno and select your COM port under Tools → Port.
Arduino is an open-source electronics platform that combines a simple microcontroller board with easy-to-use software. The Arduino Uno uses an ATmega328P processor running at 16 MHz with 32KB of flash memory.
| Part | Description |
|---|---|
USB Port | Connects to laptop for programming and provides 5V power |
Digital Pins 0–13 | Can be INPUT or OUTPUT; pins marked ~ support PWM |
Analogue Pins A0–A5 | Read voltages from 0V to 5V as numbers 0–1023 |
5V & 3.3V Pins | Regulated power output for sensors and components |
GND Pins | Ground (negative/return) — connect all component GNDs here |
RESET Button | Restarts your sketch from the beginning |
PWM Pins (~) | Pins 3, 5, 6, 9, 10, 11 — support analogWrite() |
Every Arduino program (called a sketch) must have exactly these two functions:
Connect Arduino to your laptop via USB cable
Open Arduino IDE → Tools → Board → Arduino Uno
Select your port: Tools → Port → COM3 (Windows) or /dev/ttyUSB0 (Linux/Mac)
Click the ✓ Verify button to compile your code — fix any errors shown
Click the → Upload arrow — the TX/RX LEDs will flash as code transfers
"Done uploading" = success! Your sketch is now running on the board
| Component | Value | Qty | Purpose |
|---|---|---|---|
| LED | Any colour | 1 | Our output — lights up! |
| Resistor | 220Ω (Red-Red-Brown) | 1 | Limits current to protect LED & pin |
| Jumper wires | Male-to-Male | 2 | Pin 13 to circuit; GND to circuit |
- Arduino
Pin 13→ 220Ω resistor (one leg) - Resistor (other leg) → LED long leg (anode +)
- LED short leg (cathode −) → Arduino
GNDpin
- The LED on Pin 13 blinks once per second (on 1s, off 1s)
- The built-in 'L' LED on the board also blinks — it shares Pin 13
- Open
Tools → Serial Monitor(Ctrl+Shift+M) to see LED ON / LED OFF messages
Change delay(1000) to delay(500) — twice as fast
Try delay(100) — it starts to look like a flicker, not a blink. Why?
Make the ON time and OFF time different (e.g. 200ms on, 800ms off)
Add a second LED on Pin 12 with its own resistor — make it blink at a different rate
Most Arduino pins are strictly digital — fully ON (5V) or fully OFF (0V). Pulse Width Modulation (PWM) creates the illusion of in-between brightness levels by rapidly switching the pin on and off. Your eye blurs the fast switching into a perceived brightness.
~: pins 3, 5, 6, 9, 10, and 11 only. Calling analogWrite() on a non-PWM pin won't work as expected.
This introduces millis() — the professional way to handle multiple simultaneous timings without freezing the Arduino.
delay() freezes everything — the Arduino can't read sensors, check buttons, or do anything else while it waits. millis() asks "has enough time passed?" without stopping. This is how real-world Arduino projects handle multiple concurrent tasks.
| Component | Value | Qty | Pin |
|---|---|---|---|
| Red LED | 5mm Red | 1 | Pin 4 |
| Amber LED | 5mm Yellow | 1 | Pin 5 |
| Green LED | 5mm Green | 1 | Pin 6 |
| Resistors | 220Ω each | 3 | One per LED |
Two independent sets of traffic lights that coordinate — when Road A is green, Road B is red. They are never both green simultaneously.
| Road | Colour | Arduino Pin | Resistor |
|---|---|---|---|
| Road A | Red | Pin 2 | 220Ω |
| Road A | Amber | Pin 3 | 220Ω |
| Road A | Green | Pin 4 | 220Ω |
| Road B | Red | Pin 7 | 220Ω |
| Road B | Amber | Pin 8 | 220Ω |
| Road B | Green | Pin 9 | 220Ω |
The HC-SR04 measures distance using the same principle as a bat's echolocation. It fires an inaudible 40kHz ultrasound burst and times how long the echo takes to return. Distance = (pulse duration × speed of sound) ÷ 2.
| HC-SR04 Pin | Connect to | Direction |
|---|---|---|
VCC | Arduino 5V pin | Power in |
GND | Arduino GND pin | Ground |
TRIG | Arduino Pin 11 | OUT — we send pulses |
ECHO | Arduino Pin 12 | IN — we listen for echo |
A servo contains a DC motor, gearbox, and position sensor — all in one small package. You control the exact angle (0°–180°) with a simple command. The Arduino Servo library handles all the PWM timing automatically.
- Brown or Black wire → Arduino
GND - Red wire → Arduino
5V - Orange or Yellow (signal) wire → Arduino
Pin 9
This combines everything. The HC-SR04 measures distance and the servo opens a gate proportionally — more open the closer the object gets. Two LEDs show gate status.
- HC-SR04: VCC→5V, GND→GND, TRIG→Pin 11, ECHO→Pin 12
- Servo: Red→5V, Brown/Black→GND, Signal→Pin 9
- Red LED: Pin 5 → 220Ω → Red LED → GND (gate closed indicator)
- Green LED: Pin 6 → 220Ω → Green LED → GND (gate open indicator)
Finished early? These challenges deepen your understanding, roughly ordered by difficulty.
SOS Blinker
Blink an SOS pattern using short (200ms) and long (600ms) flashes: · · · — — — · · ·
Speed Control Button
Make the traffic lights change timing with a button — short press = fast mode, long press = normal
Amber Buzzer
Add a passive buzzer on Pin 7 that beeps during the AMBER phase of the traffic light sequence
Distance Bar
Display ultrasonic distance as 5 LEDs that light up as an object gets progressively closer
Pedestrian Crossing
Add a button to the two-way lights for a pedestrian crossing mode — vehicles stop, pedestrian green LED lights for 5 seconds
Servo Speedometer
Map a potentiometer (0–1023) to servo angle (0°–180°) to create an analogue gauge needle
Smart Traffic Lights
Use the ultrasonic sensor to detect waiting vehicles and automatically extend the green phase
Parking Sensor
Build a parking sensor: Green = far, Amber = medium, Red = close, with a buzzer that beeps faster as you approach
State Machine Traffic Lights
Implement the traffic light as a proper state machine using enum and switch/case — no delay-based sequencing
Object Counter
Mount two HC-SR04 sensors facing each other to count objects that pass between them
LCD Distance Display
Connect an I2C 16×2 LCD display to show live distance reading and gate status from Sketch 7
Servo Smoothing
Modify Sketch 7 to use a running average of the last 5 distance readings to eliminate servo jitter
| Function / Concept | What it Does | Used in |
|---|---|---|
| pinMode(pin, mode) | Sets a pin as INPUT or OUTPUT | All |
| digitalWrite(pin, val) | Sends HIGH (5V) or LOW (0V) to a digital pin | 1,3,4,5,7 |
| delay(ms) | Pauses everything for N milliseconds | 1,2a,3,4 |
| analogWrite(pin, 0-255) | Sends a PWM signal — creates brightness levels | 2a |
| millis() | Returns milliseconds since power-on — non-blocking timer | 2b |
| Serial.begin(baud) | Starts Serial communication at given baud rate | All |
| Serial.println() | Sends text + newline to the Serial Monitor | All |
| Custom functions | Reusable named blocks of code (void myFunc()) | 3,4,5,7 |
| pulseIn(pin, HIGH) | Measures how long a pin stays HIGH — used for echo timing | 5,7 |
| delayMicroseconds(µs) | Pauses for N microseconds — finer than delay() | 5,7 |
| Servo.attach(pin) | Links Servo object to a physical PWM pin | 6,7 |
| servo.write(angle) | Moves servo to exact angle 0°–180° | 6,7 |
| map(val,fL,fH,tL,tH) | Scales a value from one range to another | 7 |
| constrain(val,min,max) | Clamps a value within min/max — prevents overflows | 7 |
| for (init;cond;incr) | Repeating loop with counter — used for fades and sweeps | 2a,6 |
| unsigned long | Large integer type for millis() timestamps (0 to ~50 days) | 2b |
| bool | true / false variable — tracks binary state | 2b,7 |
| #include <Servo.h> | Loads the built-in Servo library — no installation needed | 6,7 |
arduino.cc/reference has documentation for every Arduino function. Tinkercad Circuits lets you simulate Arduino circuits in your browser. Falstad Circuit Simulator is excellent for visualising PWM and timing circuits.