Fab Academy 2026  ·  Week 04

Embedded
Programming

This week I explored the world of embedded programming — microcontrollers, datasheets, and how to develop software that controls physical hardware. I compared development boards, learned to read datasheets, and wrote programs to interact with sensors and actuators using the ESP32.

ESP32 Arduino IDE Microcontrollers Datasheets GPIO Sensors
Datasheet Class Raspberry Pi Pico ESP32 Pinout

Group Assignment

  1. Demonstrate and compare toolchains for embedded architectures

Individual Assignment

  1. Browse microcontroller datasheet
  2. Write and test a program with input/output devices

Key Tools

  • Arduino IDE
  • Datasheets
  • ESP32 DevKit V4
01
Theory

What is Embedded Programming?

Embedded programming is the process of developing software that directly controls physical hardware, especially microcontrollers. An embedded system consists of three main components:

🔍 Sensors

Capture information from the environment (temperature, light, pressure, motion)

🧠 Microcontroller

Processes sensor data and makes decisions based on program logic

⚙️ Actuators

Execute actions controlled by the microcontroller (motors, LEDs, buzzers)

What are Microcontrollers?

A microcontroller is a complete system on a single chip. It includes:

  • Flash Memory — stores your program permanently
  • RAM — temporary memory during execution
  • EEPROM — permanent data storage that survives power cycles
  • Peripherals — ADC, Timers, GPIO, UART, I2C, SPI, and more

Microcontrollers only understand binary. We write code in C, C++, or MicroPython, and the compiler translates it to machine code that the microcontroller executes.

02
Group Assignment

Development Board Comparison & Analysis

My Contribution to the Group Assignment

For the group assignment, I worked hands-on with multiple development boards in the Fab Lab, comparing their performance characteristics, ease of use, and suitability for embedded programming. I tested datasheets, investigated microcontroller specifications, and evaluated which boards best suit different application scenarios. The group assignment focused on understanding the toolchains available for different embedded architectures and their practical implications.

If you want to see the complete Group Assignment, visit the official Fab Academy page: Visit Fab Academy ULima  →
📖 Learning to Read Datasheets

Our instructor gave us a quick lesson on reading microcontroller datasheets using the Raspberry Pi Pico 2W as an example. We learned how to interpret pinout diagrams, identify pin functions, and understand the specifications of different development boards.

Instructor explaining datasheet

A datasheet is the "contract" between a chip manufacturer and the engineer using it. It specifies:

  • Pinout Diagram — which pin does what
  • Electrical Characteristics — voltage, current, timing specs
  • Memory Map — where code and data go
  • Peripheral Descriptions — how to use ADC, timers, communication protocols
  • Absolute Maximum Ratings — don't exceed these or you destroy the chip
The Six Development Boards — Detailed Comparison

We tested and documented six different development boards to understand their strengths, weaknesses, and ideal applications. Each represents a different category of embedded systems design.

Board 1: Raspberry Pi Pico 2 W

Raspberry Pi Pico 2W board

Raspberry Pi Pico 2W

Raspberry Pi Pico 2W pinout

Pinout Diagram

The Raspberry Pi Pico 2 W is a development board with integrated WiFi, allowing use in IoT projects. It operates at 3.3V and includes a voltage regulator that steps down 5V USB power. Its GPIO pins can be configured as digital inputs or outputs. It supports SPI, I2C, and UART communication protocols and features integrated WiFi and Bluetooth Low Energy connectivity.

FeatureSpecification
Main MCURP2350 (ARM Cortex-M33 dual-core)
Clock SpeedUp to 150 MHz
Flash / RAM4 MB Flash / 520 KB SRAM
Digital GPIOUp to 30 programmable pins
ADC12-bit (3 channels)
WirelessWiFi + Bluetooth (CYW43439)

Board 2: Arduino UNO R4 WiFi

Arduino UNO R4 WiFi board

Arduino UNO R4 WiFi

Arduino UNO R4 WiFi pinout

Pinout Diagram

The Arduino UNO R4 WiFi is an upgraded version of the classic UNO platform. It integrates a powerful 32-bit ARM Cortex-M4 microcontroller and an ESP32-S3 WiFi/Bluetooth module. It operates at 5V logic level for backward compatibility with Arduino shields and provides extensive connectivity options for IoT applications.

FeatureSpecification
Main MCUR7FA4M1AB3CFM#AA0 (ARM Cortex-M4)
Flash / SRAM256 kB Flash / 32 kB SRAM
Digital Pins14
ADC14-bit
WirelessWiFi + BLE 5 (via ESP32-S3)
SpecialCAN Bus, DAC (12-bit)

Board 3: Arduino UNO R3

Arduino UNO R3 board

Arduino UNO R3

Arduino UNO R3 pinout

Pinout Diagram

The Arduino UNO R3 is one of the most popular development boards for learning embedded systems. It uses the ATmega328P 8-bit AVR microcontroller and is widely used in education and beginner projects. It provides a simple and accessible way to understand how hardware and software interact.

FeatureSpecification
Main MCUATmega328P (8-bit AVR)
Clock Speed16 MHz
Flash / SRAM32 kB Flash / 2 kB SRAM
Digital Pins14
Analog Inputs6
PWM6 channels

Board 4: Seeeduino XIAO nRF52840

Seeeduino XIAO nRF52840 board

Seeeduino XIAO nRF52840

Seeeduino XIAO nRF52840 pinout

Pinout Diagram

The Seeeduino XIAO nRF52840 is a compact and powerful development board optimized for IoT and Bluetooth applications. Despite its small size, it integrates wireless communication and advanced low-power features, making it ideal for wearables and battery-powered devices.

FeatureSpecification
Main MCUnRF52840 (ARM Cortex-M4F)
Flash / RAM1 MB Flash / 256 kB RAM
Clock Speed64 MHz
Digital PinsUp to 14
BluetoothBLE 5.0
ADC12-bit

Board 5: ESP32 (ESP32-WROOM)

ESP32 development board

ESP32 Board

ESP32 pinout

Pinout Diagram

The ESP32 development board is designed for IoT and wireless applications with a powerful dual-core processor and built-in WiFi and Bluetooth. It operates at 3.3V logic level and is widely used for smart devices, home automation, and wireless control systems. It offers significantly higher processing speed and memory than traditional Arduino boards.

FeatureSpecification
Main MCUXtensa LX6 (dual-core)
Clock SpeedUp to 240 MHz
Flash / RAM~4 MB Flash / 520 kB SRAM
Digital GPIOUp to 34 pins
WirelessWiFi + Bluetooth Classic + BLE
ADC / DAC12-bit ADC / 2×8-bit DAC

Board 6: Arduino Nano

Arduino Nano board

Arduino Nano

Arduino Nano pinout

Pinout Diagram

The Arduino Nano offers similar functionality to the UNO but in a much smaller form factor. It uses the same ATmega328P microcontroller and is commonly used in compact or space-limited projects such as wearable devices or small embedded prototypes while maintaining the same programming experience.

FeatureSpecification
Main MCUATmega328P (8-bit AVR)
Clock Speed16 MHz
Flash / SRAM32 kB Flash / 2 kB SRAM
Digital Pins14
Analog Inputs8
Form FactorCompact, breadboard-friendly
Development Board Comparison Matrix

Side-by-side comparison of all six boards to help identify which is best for different applications:

Feature UNO R3 Nano UNO R4 ESP32 Pico 2 W XIAO
Architecture8-bit AVR8-bit AVR32-bit Cortex-M432-bit Xtensa (dual)32-bit Cortex-M33 (dual)32-bit Cortex-M4F
Clock Speed16 MHz16 MHz48 MHzUp to 240 MHzUp to 150 MHz64 MHz
Flash32 kB32 kB256 kB~4 MB4 MB1 MB
RAM2 kB2 kB32 kB520 kB520 kB256 kB
Digital Pins141414Up to 34Up to 30Up to 14
WiFiNoNoYes (2.4 GHz)Yes (2.4 GHz)Yes (2.4 GHz)No
BluetoothNoNoBLE 5Classic + BLEBLE 5.2BLE 5.0
Best ForEducation basicsCompact projectsIoT intermediateIoT advancedWiFi connectedWearables
✅ Final Decision for HigiBox: I chose the ESP32 DEVKIT V4 with the ESP-WROOM-32 processor. Its dual-core architecture (240 MHz), integrated WiFi and Bluetooth, and generous memory make it the most versatile for IoT projects with real-time processing requirements. The extensive GPIO count and built-in wireless eliminate the need for external modules, reducing complexity and cost.
03
Individual Setup

ESP32 Setup with Arduino IDE

Setting up the ESP32 with Arduino IDE requires several steps: installing the USB driver, configuring the IDE, and selecting the correct board and port.

Step 1 Install CP2102 Driver

Connect the ESP32 to your computer. If Device Manager shows a yellow warning, download and install the CP2102 driver from Silicon Labs.

Device Manager warning
Step 2 Download Arduino IDE

Download from arduino.cc/en/software

Step 3 Add ESP32 Board Manager URL

File → Preferences → Add this URL to "Additional boards manager URLs":

https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
Step 4 Install ESP32 Core

Tools → Board → Boards Manager → Search "esp32" and install "esp32 by Espressif Systems"

Step 5 Select Board & Port

Tools → Board → "ESP32 Dev Module"
Tools → Port → Select your COM port

✓ Your ESP32 is ready! Upload sketches and monitor results in the Serial Monitor.
03.5
Advanced Understanding

ESP32 — Complete Technical Investigation

This section is a comprehensive technical deep-dive into the ESP32 microcontroller, the heart of my HigiBox project. I chose to investigate one platform in depth rather than compare many, to truly understand its capabilities, limitations, and internal workings.

Why the ESP32?

The ESP32 is a system-on-chip (SoC) that integrates a powerful processor, memory, wireless radios, and extensive peripherals in a single chip. For HigiBox, it is ideal because:

🎯
Dual-Core Processing

Simultaneous WiFi/BT communication and dispenser control without blocking. Core 0 handles wireless; Core 1 manages real-time motor/sensor logic.

📡
Integrated Wireless

WiFi 802.11 b/g/n (2.4 GHz) + Bluetooth Classic + BLE. No separate modules needed. Reduces PCB footprint and cost.

Rich Peripheral Set

16 PWM channels, 12-bit ADC, I2C, SPI, UART, touch sensors, timers. Covers all HigiBox requirements without external glue logic.

💰
Cost-Effective

Development boards under $10. Production modules under $5. Ideal for consumer IoT devices and wearables.

Technical Specifications — ESP32 WROOM-32E

My board uses the ESP32-WROOM-32E, which is the standard production module. Below are the complete specifications:

Processor & Memory

ParameterValueNotes
CPUDual Xtensa 32-bit LX6Up to 160 MHz per core, configurable
Max Clock Speed240 MHz (turbo mode)Consumes more power; standard is 160 MHz
Flash Memory4 MB (embedded)Stores bootloader, app code, and calibration data
SRAM520 KBInternal RAM for heap, stack, and variables
PSRAM (Optional)Up to 16 MBExternal SPI RAM; ESP32-WROVER variant
RTC Memory8 KBSurvives deep sleep; useful for persistent state
I-Cache32 KBInstruction cache per core
D-Cache32 KBData cache per core

Power & Operating Conditions

ParameterMinTypicalMax
Operating Voltage2.3 V3.3 V3.6 V
Current — Idle10 mA
Current — WiFi TX160 mA240 mA
Current — Deep Sleep10 µA150 µA
Temp. Range-40 °C85 °C
🔋 Power Insight for HigiBox: Deep sleep at 10 µA means a 2000 mAh battery could power the device for ~8 years in deep sleep (very low background draw). WiFi transmission at 160–240 mA requires careful power budgeting — WiFi should only transmit alerts, not continuously.
GPIO & Peripheral Mapping

GPIO Pins (34 total available)

The ESP32 has 34 GPIO pins, but not all are equally suitable for every application. Some pins are reserved, strapping pins affect boot mode, and some have limited functionality:

📌
Input-Only Pins

GPIO34, GPIO35, GPIO36, GPIO39 — Can only be used as inputs (no output capability). Ideal for analog sensors or button inputs since they don't drive loads.

⚠️
Strapping Pins (Boot Configuration)

GPIO0, GPIO2, GPIO5, GPIO12, GPIO15 — Affect boot mode during startup. Pulling them to wrong levels can prevent the board from booting. Use with caution or avoid for application logic.

Peripheral Inventory

PeripheralCount/TypeHigiBox Usage
PWM (LED)16 channels @ 1–8 bitsControl motor speed (1 channel)
ADC2× 12-bit SAR ADC; ADC1 (8 ch), ADC2 (10 ch)Stock sensor on ADC1 (ADC2 conflicts with WiFi)
DAC2× 8-bitNot used; could drive analog circuit
I2C2× (I2C0, I2C1)OLED display connection
SPI3× (HSPI, VSPI, SPI3)Optional SD card logging
UART3× (UART0, UART1, UART2)UART0 for programming; UART1 for external sensors
Timers4× 64-bit timersMotor pulse timing, event scheduling
Touch Sensors10 capacitive touch channelsAlternative to mechanical buttons
CAN (TWAI)1× CAN 2.0BNot used; industrial applications
RMT8 channelsOptional: WS2812 RGB LED addressable control
💡 Critical for HigiBox: Use ADC1 exclusively for the stock sensor. ADC2 becomes unavailable when WiFi is active. SPI pins (GPIO12, GPIO13, GPIO14, GPIO15) are shared with flash memory on some boards — check your specific variant before using them.
Wireless Subsystem — WiFi & Bluetooth Architecture

WiFi (802.11 b/g/n @ 2.4 GHz)

  • Standards: 802.11 b (1, 2, 5.5, 11 Mbps) / g (6–54 Mbps) / n (up to 150 Mbps)
  • Modes: Station (STA), SoftAP (AP), Station+AP (concurrent)
  • Security: WEP, WPA, WPA2, WPA3 support
  • Typical Current: RX 80 mA, TX 160–240 mA (varies by power level)
  • Issue: Blocks ADC2 when active; cannot use ADC2 while WiFi transmitting

Bluetooth & BLE (2.4 GHz)

  • Classic Bluetooth: 2.1 with EDR (Enhanced Data Rate)
  • BLE: Bluetooth 4.2 compliant
  • Concurrent: WiFi + BT or WiFi + BLE simultaneously
  • BLE Current Draw: ~5–15 mA RX, ~15–30 mA TX (much lower than WiFi)
  • Ideal for HigiBox: BLE is preferred for mobile app (lower power, ideal for IoT)

RF Front-End

  • Antenna: Printed PCB antenna or external antenna connector on some modules
  • Transmit Power: Up to +20 dBm (100 mW) in standard mode
  • Receiver Sensitivity: Typical -95 dBm @ 11 Mbps (WiFi), -92 dBm @ 1 Mbps (BLE)
  • Range: Typically 30–50 meters indoors, up to 100 meters in optimal conditions
📡 For HigiBox Mobile App: Design BLE communication to be always-on with low-power advertisement. WiFi should only activate for critical log uploads or firmware updates, then immediately sleep. This maximizes battery life while maintaining responsiveness.
ESP32 Variants — Why I Chose WROOM-32E

Espressif produces multiple ESP32 variants. Understanding the differences is critical for production design:

Variant Flash PSRAM Size Best For
WROOM-32E 4 MB No 18×25.5 mm Standard IoT (my choice)
WROVER 4 MB 8 MB 18×31.4 mm Apps needing large buffers
WROOM-32U 4 MB No 18×25.5 mm Industrial, extended temp range
SOLO (ESP8266-like) 2/4 MB Smaller WiFi only, cost-critical
MINI 4 MB No 13×17 mm Compact wearables (HigiBox v2?)
✓ WROOM-32E Decision Rationale: Standard flash (4 MB) is adequate for HigiBox firmware + WiFi stack + BLE stack + OTA updates. No extra PSRAM needed. Mature, well-documented, widely available. Larger size (18×25.5 mm) allows hand-soldering during prototyping.
Boot Sequence & Sleep Modes

Boot Sequence (Power-On Reset)

  1. ROM Bootloader (Mask ROM): Always runs first, 128 KB fixed code burned at manufacturing. Checks strapping pins to determine boot mode.
  2. Strapping Pins Decision:
    • GPIO0=0, GPIO2=0 → Download mode (firmware upload from UART)
    • GPIO0=1 → Normal boot from flash
  3. Second-Stage Bootloader: Loads from flash address 0x1000. Initializes flash, loads partition table, verifies digital signatures if enabled.
  4. Partition Table: Defines flash layout (bootloader, partitions, NVS storage, SPIFFS filesystem if used)
  5. Application Load: bootloader copies your firmware from flash into RAM and jumps to entry point
  6. User Setup(): Your setup() function runs; WiFi stack initializes if enabled
  7. loop(): Main program execution begins
⚠️ Critical for HigiBox OTA Updates: Partition your flash with two app partitions (OTA_0 and OTA_1). This allows secure firmware updates—if update fails, the chip boots the previous version. Without this, a bad upload bricks the device.

Sleep Modes & Power States

Mode Current Draw Wake Time Use Case
Active (Normal) 60–160 mA Running application, WiFi/BLE active
Modem Sleep 20 mA Instant CPU running, WiFi/BT off (useful for quick tasks)
Light Sleep 0.8–10 mA ~6 ms CPU paused, timers/ADC running, can wake on GPIO interrupt
Deep Sleep 10–150 µA ~1 second Only RTC logic alive, ULP coprocessor, external trigger or timer
Hibernation 2.5 µA ~5 seconds Extreme power saving; minimal wake capability
🔋 Battery Strategy for HigiBox: Normal operation in light sleep between button presses (~0.8 mA). When pill dispensed, deep sleep for 23+ hours (~100 µA), waking at timer interrupt for stock checks and BLE advertisements. This approach extends a 2000 mAh battery to months.

ESP32 Internal Architecture — Block Diagram Mapping

Flash Cache
Maps flash into addressable memory space. Transparent access to SPI flash as if it were RAM. Critical for code execution speed.
SPI (3×)
SPI0/1 dedicated to flash/PSRAM. SPI2/3 available for external SPI devices. Max frequency 80 MHz user SPI.
I2C (2×)
400 kHz standard, 1 MHz fast mode. Perfect for sensors, displays, EEPROM. HigiBox uses for OLED.
UART (3×)
Up to 4.5 Mbps per port. UART0 reserved for debugging/programming. UART1/2 available for external devices.
PWM (16 ch)
LEDC controller. 1–8 bit resolution. Frequency 5 Hz–40 kHz. Perfect for motor speed control in HigiBox.
ADC1 (8 ch)
12-bit SAR ADC. Measures 0–3.3V. Use for stock sensors, battery voltage monitoring. No WiFi conflicts.
ADC2 (10 ch)
12-bit SAR ADC. CONFLICTS with WiFi when active. Avoid using when WiFi enabled. Only for WiFi-off scenarios.
Touch (10 ch)
Capacitive touch detection. No mechanical buttons needed. Could replace physical dispense button in HigiBox v2.
DAC (2×)
8-bit DAC outputs. 0–3.3V analog. Not used in current HigiBox design but available.
Timers (4×)
64-bit timers with prescalers. Used for motor activation timing, measuring sensor intervals, event scheduling.
Watchdog
Hardware watchdog. Resets chip if software hangs. Critical for unattended operation (medical device context).
Bluetooth Controller
Baseband processor for BT/BLE. Implements Link Layer state machine. Handles advertising, connections, encryption.
Bluetooth Host Stack (NimBLE)
Gap/GATT protocol implementation. Manages services, characteristics, notifications. Runs on CPU core 0 concurrently with user app.
WiFi MAC & Baseband
Hardware MAC implements 802.11 protocol, CSMA/CA collision avoidance, frame assembly/disassembly.
WiFi Stack (lwIP)
TCP/IP stack (IPv4, TCP, UDP). Handles IP addressing, socket creation, packet routing. Lightweight, optimized for embedded.
Dual-Core CPU (Xtensa LX6)
240 MHz (turbo) or 160 MHz (standard)

• Core 0: Runs WiFi/BT stack in real-time.
• Core 1: Runs user application logic.
• Shared L1 caches (32 KB I-cache, 32 KB D-cache per core).
• Independent operation allows simultaneous connectivity + control.

ROM 448 KB
SRAM 520 KB
RTC 8 KB
Real-Time Clock (RTC) System

Survives deep sleep. Manages wake scheduling, clock calibration, low-power sensor monitoring.

ULP Core
Timer
Sensor
Memory
RF Frontend (2.4 GHz)
PCB antenna or external IPEX connector. Shared by WiFi and BT. TX power adjustable 0–20 dBm.
Clock Generator
32 MHz main oscillator, 32 kHz RTC oscillator. Can trim clock using eFuses for temperature drift compensation.
Analog Circuits
Voltage regulators (3.3V, 1.8V), bias generator, temperature sensor (±20°C accuracy), crystal oscillator driver.
Hardware Crypto Engine
SHA-256
AES-128
RSA-4096
RNG

Hardware acceleration for cryptographic operations. Protects OTA firmware updates, TLS/SSL handshakes, and secure WiFi (WPA3).

eFuse & Security

One-time programmable eFuses store MAC address, calibration data, flash encryption keys, secure boot keys. Enables secure OTA and tamper protection.

🔴 Critical for project 📡 WiFi / BT ⚙️ GPIO / I/O ⚪ Support Logic
🎯 Key Notes for HigiBox Final Project
Use ADC1 ONLY

ADC2 becomes unavailable when WiFi transmits. For HigiBox stock sensor (weight or optical), connect to ADC1 pins (GPIO32–39). No conflicts with wireless operation.

PWM for Precise Timing

16 PWM channels available. Use one for motor control. Frequency 5 Hz–40 kHz allows precise pulse width modulation (e.g., 100ms motor pulse = 1 pill).

Dual-Core Simplifies Design

Core 0 handles WiFi/BLE stack automatically. Core 1 runs your dispenser logic without blocking on wireless events. No need for async event handling complexity.

Deep Sleep for Battery

Between dispensing events, enable deep sleep (10 µA draw). Wake via timer interrupt every 24 hours for BLE advertisement and stock check. A 2000 mAh battery = 8+ months runtime.

BLE Over WiFi

Mobile app should use Bluetooth Low Energy (BLE) for control/alerts, not WiFi. WiFi consumes 160 mA; BLE only 5–30 mA. Reserve WiFi for critical cloud logging only.

Secure OTA Updates

Partition flash with dual OTA slots. Hardware crypto engine verifies signatures during firmware updates. Prevents downgrade attacks and ensures production reliability.

⚠️ Limitations & Design Considerations
ADC2 WiFi Conflict

ADC2 unavailable during active WiFi transmission. This is a hardware limitation of how the SPI bus is shared. Plan sensor connections for ADC1.

Strapping Pin Conflicts

GPIO0, GPIO2, GPIO5, GPIO12, GPIO15 affect boot mode. Avoid using them as application GPIO if possible. If necessary, document pull-up/pull-down requirements carefully.

Antenna Design Critical

PCB antenna is direction-dependent and sensitive to component placement. Poor antenna design reduces range from 100m to 5m. If range is critical, use external antenna option (WROVER modules).

No Floating-Point Unit

No hardware FPU. Floating-point math is slow (emulated in software). For time-critical code, prefer integer math. This is rarely a problem for IoT devices.

Limited GPIO Current

Each GPIO pin can source/sink ~20 mA maximum. For high-current devices (motors, heaters), use external MOSFETs or relay drivers. N20 motor draws ~100 mA — use a driver circuit.

Supply Ripple Sensitivity

Internal voltage regulators are sensitive to supply noise. Use low-ESR capacitors (0.1 µF + 10 µF) close to ESP32 power pins. Poor filtering causes WiFi instability.

🔒 Hardware Security & Cryptography

Cryptographic Accelerators (Hardware)

  • SHA-256/SHA-1: Message digest for firmware verification and TLS handshakes. ~10× faster than software SHA.
  • AES-128 (ECB/CBC): Block cipher for flash encryption and secure communication. Hardware accelerated, essential for real-time encrypted streams.
  • RSA-4096: Asymmetric cryptography for secure boot and OTA signature verification. Slower but necessary for firmware authenticity.
  • Random Number Generator: Hardware TRNG (True RNG) based on RF noise. Critical for generating cryptographic keys and nonces.

Flash Encryption & Secure Boot

  • Flash Encryption: Optional hardware-enabled encryption of entire flash contents using AES-128. Transparent to application — data decrypted on-the-fly during execution.
  • Secure Boot: Bootloader verifies RSA-4096 signature of application before executing. Prevents unauthorized firmware installation.
  • eFuse Keys: Encryption and signing keys stored in one-time-programmable eFuses. Cannot be read back externally — only chip can use them.
🔐 For HigiBox Production: Enable secure boot and flash encryption. This prevents attackers from extracting proprietary dispensing logic or modifying firmware to bypass safety checks. Critical for a medical device context.

TLS/SSL Support

  • OpenSSL and mbedTLS libraries included in SDK
  • Hardware crypto acceleration for TLS handshakes and encrypted data transfer
  • Support for certificate validation and mutual authentication
Comparison with Other Microcontrollers

Why I chose ESP32 over alternatives:

Chip CPU Flash Wireless Cost Best For
ESP32 (my choice) Xtensa LX6 dual-core @ 240 MHz 4 MB WiFi + BT/BLE $3–5/chip IoT with cloud connectivity and mobile app
STM32H7 Cortex-M7 @ 480 MHz Up to 2 MB None (require external modules) $5–10 High-performance real-time systems, motor control
nRF52840 Cortex-M4F @ 64 MHz 1 MB BLE only $8–12 Wearables, low-power BLE-only devices
Raspberry Pi Pico Cortex-M0+ dual-core @ 133 MHz 2 MB None $4–5 Educational, simple embedded projects (no wireless)
SAMD21 Cortex-M0+ @ 48 MHz 256 KB None $2–3 Arduino-compatible Arduino Zero (very limited resources)
Decision Matrix for HigiBox:
✓ Needs WiFi + BLE → ESP32 only choice
✓ Battery-powered IoT → ESP32 beats STM32
✗ STM32 faster but requires external WiFi module (cost + complexity)
✗ Raspberry Pi Pico has no wireless
✗ nRF52840 better for BLE-only, but no WiFi

ESP32 is the only chip that does everything HigiBox needs in one package.
📚 Official Documentation & Datasheets

All ESP32 technical information is publicly available from Espressif:

DocumentPurposeKey Info
ESP32 Datasheet Hardware specification Pin assignments, electrical characteristics, timing specs, absolute maximum ratings
ESP32 Technical Reference Manual Internal architecture Register descriptions, peripheral operation, interrupt handling, memory map (500+ pages)
ESP32 Hardware Design Guide PCB design recommendations Power supply, decoupling, antenna design, signal integrity, EMC considerations
ESP-IDF Programming Guide Software development framework APIs for WiFi, BLE, timers, ADC, sleep modes, OTA updates
ESP32-WROOM-32E Datasheet Module-level specs Pinout, antenna type, power consumption, operating range, compliance certifications
04
Programming Guide

Setting Up Your First Program

Once your ESP32 is physically set up and the drivers are installed, you're ready to write your first program. Here's a complete workflow for setting up a simple program in Arduino IDE.

Step 1 Create a New Sketch

File → New opens a blank sketch template. By default, Arduino IDE gives you a skeleton with setup() and loop() functions.

Step 2 Name and Save Your Sketch

File → Save or use the keyboard shortcut. Arduino will create a folder with your sketch name and save a .ino file inside.

💡 Tip: Use descriptive names like "MotorControl_v1" or "SensorRead_Test" to keep your projects organized.
Step 3 Write Your Code

The structure of every Arduino sketch is:

void setup() { // Runs once when the board is powered or reset // Initialize pins, serial communication, sensors } void loop() { // Runs repeatedly (as fast as the board can loop) // Your main program logic goes here }

Common initialization tasks in setup():

  • pinMode(pin, OUTPUT) — declare a pin as output (for LEDs, motors)
  • pinMode(pin, INPUT) — declare a pin as input (for buttons, sensors)
  • Serial.begin(115200) — open serial communication at 115200 baud
Step 4 Verify Your Code

Sketch → Verify/Compile or press the Verify button (checkmark icon). The IDE checks for syntax errors and compiles your code. If there are issues, error messages appear in the console below.

💡 Pro Tip: Always verify before uploading. It saves time — finding errors during compilation is faster than discovering them on the board.
Step 5 Upload to Your ESP32

Sketch → Upload or press the Upload button (arrow icon). The IDE will:

  1. Compile your sketch again
  2. Detect your board and COM port
  3. Send the compiled code to the ESP32 via USB
  4. Print status messages as the upload progresses
⏱️ Upload typically takes 5–15 seconds depending on code size. You'll see "Done uploading" when complete.
Step 6 Monitor Serial Output (Optional)

If your sketch uses Serial.println() to print debug messages, open the Serial Monitor to see them in real time.

Tools → Serial Monitor or press Ctrl+Shift+M

  • Make sure the baud rate matches your code (usually 115200)
  • You'll see all messages your program sends to Serial
  • Useful for debugging and understanding what your program is doing
🔍 Example Output:
Button pressed: 1234
LED turned ON
Motor speed: 128 / 255
Step 7 Troubleshooting Common Issues
⚠️
Port Not Found

Board not detected. Check USB cable, reinstall CP2102 driver, and verify the correct port is selected in Tools → Port.

⚠️
Upload Failed

Usually a baud rate mismatch or corrupted upload. Try uploading again. If it persists, hold the "Boot" button on the ESP32 while uploading.

⚠️
Code Compilation Error

Check the error message in the console. Common issues: missing semicolons, mismatched brackets, undefined variables. The IDE highlights the line with the error.

⚠️
Sketch Won't Run

If it uploads but doesn't do what you expect, open the Serial Monitor to see if there are runtime errors or unexpected behavior in your loop.

Essential Arduino Functions Cheat Sheet

Function Purpose Example
pinMode(pin, mode) Set pin as INPUT or OUTPUT pinMode(2, OUTPUT);
digitalWrite(pin, value) Set pin to HIGH or LOW digitalWrite(2, HIGH);
digitalRead(pin) Read pin state (HIGH or LOW) int state = digitalRead(5);
analogRead(pin) Read analog value (0–4095) int value = analogRead(34);
analogWrite(pin, value) PWM output (0–255) analogWrite(18, 128);
delay(ms) Pause execution (milliseconds) delay(1000);
Serial.begin(baud) Start serial communication Serial.begin(115200);
Serial.println() Print message + newline to Serial Serial.println("Hello");
05
Hands-On Exercises

7 Programming Activities

These activities progress from simple digital output to complex sensor integration and system interactions. Each includes code, downloadable .ino file, and demonstration video.

1

Blink — LED Flashing

📌 Purpose: Turn the ESP32's built-in LED on and off every second. The "Hello World" of embedded systems.

Explanation: The built-in LED on pin 2 blinks with 1-second intervals (500ms ON + 500ms OFF). Perfect for testing if your board and IDE are set up correctly.

Code:

void setup() { pinMode(2, OUTPUT); Serial.begin(115200); } void loop() { digitalWrite(2, HIGH); // LED on Serial.println("Hola"); delay(1000); digitalWrite(2, LOW); // LED off Serial.println("Adios"); delay(1000); }

Key Concepts: pinMode() declares a pin as output, digitalWrite() sets HIGH (on) or LOW (off), delay() pauses in milliseconds.

2

Button Control — LED On/Off

📌 Purpose: Turn an LED on when a button is pressed, off when released. Introduces INPUT reading and conditional logic.

Code:

#define BOTON 5 #define LED 18 void setup() { pinMode(BOTON, INPUT_PULLUP); pinMode(LED, OUTPUT); digitalWrite(LED, LOW); } void loop() { int estadoBoton = !digitalRead(BOTON); if (estadoBoton == LOW) { digitalWrite(LED, HIGH); // Turn LED ON } else { digitalWrite(LED, LOW); // Turn LED OFF } }

Key Concepts: INPUT_PULLUP uses the internal pull-up resistor. digitalRead() reads the button state. The "!" operator inverts the logic.

3

Blinking Control — Fixed 1-Second Cycle

📌 Purpose: Blink an LED with precise 1-second intervals (500ms ON + 500ms OFF).

Code:

#define LED 18 void setup() { pinMode(LED, OUTPUT); } void loop() { digitalWrite(LED, HIGH); // LED ON delay(500); digitalWrite(LED, LOW); // LED OFF delay(500); }
4

Light Sensor (LDR) — Auto Night Light

📌 Purpose: Read an analog light sensor and automatically turn on an LED when it gets dark. Introduces ADC (analog-to-digital conversion).

Code:

#define PIN_LDR 34 #define PIN_LED 2 int valorLDR = 0; int umbralOscuridad = 3900; void setup() { Serial.begin(115200); pinMode(PIN_LED, OUTPUT); digitalWrite(PIN_LED, LOW); } void loop() { valorLDR = analogRead(PIN_LDR); Serial.print("LDR Value: "); Serial.println(valorLDR); if (valorLDR > umbralOscuridad) { digitalWrite(PIN_LED, HIGH); // Darkness: LED ON } else { digitalWrite(PIN_LED, LOW); // Light: LED OFF } delay(300); }
5

Potentiometer Control — LED Brightness

📌 Purpose: Use a potentiometer to control LED brightness. Combines analog input with PWM (Pulse Width Modulation) output.

Code:

#define POT 34 #define LED 18 void setup() { Serial.begin(115200); pinMode(LED, OUTPUT); } void loop() { int valorPot = analogRead(POT); int brillo = map(valorPot, 0, 4095, 0, 255); analogWrite(LED, brillo); Serial.print("Potentiometer: "); Serial.print(valorPot); Serial.print(" | Brightness: "); Serial.println(brillo); delay(50); }
6

Temperature Sensor (LM35) — Color Alert

📌 Purpose: Monitor temperature with an LM35 sensor and change LED color when threshold is exceeded.

Code:

#define PIN_LM35 34 #define LED_VERDE 19 #define LED_ROJO 18 float temperatura = 0; float temperaturaAlta = 14.0; void setup() { Serial.begin(115200); pinMode(LED_VERDE, OUTPUT); pinMode(LED_ROJO, OUTPUT); digitalWrite(LED_VERDE, LOW); digitalWrite(LED_ROJO, LOW); } void loop() { int lecturaADC = analogRead(PIN_LM35); float voltaje = lecturaADC * (3.3 / 4095.0); temperatura = voltaje * 100.0; if (temperatura >= temperaturaAlta) { digitalWrite(LED_ROJO, HIGH); digitalWrite(LED_VERDE, LOW); } else { digitalWrite(LED_ROJO, LOW); digitalWrite(LED_VERDE, HIGH); } delay(500); }
7

LED Sequence — Chase Animation

📌 Purpose: Create a visually appealing LED sequence that goes UP (1→5) then DOWN (5→1). Demonstrates arrays and loops.

Code:

int leds[] = {18, 19, 21, 22, 23}; int cantidadLeds = 5; void setup() { for (int i = 0; i < cantidadLeds; i++) { pinMode(leds[i], OUTPUT); digitalWrite(leds[i], LOW); } } void loop() { // Going UP: LED 1 to LED 5 for (int i = 0; i < cantidadLeds; i++) { digitalWrite(leds[i], HIGH); delay(200); digitalWrite(leds[i], LOW); } // Going DOWN: LED 5 to LED 1 for (int i = cantidadLeds - 1; i >= 0; i--) { digitalWrite(leds[i], HIGH); delay(200); digitalWrite(leds[i], LOW); } }

Get in Touch

  • micaela.cordova.carmelino@gmail.com
  • ml.cordovac@alum.up.edu.pe

© 2026 Micaela Córdova - Fab Academy 2026 Portfolio