IoT lab viva notes

Tavish Gupta, 23BCP064

Foundations: the building blocks and the choices between them

Eight experiments, but only a handful of ideas underneath. Each idea is a choice you make when designing a device; this page is about what the options are and what each costs.

The execution model: a superloop

There is no operating system scheduling your program on the UNO. The Arduino core supplies main(), which calls init() (sets up timers, ADC), then your setup() once, then your loop() inside for (;;) forever. That shape is called a superloop: one thread, one infinite loop, all work done by polling inside it.

Power on or reset setup()runs once loop()runs again and again foreverpinMode, Serial.begin
setup() initialises state and peripherals; loop() is the body of an infinite loop the core owns.
  • State lives in global variables (they persist across loop() calls) or in the hardware itself (an output pin keeps its level until written again).
  • Each pass of loop() is: read inputs, decide, write outputs, maybe communicate. Every sketch in your file has this shape; reading a sketch means identifying those four parts.
  • On the ESP32, the same setup()/loop() API runs inside a FreeRTOS task, and Wi-Fi and Bluetooth run in other tasks. You still write a superloop, but the radio stacks work in the background.
  • Consequence: anything that blocks inside loop() stops everything else in your program. That is the main source of limits in your lab code (see Timing below).

A pin is an interface with rules

Think of a GPIO pin as a 1-bit port to the outside world with a direction. pinMode(pin, OUTPUT) makes the chip drive the wire; INPUT makes it only listen. The software side is trivial. The constraints are physical, and they are what you design around:

RuleWhat it means for designWhere it shows up
Logic levelUNO/MEGA pins are 5 V; ESP32 pins are 3.3 V and are not 5 V tolerant. A 5 V signal into an ESP32 needs a divider or level shifter.Exp 3 to 8 on ESP32; HC-05 RX divider; SIM800L RX divider
Current budgetA pin can supply about 20 mA safely (ATmega). LEDs need a series resistor; motors, relays and coils need a driver.every LED has 220 Ω; relay module has a transistor
Common groundA voltage only means something relative to a reference. Two devices that exchange signals must share GND.GSM on its own supply, servo on 5 V
Defined input levelAn unconnected input floats and reads noise. Pull it to a known level with a resistor (external, or the chip’s internal pull-up).Exp 1 button pull-down
Power budgetSome loads need far more current than USB or a regulator gives: servo stall, GSM transmit bursts (~2 A).Exp 3, Exp 7
Arduinopin 13 = 5 V 220 Ω GND 3 V across it≈ 2 V (red LED) Ohm’s law, V = I × RI = (5 − 2) / 220I ≈ 0.0136 A = 13.6 mAsafe: pin limit about 20 mA
The one calculation you should be able to do anywhere: series resistor for an LED. (5 − 2) V / 220 Ω ≈ 13.6 mA.
5 V button pin 2 (INPUT) 10 kΩ pull-down Released: pin pulled to GNDdigitalRead → LOW Pressed: pin connected to 5 VdigitalRead → HIGH
A button gives you a short or an open circuit, never a voltage. The resistor turns “open” into a defined LOW.

How information is encoded on a wire

Almost every sensor or actuator in this lab moves information in one of a few encodings. Recognising the encoding tells you which API you need.

EncodingCarriesRead or write withIn your lab
Level (digital)1 bit: HIGH or LOWdigitalRead() / digitalWrite()LED, button, relay, LDR module DO, active buzzer
Voltage (analog)a value on a continuous scaleanalogRead() through the ADCpotentiometer wiper
Duty cycle (PWM)a fraction 0 to 1, as on-time per periodanalogWrite(), LEDC on ESP32LED brightness
Pulse widtha number carried in how long a pulse lastspulseIn(); libraries generate or decode itHC-SR04 echo, servo command, DHT bits
Frequencya value carried in how often the signal repeatstone()siren tones
Serial bytesarbitrary data, one bit at a time at an agreed rateSerial, SoftwareSerial, SerialBTSerial Monitor, GSM AT commands, Bluetooth

Analog in: quantisation

An ADC maps a voltage onto an integer. With n bits over a reference voltage Vref, the step size is Vref / 2ⁿ. The UNO/MEGA ADC is 10-bit over 5 V: 1024 codes, about 4.9 mV per step. The ESP32’s is 12-bit (0 to 4095) over roughly 3.3 V. More bits means finer steps, not better accuracy: noise and the reference still limit you.

input voltage 0 to 5 V10230 analogRead() on Arduino: 10 bits2¹⁰ = 1024 steps, 0 … 1023one step = 5 / 1024 ≈ 4.9 mVESP32: 12 bits, 0 … 4095, 3.3 Vreal ADCs have more, smaller steps
Voltage in, integer out. Every analogRead() is this mapping.

Analog out: PWM

The UNO cannot output 2.5 V. It switches the pin fully on and off at a fixed frequency and varies the fraction of each period it is on. Anything slow compared with the switching (an eye looking at an LED, a motor’s inertia, an RC filter) sees the average: duty × 5 V. analogWrite(pin, v) takes v from 0 to 255 (8-bit duty). Most UNO/MEGA PWM pins run near 490 Hz.

5 V0 V
Move the slider to see the duty cycle.

Timing models: blocking, polling, interrupts

In a superloop the central design question is: what does the CPU do while it waits? Your lab code always picks the simplest answer, blocking. Knowing the alternatives is what lets you explain its limits.

ModelHow it worksCostIn your lab
Blockingcall a function that waits: delay(1000), pulseIn(), while (!connected)nothing else runs while waitingeverywhere: every sketch uses delay()
Polling with time checkseach loop pass compares millis() with a saved timestamp and acts when duemore code; loop must run oftennot used; it is the usual fix
Interruptshardware calls a short function the instant an event happens (pin change, timer)shared state needs care; handlers must be tinyused inside libraries (SoftwareSerial, Servo timing), not in your code
Callbacks from a libraryyou register a function; the library calls it from its own processingyou must keep calling the library’s updateExp 8: onLedPinChange() via ArduinoCloud.update()
RTOS tasksindependent threads scheduled by FreeRTOSsynchronisation, memory per taskESP32 radio stacks run this way under your sketch

Experiments 1, 5, 6, 7 and 8 move the same tiny payload, “LED on” or “LED off”, over five different links. Comparing them is the most useful design exercise in the lab.

USB serial (Exp 1)Bluetooth SPP (Exp 5)Wi-Fi + HTTP (Exp 6)GSM SMS/call (Exp 7)MQTT via cloud (Exp 8)
Topologypoint to point, wiredpoint to point, pairedclient to server on a LANdevice to phone via operatordevice and app both clients of a broker
Addressingthe COM portBluetooth address, paired nameIP address and port 80phone numberdevice ID; topics/variables
Data unitbytesbytesHTTP request/response textSMS text up to 160 charactersMQTT messages
Reliabilityreliable at short rangereliable link layerTCP: reliable, orderedstore and forward by the networkTCP plus MQTT acknowledgements
Rangecableabout 10 mone networkanywhere with 2G coverageanywhere with internet
Security in your codephysical accesspairing onlynone (plain HTTP)SIM and phone numberTLS plus device credentials
Who starts the connectionPCphonebrowser connects in to the deviceeither sidedevice connects out to the broker
Board ATXRXGND Board BRXTXGND TX goes to RX, both ways One byte, 8N1 (8 data bits, no parity, 1 stop bit) start8 data bitsstop 9600 baud ≈ 960 bytes per secondboth sides must use the same baud rate
UART underlies three of these: USB serial, the GSM module, and (emulated) Bluetooth SPP.

Interaction patterns

Polling versus event-driven

Why
Polling (check every loop) is simple and deterministic, and is what Exp 1 to 7 do. Event-driven code reacts only when something changes, and is what Exp 8’s callback does.
Alternative
Interrupts for hardware events; callbacks for library events.
Switch when
Switch to events when inputs are rare and the CPU should sleep, or when you must not miss a short event.

Request-response versus publish-subscribe

Why
Exp 6 is request-response: the browser asks, the ESP32 answers. Exp 8 is publish-subscribe: changes are pushed through a broker to whoever subscribed.
Alternative
Request-response is simpler to reason about; pub/sub decouples senders from receivers and scales to many.
Switch when
Use pub/sub when many devices or many viewers share state, or when the device cannot accept inbound connections.

Device as server versus device as client

Why
In Exp 6 the ESP32 listens on port 80, so the controller must reach it. Behind a home router (NAT) nothing on the internet can, without port forwarding. In Exp 8 the ESP32 makes an outbound connection to the cloud, which NAT allows, and keeps it open.
Alternative
Port forwarding or a VPN to keep the server model.
Switch when
Any device that must be controlled from outside its network should be a client of a broker or cloud.

Decide at the edge versus in the cloud

Why
Exp 2 and 4 decide on the device (threshold in code): instant and works offline. Exp 8 lets a person decide in the cloud dashboard.
Alternative
Send raw readings up and decide in the cloud.
Switch when
Keep safety and real-time decisions at the edge; move decisions that need history, many devices, or a human to the cloud.

What the libraries hide

LibraryWhat you callWhat it does for you
Arduino coredigitalWrite, analogRead, delay, Serialregister access, ADC sequencing, timers for millis/PWM, UART buffers and interrupts
DHT (Adafruit)readHumidity()the single-wire timing protocol, 40-bit decode, checksum, NaN on failure
ESP32Servoattach(), write(angle)configures an LEDC PWM channel at 50 Hz and converts angle to pulse width
BluetoothSerialSerialBT.read()the Bluetooth Classic stack, pairing, SPP/RFCOMM channel
WiFiWiFi.begin(), WiFiServerassociation, DHCP, the TCP/IP stack (lwIP), sockets
SoftwareSerialsim.println()a UART implemented in software on ordinary pins, timed by the CPU
ArduinoIoTCloudArduinoCloud.update()TLS connection, MQTT, property sync, reconnects, callbacks

In a viva, “what does this library do internally?” is answered from this table: name the protocol or hardware it manages and the problem that would be yours without it.

Toolchain and debugging

  • Build: the IDE compiles C++ with the board’s toolchain (avr-gcc for UNO/MEGA, the Xtensa toolchain for ESP32) and links the core and libraries.
  • Upload: a small bootloader on the chip receives the program over USB serial and writes it to flash. Wrong board or port means a failed upload; on some ESP32 boards you hold BOOT to enter download mode.
  • Observe: the Serial Monitor is the only window into a running sketch. Every sketch in your file prints something at start; seeing it proves upload, reset and baud rate are right.
  • Simulate: your circuit screenshots come from a simulator (the Wokwi interface). It is good for logic and wiring, but it does not model power limits, noise or a module’s real polarity. That is why some hardware photos differ from the simulation.

Viva questions

Why

Why do setup() and loop() exist instead of main()?

The core owns main(): it initialises the hardware, calls your setup() once, then calls loop() forever. This gives a fixed superloop structure, so a sketch only describes initialisation and the repeated body.

Why is the ESP32 used for experiments 3 to 8?

It has Wi-Fi and Bluetooth on chip, a faster dual-core CPU and more memory. The UNO would need extra modules plus 5 V to 3.3 V level shifting.

Why does every LED have a resistor but the relay has a module?

An LED only needs its current limited (a resistor). A relay coil needs more current than a pin can give and produces a voltage spike when switched off, so it needs a transistor and a flyback diode, which the module provides.

What if

What if two boards exchange serial data but do not share ground?

Each measures the signal against its own reference, so the levels are undefined: garbage data or no communication. Ground must be common.

What if you connect a 5 V sensor output straight to an ESP32 input?

You exceed the pin’s rating; it may work for a while or damage the pin. Divide it down or use a level shifter.

What if your loop() contains a 10-second delay?

Nothing else happens for 10 s: inputs are missed, serial input piles up in the buffer, and on Exp 8 the cloud connection is not serviced.

Design

How would you control a device in your home from a phone on mobile data?

Make the device a client of a cloud or MQTT broker (outbound connection, works behind NAT), as in Exp 8; not a server on the LAN as in Exp 6.

Polling or interrupts for a button?

Polling is fine if loop() runs often and nothing blocks. Use an interrupt if the loop has long blocking calls or the CPU sleeps, and debounce in either case.