IoT lab viva notes

Tavish Gupta, 23BCP064

Experiment 3: servo motor, relay and the siren design

Two actuator problems a designer meets constantly: “move to an exact position and stay there” (servo) and “let a small logic signal switch a different circuit safely” (relay). Plus the siren, which in your file is a design described in words.

Objective

Servo
Command an SG90 to 90°, 180° and 0° in a repeating sequence, one second apart, from an ESP32.
Relay
Switch an LED, wired as a separate load, on and off every second through a relay module.
Siren
Design a police siren: two alternating tones on a buzzer with red and blue lights alternating in step.
Learn
open-loop vs closed-loop actuation, PWM as a command signal, why loads need drivers, and electrical isolation.

System

ESP32loop(): fixed sequenceSG90 servoGPIO 32: 50 Hz pulse trainRelay moduleGPIO 25: HIGH or LOWLED loadown circuitCOM to NO
The ESP32 never powers either load directly: the servo has its own driver inside, and the relay module has a transistor and a separate contact circuit.

Design decisions

A servo, not a plain DC motor

Why
The task is “go to an angle and hold it”. A servo closes the loop internally: a potentiometer on the output shaft feeds back the actual angle, and its controller drives the motor until it matches the command. The microcontroller only sends the target.
Alternative
DC motor (just spins; position needs an encoder and your own control loop) or a stepper (moves in exact steps open-loop, holds with current).
Switch when
Continuous rotation: DC motor. Precise repeatable positions without feedback, many turns: stepper.

ESP32Servo library

Why
The standard Servo.h uses AVR timers that the ESP32 does not have. ESP32Servo drives the ESP32’s LEDC PWM hardware behind the same attach()/write() API.
Alternative
Configure LEDC directly: 50 Hz, e.g. 16-bit resolution, duty computed from the pulse width.
Switch when
When you need custom pulse limits or many servos with precise timing.

Servo powered from 5 V, signal from 3.3 V GPIO

Why
The SG90 motor needs 5 V; its signal input accepts a 3.3 V logic pulse. One small unloaded servo is within what USB 5 V can supply.
Alternative
A separate 5 V supply with grounds joined.
Switch when
More than one servo, or any load on the horn: stall current can reach hundreds of mA and brown out the ESP32.

Relay module, not a bare relay

Why
A coil needs tens of mA at 5 V and produces a reverse voltage spike when switched off. The module has a transistor to drive the coil and a flyback diode to absorb the spike, so a GPIO can drive its IN pin directly.
Alternative
A transistor or MOSFET switching the load directly; a solid-state relay.
Switch when
MOSFET for DC loads and fast or frequent switching (PWM). SSR for silent AC switching. Mechanical relay when you need isolation and any AC/DC load at low switching rates.

Load on COM and NO

Why
NO (normally open) means the load is off when the coil is unpowered, including when the board is off or resetting. That is the safe default.
Alternative
COM and NC: load on by default, off when energised.
Switch when
Use NC when the load must stay on if the controller dies (for example a fail-safe lock that must stay powered).

Passive buzzer for the siren

Why
A siren needs two pitches. A passive buzzer plays whatever frequency you generate with tone(); an active one has a fixed pitch.
Alternative
A small speaker with a transistor driver for more volume.
Switch when
Loudness matters.

What we did

  1. Installed the ESP32 board package and the ESP32Servo library.

    The ESP32 is not an AVR board: it needs its own compiler, core and a servo library that targets its PWM hardware.

  2. Wired the servo: brown to GND, red to 5 V, orange signal to GPIO 32.

    Power and ground for the motor, and one control line. Reversing red and brown damages the servo.

  3. Uploaded the servo sketch; opened the Serial Monitor at 115200.

    115200 is the ESP32 convention and matches its boot log, so both show cleanly.

  4. Observed 90° → 180° → 0° each second, and pushed the horn gently.

    Resistance to a push shows the internal feedback loop is holding position.

  5. Wired the relay module: VCC 5 V, GND, IN to GPIO 25; load: 5 V to COM, NO to LED via 220 Ω, LED to GND.

    Control side and load side are wired as two separate circuits; the contact closes the load circuit.

  6. Uploaded the relay sketch; listened for the click and watched the LED.

    The click is the armature moving; the LED proves the contact closes the load circuit.

Servo: principle, circuit, code

Command signal: a pulse every 20 ms (50 Hz). Only the pulse width carries information. The SG90 datasheet gives roughly 1 ms to 2 ms; ESP32Servo by default maps 0° to 180° onto 544 µs to 2400 µs (the classic Arduino Servo range). write(angle) computes 544 + angle × (2400 − 544) / 180.

0°544 µs90°1472 µs180°2400 µs 20 ms = 50 Hz frame (pulse widths drawn to scale)
Three commands drawn to scale against the 20 ms frame.
180°0°90°
90 degrees is about 1472 microseconds.
Servo circuit.
Servo circuit.
  • The servo’s three-wire plug: brown (GND, black wire to the ESP32 GND), red (5 V, red wire to the 5 V pin), orange (signal, green wire to GPIO 32).
  • No other parts: the servo contains its own motor driver.

Servo sweep on ESP32

22 lines, exactly as in your lab file

#include <ESP32Servo.h> Servo myServo;int servoPin = 32; void setup() {    Serial.begin(115200);    Serial.println("Hello, ESP32!");     myServo.attach(servoPin);} void loop() {    myServo.write(90);    delay(1000);     myServo.write(180);    delay(1000);     myServo.write(0);    delay(1000);}
  1. Line 1
    Servo API on top of the ESP32’s LEDC PWM.
  2. Line 3
    Object holding the pin, channel and pulse limits.
  3. Line 4
    Any output-capable GPIO works; 32 is free of boot-strapping duties.
  4. Lines 7 to 8
    Banner after the ESP32’s own boot log.
  5. Line 10
    Allocates a PWM channel at 50 Hz on GPIO 32 and starts the pulse train. From here the hardware repeats the pulse on its own; the CPU only changes its width.
  6. Lines 14 to 15
    Set width ≈ 1472 µs and wait. write() returns at once; the delay is what gives the servo time to physically move (an SG90 needs roughly 0.1 s per 60° unloaded).
  7. Lines 17 to 18
    ≈ 2400 µs.
  8. Lines 20 to 21
    ≈ 544 µs. Then the loop repeats.
Servo on hardware.
Servo on hardware.
  • The SG90 on the bench wired by jumper leads to the ESP32 on the breadboard.
  • The horn position in a photo is one moment of the sweep; motion is confirmed by observation, not by the still.

Relay: principle, circuit, code

Control side (low voltage) IN ← GPIO 25VCC ← 5 VGND transistor+ flyback diodedrives the coil, clamps its spike Contact side (isolated) COMNONC coil ON: COM joins NO (solid line)coil OFF: COM rests on NC magnet
Coil side and contact side share no conductor; the magnetic field is the only link.

That separation is galvanic isolation: the 3.3 V logic and the load can be at completely different voltages, even mains, with no electrical path between them. The price: the relay is mechanical, so it is slow (milliseconds), audible, and its contacts wear out after a finite number of operations.

Relay circuit.
Relay circuit.
  • Module control pins: VCC to 5 V, GND, IN to GPIO 25 (green wire).
  • Load side: the red wire feeds COM from 5 V; NO goes through the resistor to the LED, LED to GND.
  • Trace the load loop: 5 V → COM → (contact) → NO → resistor → LED → GND. The loop is open until the coil pulls the contact.

Relay switching an LED

16 lines, exactly as in your lab file

int relayPin = 25; void setup() {    Serial.begin(115200);    Serial.println("Hello, ESP32!");     pinMode(relayPin, OUTPUT);} void loop() {    digitalWrite(relayPin, HIGH);    delay(1000);     digitalWrite(relayPin, LOW);    delay(1000);}
  1. Line 1
    Module IN on GPIO 25.
  2. Line 7
    The pin drives the module’s input stage, not the coil directly.
  3. Lines 11 to 12
    HIGH energises this module (active-high): COM connects to NO, LED on, click.
  4. Lines 14 to 15
    LOW releases: spring returns COM to NC, LED off. The flyback diode absorbs the coil’s spike at this moment.
Relay simulation, energised.
Relay simulation, energised.
  • The LED is lit while the relay is energised: the contact has closed the load circuit.
  • The serial pane shows the ESP32 boot log (load addresses, entry point) followed by Hello, ESP32!: proof the sketch started after reset.

The siren design

In your file the siren is a design: a passive buzzer, a red LED and a blue LED (each with 220 Ω) on three digital pins, common ground. Behaviour: low tone (about 440 Hz) with red on for 0.5 s, then high tone (about 880 Hz) with blue on for 0.5 s, repeated.

00.5 s1.0 s1.5 s2.0 s red LED, ~440 Hzred LED, ~440 Hzblue LED, ~880 Hzblue LED, ~880 Hz highlow
The specified timing: two states alternating every 0.5 s.
  • It is a two-state machine driven by time: state A (red, low tone) and state B (blue, high tone), switching every 500 ms.
  • tone(pin, f) generates a 50 % duty square wave at f Hz using a hardware timer, so the CPU is free while it plays; noTone(pin) stops it.
  • 880 Hz is exactly double 440 Hz (one octave), so the two states are clearly distinguishable.
  • A sweeping “wail” would step the frequency up and down instead of jumping between two values.

Limits and redesign

  • Servo power: under load an SG90 can pull enough current to reset the ESP32 via USB. Separate 5 V supply, common ground, and a capacitor across the servo supply.
  • Servo speed: write() jumps instantly; for smooth motion step the angle in small increments with short waits (non-blocking with millis()).
  • Relay rate: fine for once a second; for PWM or frequent switching use a MOSFET.

Say this in the viva

Viva questions

Why

Why can’t a GPIO drive a relay coil directly?

The coil needs more current than a pin can supply, and switching it off produces a reverse voltage spike that can destroy the pin. The module’s transistor supplies the current and its flyback diode clamps the spike.

Why is the load on NO and not NC?

So the load is off by default whenever the controller is off, resetting or crashed.

Why does the servo hold its position against a push?

Its internal controller compares the commanded angle with the feedback potentiometer and drives the motor to correct any error.

What if

What if you call write(90) and write(180) with no delay between?

The second command replaces the first before the servo moves: it heads straight to 180°.

What if the relay module is active-low?

HIGH turns it off and LOW on; the LED would be on when the code intends off, and on during boot.

What if you power three servos from the ESP32’s 5 V pin?

Their combined current, especially at stall, can drop the supply and reset the board. Use a separate supply with common ground.

Design

A fan must be switched on above 30 °C. Relay or MOSFET?

For a small DC fan, a logic-level MOSFET: silent, fast, and it allows PWM speed control. For a mains fan, a relay or SSR for isolation.

How would you make a robotic arm joint hold position under load?

A higher-torque servo with its own supply, or a motor with an encoder and your own PID loop if you need more precision than a hobby servo gives.