Back to Embedded Systems Hardware Engineering Series

Part 1: Electronics Foundations

April 17, 2026 Wasil Zafar 45 min read

Master the electrical fundamentals that underpin every embedded system — from Ohm’s law and Kirchhoff’s circuit laws to power dissipation, analog/digital signal processing, and the complete embedded hardware landscape.

Table of Contents

  1. Why Electronics Matter
  2. Ohm’s Law & Circuit Basics
  3. Kirchhoff’s Laws
  4. AC vs DC & Power
  5. Analog Circuit Essentials
  6. Digital Logic Fundamentals
  7. The Embedded Landscape
  8. Component Calculator Tool
  9. Conclusion & Next Steps

Why Electronics Matter for Hardware Engineers

Every embedded system — from a simple blinking LED to a satellite’s flight computer — is built on the same electrical principles. Before you can design a custom PCB, debug a power rail, or select the right voltage regulator, you need to speak the language of electrons. This article builds that foundation from the ground up.

Think of it this way: Software engineers learn variables and loops before building applications. Hardware engineers learn voltage and current before building circuits. This part is your “Hello, World!” for hardware.

A Brief History of Electronics & Embedded Systems

1827 Georg Simon Ohm publishes Die galvanische Kette, establishing V = I × R — the foundation of circuit analysis.
1845 Gustav Kirchhoff formalises the current and voltage laws that let engineers analyse any circuit topology.
1947 Bell Labs invents the transistor, replacing vacuum tubes and enabling compact, low-power electronics.
1958 Jack Kilby (TI) and Robert Noyce (Fairchild) independently create the integrated circuit, putting multiple transistors on a single chip.
1971 Intel releases the 4004 — the first commercial microprocessor — originally designed for a Japanese calculator.
1976 Texas Instruments releases the TMS1000, considered the first true microcontroller with CPU, RAM, ROM, and I/O on one chip.
2003 ST Microelectronics launches the STM32 family, which becomes the world’s most popular 32-bit MCU platform for embedded design.
Today Billions of embedded processors ship annually — in cars, medical devices, wearables, industrial robots, and smart-home gadgets — all built on the same electrical laws you’ll learn in this article.

The Water Analogy

The most intuitive way to understand electricity is through a water analogy that engineers have used for over a century:

Electrical Concept Water Analogy Unit Symbol
Voltage (potential difference) Water pressure Volts (V) V
Current (charge flow) Water flow rate Amperes (A) I
Resistance (opposition to flow) Pipe diameter / constriction Ohms (Ω) R
Capacitance (charge storage) Water tank / reservoir Farads (F) C
Inductance (energy in magnetic field) Water wheel inertia Henrys (H) L

A battery is like a water pump that creates pressure. Wires are pipes. A resistor is a narrow section of pipe. A capacitor is a flexible membrane that stores pressure temporarily. Keep this mental model — it will serve you through the entire series.

Ohm’s Law & Circuit Basics

Georg Simon Ohm discovered in 1827 that the current through a conductor is directly proportional to the voltage across it and inversely proportional to its resistance. This single relationship — V = I × R — is arguably the most important equation in electronics.

Ohm’s Law Triangle
flowchart TD
    V["V = I × R
Voltage (Volts)"] --> I["I = V / R
Current (Amps)"] V --> R["R = V / I
Resistance (Ohms)"] I --> P["P = V × I
Power (Watts)"] R --> P
## Ohm's Law Calculator
## Run standalone in any Python environment

def ohms_law(voltage=None, current=None, resistance=None):
    """Calculate the missing value using Ohm's Law (V = I * R)."""
    if voltage is None:
        voltage = current * resistance
        print(f"Voltage = {current} A × {resistance} Ω = {voltage} V")
    elif current is None:
        current = voltage / resistance
        print(f"Current = {voltage} V / {resistance} Ω = {current:.4f} A ({current*1000:.2f} mA)")
    elif resistance is None:
        resistance = voltage / current
        print(f"Resistance = {voltage} V / {current} A = {resistance:.2f} Ω")
    return voltage, current, resistance

# Example 1: LED circuit — 3.3V supply, 220Ω resistor
# LED forward voltage ≈ 2.0V, so resistor sees 1.3V
print("=== LED Current Calculation ===")
ohms_law(voltage=1.3, resistance=220)

# Example 2: What resistor for 20mA through an LED on 5V?
print("\n=== Resistor Selection ===")
ohms_law(voltage=3.0, current=0.020)  # 5V - 2V LED drop = 3V
Output
=== LED Current Calculation ===
Voltage = 1.3 V / 220 Ω = 0.0059 A (5.91 mA)

=== Resistor Selection ===
Resistance = 3.0 V / 0.02 A = 150.00 Ω

Power Dissipation

Every component that carries current dissipates power as heat. This is critical in embedded design because excess heat damages components, drains batteries, and affects sensor accuracy. Power is calculated as:

Power equations: P = V × I = I² × R = V² / R. A tiny SMD resistor rated for 0.1W will burn if you push 0.5W through it. Always check power ratings!
## Power Dissipation Calculator
## Run standalone in any Python environment

def power_calc(voltage, current):
    """Calculate power dissipation and recommend resistor package."""
    power_w = voltage * current
    power_mw = power_w * 1000

    # Common SMD resistor power ratings
    packages = [
        ("0201", 0.05), ("0402", 0.0625), ("0603", 0.1),
        ("0805", 0.125), ("1206", 0.25), ("2512", 1.0)
    ]

    print(f"Power = {voltage}V × {current*1000:.1f}mA = {power_mw:.1f} mW ({power_w:.4f} W)")
    print(f"\nRecommended packages (≥2× derating):")
    for name, rating in packages:
        if rating >= power_w * 2:  # 50% derating rule
            print(f"  ✓ {name} ({rating*1000:.0f} mW rated) — {power_w/rating*100:.0f}% utilisation")

# Example: 3.3V GPIO driving 10mA through a resistor
power_calc(voltage=3.3, current=0.010)

# Example: 12V motor driver dropping 2V at 500mA
print("\n=== Motor Driver Heat ===")
power_calc(voltage=2.0, current=0.500)
Output
Power = 3.3V × 10.0mA = 33.0 mW (0.0330 W)

Recommended packages (≥2× derating):
  ✓ 0603 (100 mW rated) — 33% utilisation
  ✓ 0805 (125 mW rated) — 26% utilisation
  ✓ 1206 (250 mW rated) — 13% utilisation
  ✓ 2512 (1000 mW rated) — 3% utilisation

=== Motor Driver Heat ===
Power = 2.0V × 500.0mA = 1000.0 mW (1.0000 W)

Recommended packages (≥2× derating):
  (none — consider a power resistor or heat sink)

Series & Parallel Circuits

Components can be connected in series (end-to-end, sharing the same current) or in parallel (side-by-side, sharing the same voltage). Understanding this distinction is essential for designing voltage dividers, power distribution, and sensor networks.

Series vs Parallel Resistor Networks
flowchart LR
    subgraph Series["Series: R_total = R1 + R2 + R3"]
        A1["+V"] --> R1s["R1
100Ω"] --> R2s["R2
220Ω"] --> R3s["R3
330Ω"] --> GND1["GND"] end subgraph Parallel["Parallel: 1/R_total = 1/R1 + 1/R2"] A2["+V"] --> R1p["R1 = 100Ω"] A2 --> R2p["R2 = 100Ω"] R1p --> GND2["GND"] R2p --> GND2 end
## Series & Parallel Resistance Calculator
## Run standalone in any Python environment

def series_resistance(*resistors):
    """Calculate total resistance for series-connected resistors."""
    total = sum(resistors)
    print(f"Series: {' + '.join(f'{r}Ω' for r in resistors)} = {total}Ω")
    return total

def parallel_resistance(*resistors):
    """Calculate total resistance for parallel-connected resistors."""
    reciprocal_sum = sum(1/r for r in resistors)
    total = 1 / reciprocal_sum
    print(f"Parallel: {' ‖ '.join(f'{r}Ω' for r in resistors)} = {total:.2f}Ω")
    return total

# Series example: three resistors in an LED string
series_resistance(100, 220, 330)

# Parallel example: two identical resistors halve resistance
parallel_resistance(100, 100)

# Common trick: need 150Ω but only have 100Ω and 330Ω?
print("\n=== Combining standard values ===")
# 100Ω in series with (330Ω ‖ 330Ω) = 100 + 165 = 265Ω
par = parallel_resistance(330, 330)
series_resistance(100, round(par, 2))
Output
Series: 100Ω + 220Ω + 330Ω = 650Ω
Parallel: 100Ω ‖ 100Ω = 50.00Ω

=== Combining standard values ===
Parallel: 330Ω ‖ 330Ω = 165.00Ω
Series: 100Ω + 165.0Ω = 265.0Ω

Exercise: LED Current Limiting

Hands-On Beginner

Scenario: You have a 3.3V microcontroller GPIO pin, a red LED (forward voltage 2.0V, max current 20mA), and standard resistors (100Ω, 150Ω, 220Ω, 330Ω, 470Ω).

  1. Calculate the voltage drop across the resistor (3.3V − 2.0V = ?)
  2. Using Ohm’s law, calculate the ideal resistance for 15mA
  3. Pick the nearest standard resistor value
  4. Calculate actual current with your chosen resistor
  5. Calculate power dissipated by the resistor

Answer: VR = 1.3V. Ideal R = 1.3V / 0.015A = 86.7Ω. Use 100Ω → I = 13mA, P = 16.9mW (any 0402+ package works).

Kirchhoff’s Circuit Laws

While Ohm’s law handles individual components, Gustav Kirchhoff’s two laws handle entire circuits. Together, they let you analyse any circuit, no matter how complex.

Kirchhoff’s Current Law (KCL)

The sum of currents entering a node equals the sum of currents leaving it. Think of it as water conservation: every drop that flows into a junction must flow out somewhere. In embedded systems, KCL helps you calculate how much current your power supply must deliver when multiple peripherals share a voltage rail.

## KCL — Current Budget Calculator
## Run standalone in any Python environment

def current_budget(supply_voltage, peripherals):
    """
    Calculate total current draw from a shared power rail.
    peripherals: list of (name, current_mA) tuples
    """
    print(f"=== Power Rail: {supply_voltage}V ===")
    total_ma = 0
    for name, current in peripherals:
        print(f"  {name:.<30} {current:>6.1f} mA")
        total_ma += current

    print(f"  {'─' * 38}")
    print(f"  {'Total current draw':.<30} {total_ma:>6.1f} mA")
    print(f"  Power consumption: {supply_voltage * total_ma / 1000:.3f} W")
    print(f"  Recommended supply: ≥{total_ma * 1.2:.0f} mA (20% margin)")
    return total_ma

# Typical 3.3V rail budget for an IoT device
peripherals_3v3 = [
    ("STM32F4 MCU (active)", 30.0),
    ("BME280 sensor", 0.35),
    ("SPI Flash (read)", 15.0),
    ("Status LED (×2)", 26.0),
    ("ESP32 WiFi (Tx)", 240.0),
]
current_budget(3.3, peripherals_3v3)
Output
=== Power Rail: 3.3V ===
  STM32F4 MCU (active)..........   30.0 mA
  BME280 sensor.................    0.4 mA
  SPI Flash (read)..............   15.0 mA
  Status LED (×2)...............   26.0 mA
  ESP32 WiFi (Tx)...............  240.0 mA
  ──────────────────────────────────────
  Total current draw............  311.4 mA
  Power consumption: 1.028 W
  Recommended supply: ≥374 mA (20% margin)
Analogy Think of Kirchhoff’s Current Law like a highway interchange: every car that enters the junction must exit through one of the roads. No cars are created or destroyed at the intersection — the same way, no electrons appear from nowhere or vanish at a circuit node. If 311 mA flows into your power rail, exactly 311 mA must flow out through the peripherals.

Kirchhoff’s Voltage Law (KVL)

The sum of all voltages around any closed loop in a circuit is zero. Every volt the battery provides must be “used up” by the components in the loop. This is how you verify that your voltage regulator, decoupling capacitors, and load are all properly accounted for.

KVL in practice: If a 5V USB supply feeds a 3.3V LDO regulator, the LDO must “drop” 1.7V across itself. That 1.7V × load current = heat the LDO must dissipate. This is why choosing the right regulator matters!
KVL Example — Voltage Drops in a Loop
flowchart LR
    BAT["Battery
+5V"] --> R1["R1
2.5V drop"] R1 --> LED["LED
2.0V drop"] LED --> R2["R2
0.5V drop"] R2 --> BAT

AC vs DC & Power

Embedded systems primarily operate on DC (Direct Current) — steady voltage from batteries, USB ports, or regulated supplies. But understanding AC (Alternating Current) is essential because: (1) mains power is AC, (2) communication signals like UART are effectively AC, and (3) switching power supplies operate at high AC frequencies internally.

DC Fundamentals

A DC signal maintains a constant voltage over time. Your 3.3V rail is DC. Your battery is DC. GPIO output pins produce DC levels (HIGH = VDD, LOW = GND). The key DC parameters:

Parameter Common Values Where You’ll See It
1.8V Core voltage for modern MCUs STM32 internal regulator
3.3V Standard logic level GPIO, SPI, I2C, sensors
5.0V USB VBUS, legacy logic USB devices, Arduino, motors
12V Automotive, industrial CAN bus transceivers, actuators
24V Industrial I/O PLC interfaces, solenoids

AC Signals & Frequency

An AC signal alternates between positive and negative voltage. Key parameters include frequency (cycles per second, measured in Hz), amplitude (peak voltage), and duty cycle (for square waves like PWM).

## AC Signal Analysis
## Run standalone — requires numpy and matplotlib

import numpy as np
import matplotlib.pyplot as plt

# Generate time axis (1ms at 1MHz sample rate)
t = np.linspace(0, 0.001, 1000)

# Common embedded signals
signals = {
    "50Hz Mains (scaled)": np.sin(2 * np.pi * 50 * t),
    "1kHz PWM (50% duty)": np.sign(np.sin(2 * np.pi * 1000 * t)),
    "UART at 9600 baud": np.sign(np.sin(2 * np.pi * 9600 * t)) * 3.3,
}

fig, axes = plt.subplots(3, 1, figsize=(10, 6), sharex=True)
for ax, (name, signal) in zip(axes, signals.items()):
    ax.plot(t * 1000, signal, linewidth=1.5)
    ax.set_title(name, fontsize=11)
    ax.set_ylabel("Voltage")
    ax.grid(True, alpha=0.3)

axes[-1].set_xlabel("Time (ms)")
plt.tight_layout()
plt.savefig("ac_signals.png", dpi=150, bbox_inches="tight")
plt.show()

Power Supply Basics

Every embedded system needs a stable power supply. The three most common types you’ll encounter:

Power Supply Decision Tree
flowchart TD
    Q{"Input voltage
vs output?"} -->|"V_in close to V_out
(≤1V diff)"| LDO["LDO Regulator
Simple, low noise
η = V_out/V_in"] Q -->|"V_in >> V_out
(step-down)"| BUCK["Buck Converter
High efficiency (85-95%)
More complex, noisy"] Q -->|"V_in << V_out
(step-up)"| BOOST["Boost Converter
Battery to 5V/12V
Efficiency 80-90%"] LDO --> USE1["Use when:
Low noise needed,
small current (<500mA)"] BUCK --> USE2["Use when:
Battery life matters,
high current (>500mA)"] BOOST --> USE3["Use when:
Single-cell battery
powering 3.3V/5V logic"]

Case Study: LDO vs Buck for IoT Sensor Node

Design Decision Power

Scenario: A battery-powered sensor node needs 3.3V at 50mA average from a 2S LiPo battery (7.4V nominal).

  • LDO (AMS1117-3.3): Drops 4.1V × 50mA = 205mW wasted as heat. Efficiency = 3.3/7.4 = 44.6%. Battery life: ~18 hours.
  • Buck (TPS62160): 90% efficient. Only 18.3mW wasted. Battery life: ~40 hours.

Decision: Buck converter for battery power (doubles battery life), but add an LDO downstream for the ADC reference to filter switching noise.

Analog Circuit Essentials

Embedded systems interact with the real world through analog signals — sensor readings, audio, motor control. Even in a “digital” system, you’ll encounter analog concerns at the boundaries.

Voltage Dividers

A voltage divider is two resistors in series that produce an output voltage proportional to the ratio of the resistances. It’s one of the most common circuits in embedded design, used for level shifting, ADC input scaling, and battery voltage monitoring.

The output voltage is: Vout = Vin × R2 / (R1 + R2)

## Voltage Divider Calculator
## Run standalone in any Python environment

def voltage_divider(v_in, r1, r2):
    """Calculate voltage divider output and current draw."""
    v_out = v_in * r2 / (r1 + r2)
    current = v_in / (r1 + r2)
    power = v_in * current

    print(f"V_in = {v_in}V, R1 = {r1/1000:.1f}kΩ, R2 = {r2/1000:.1f}kΩ")
    print(f"V_out = {v_out:.3f}V")
    print(f"Current = {current*1000:.3f} mA")
    print(f"Power = {power*1000:.2f} mW")
    return v_out

# Example 1: Monitor 12V battery with 3.3V ADC
print("=== Battery Monitor (12V → 3.3V ADC) ===")
voltage_divider(v_in=12.6, r1=100_000, r2=33_000)  # Max 3.13V — safe for ADC

# Example 2: 5V to 3.3V level shift
print("\n=== Level Shift (5V → 3.3V) ===")
voltage_divider(v_in=5.0, r1=1_800, r2=3_300)
Output
=== Battery Monitor (12V → 3.3V ADC) ===
V_in = 12.6V, R1 = 100.0kΩ, R2 = 33.0kΩ
V_out = 3.127V
Current = 0.095 mA
Power = 1.19 mW

=== Level Shift (5V → 3.3V) ===
V_in = 5.0V, R1 = 1.8kΩ, R2 = 3.3kΩ
V_out = 3.235V
Current = 0.980 mA
Power = 4.90 mW

RC Circuits & Filtering

A resistor-capacitor (RC) circuit is the foundation of signal filtering. In embedded systems, RC filters are used for debouncing buttons, smoothing PWM outputs, and filtering ADC inputs.

Time constant: τ = R × C. After 1τ, a capacitor charges to 63.2%. After 5τ, it reaches 99.3% (considered “fully charged”). A 10kΩ resistor + 100nF capacitor gives τ = 1ms — perfect for button debouncing.
## RC Circuit Time Constant Calculator
## Run standalone — requires numpy and matplotlib

import numpy as np
import matplotlib.pyplot as plt

def rc_charging(r_ohms, c_farads, v_supply, duration_ms=10):
    """Simulate RC charging curve."""
    tau = r_ohms * c_farads
    t = np.linspace(0, duration_ms / 1000, 500)
    v_cap = v_supply * (1 - np.exp(-t / tau))

    plt.figure(figsize=(8, 4))
    plt.plot(t * 1000, v_cap, linewidth=2, label=f"τ = {tau*1000:.2f} ms")
    plt.axhline(y=v_supply * 0.632, color='r', linestyle='--', alpha=0.5, label="63.2% (1τ)")
    plt.axhline(y=v_supply * 0.993, color='g', linestyle='--', alpha=0.5, label="99.3% (5τ)")
    plt.xlabel("Time (ms)")
    plt.ylabel("Capacitor Voltage (V)")
    plt.title(f"RC Charging: R={r_ohms/1000:.1f}kΩ, C={c_farads*1e9:.0f}nF")
    plt.legend()
    plt.grid(True, alpha=0.3)
    plt.tight_layout()
    plt.savefig("rc_charging.png", dpi=150, bbox_inches="tight")
    plt.show()

# Button debounce: 10kΩ + 100nF = 1ms time constant
rc_charging(r_ohms=10_000, c_farads=100e-9, v_supply=3.3, duration_ms=5)

Operational Amplifiers (Op-Amps)

Op-amps amplify small analog signals to levels your MCU’s ADC can read. The two configurations you’ll use most in embedded design:

Configuration Gain Formula Embedded Use Case
Non-Inverting G = 1 + Rf/Rin Amplify thermocouple output (mV → V range)
Inverting G = −Rf/Rin Summing amplifier for audio mixing
Buffer (Voltage Follower) G = 1 Isolate high-impedance sensor from ADC
Comparator mode Output = HIGH/LOW Threshold detection (over-voltage, over-current)

Digital Logic Fundamentals

Digital electronics represent information as discrete voltage levels: HIGH (logic 1) and LOW (logic 0). Every microcontroller, FPGA, and digital IC operates on these principles.

Logic Gates & Truth Tables

Logic gates are the building blocks of all digital systems. While you rarely design with discrete gates in modern embedded systems (the MCU handles it internally), understanding gates helps you read datasheets, design glue logic, and debug digital interfaces.

Gate Symbol Boolean 0,0 0,1 1,0 1,1 Embedded Use
AND & A · B 0 0 0 1 Enable signals, bit masking
OR | A + B 0 1 1 1 Interrupt combining, flag setting
NOT ~ ¬A 1 0 Active-low signals, inversion
XOR ^ A ⊕ B 0 1 1 0 Parity check, toggle bits
NAND ¬(A · B) 1 1 1 0 Universal gate, SR latches
## Bitwise Operations in Embedded Firmware
## Run standalone in any Python environment

# Register manipulation — common in embedded C, demonstrated in Python

# GPIO Output Data Register (simulated as 8-bit)
ODR = 0b00000000
print(f"Initial ODR:  {ODR:08b}  (0x{ODR:02X})")

# Set bit 5 (turn on LED on pin 5) — OR mask
ODR = ODR | (1 << 5)
print(f"Set bit 5:    {ODR:08b}  (0x{ODR:02X})")

# Set bit 2 (enable peripheral on pin 2)
ODR = ODR | (1 << 2)
print(f"Set bit 2:    {ODR:08b}  (0x{ODR:02X})")

# Clear bit 5 (turn off LED) — AND with inverted mask
ODR = ODR & ~(1 << 5)
print(f"Clear bit 5:  {ODR:08b}  (0x{ODR:02X})")

# Toggle bit 2 — XOR
ODR = ODR ^ (1 << 2)
print(f"Toggle bit 2: {ODR:08b}  (0x{ODR:02X})")

# Check if bit 3 is set — AND + compare
is_set = bool(ODR & (1 << 3))
print(f"Bit 3 set?    {is_set}")
Output
Initial ODR:  00000000  (0x00)
Set bit 5:    00100000  (0x20)
Set bit 2:    00100100  (0x24)
Clear bit 5:  00000100  (0x04)
Toggle bit 2: 00000000  (0x00)
Bit 3 set?    False
Analogy Think of a hardware register like a row of light switches on a wall. Each switch (bit) independently controls one thing — an LED, a motor, a sensor enable. “Setting” a bit flips one switch ON without touching the others. “Clearing” flips one switch OFF. “Toggling” reverses whichever position the switch is currently in.

Logic Families & Voltage Levels

Different chips use different voltage levels to represent HIGH and LOW. Mixing logic families without level shifting is one of the most common beginner mistakes in embedded design.

Logic Family VDD VOH min VIL max VIH min 5V Tolerant?
3.3V LVCMOS 3.3V 2.4V 0.8V 2.0V Usually no
5V TTL 5.0V 2.4V 0.8V 2.0V N/A (is 5V)
1.8V LVCMOS 1.8V 1.2V 0.5V 1.17V No
Level mismatch damage: Connecting a 5V output directly to a 3.3V input can destroy the receiving chip. Always check the “Absolute Maximum Ratings” in the datasheet. Use voltage dividers, level shifters (TXS0108E), or open-drain outputs with pull-ups.

Timing & Clock Signals

Every digital system runs on a clock. The clock frequency determines how fast your MCU executes instructions, how fast SPI transfers data, and how quickly your ADC converts. Key timing concepts:

Concept Definition Embedded Example
Frequency Cycles per second (Hz) STM32F4 runs at 168 MHz
Period T = 1/f (seconds per cycle) 168 MHz → 5.95 ns per cycle
Duty Cycle % of period signal is HIGH PWM at 50% = half brightness LED
Rise/Fall Time Time to transition 10%→90% Affects signal integrity at high speeds
Propagation Delay Input-to-output delay of a gate Critical for high-speed bus timing

The Embedded Hardware Landscape

Now that you understand the electrical fundamentals, let’s survey the hardware platforms you’ll work with throughout this series.

MCU vs MPU vs SoC vs FPGA

Embedded Processor Comparison
flowchart LR
    subgraph MCU["MCU
(Microcontroller)"] M1["CPU + RAM + Flash
+ Peripherals
All on one chip"] end subgraph MPU["MPU
(Microprocessor)"] M2["CPU only
External RAM, storage
Runs Linux/RTOS"] end subgraph SoC["SoC
(System on Chip)"] M3["CPU + GPU + DSP
+ Peripherals
Phone/tablet chips"] end subgraph FPGA["FPGA
(Field-Programmable)"] M4["Configurable logic
Parallel processing
Custom hardware"] end MCU -->|"More resources"| MPU MPU -->|"More integration"| SoC MCU -->|"Custom logic"| FPGA
Platform Typical Chips RAM OS Use Case Power
MCU STM32, ESP32, nRF52 64KB–1MB Bare-metal / RTOS Sensors, control, IoT μA–mA
MPU i.MX6, AM335x 256MB–4GB Linux HMI, networking, vision 100mA–2A
SoC Snapdragon, Apple M-series 4GB–32GB Android/iOS/macOS Mobile, tablets, laptops 1–15W
FPGA Xilinx Artix, Intel Cyclone Block RAM HDL (no OS) Signal processing, proto mA–Amps

Development Ecosystem Overview

Throughout this series, you’ll use these tools at different stages of the hardware development lifecycle:

Hardware Development Lifecycle
flowchart TD
    REQ["1. Requirements
Define specs, I/O, power"] --> PROTO["2. Prototyping
Breadboard + dev boards"] PROTO --> SCHEM["3. Schematic
KiCad / Altium"] SCHEM --> SIM["4. Simulation
SPICE, signal integrity"] SIM --> PCB["5. PCB Layout
2/4-layer, routing"] PCB --> DFX["6. DFX Review
DFM, DFA, DFT"] DFX --> MFG["7. Manufacturing
Gerber → fab → assembly"] MFG --> BRING["8. Bring-Up
Power-on, debug, flash"] BRING --> FW["9. Firmware
Drivers, RTOS, comms"] FW --> TEST["10. Test & Validate"] TEST --> CERT["11. Compliance
CE, FCC, RoHS"] CERT --> PROD["12. Production
Mass manufacturing"] PROD -.->|"Rev B"| REQ

Industry Snapshot: Hardware Engineer’s Toolkit

Professional Tools

A professional hardware engineer’s typical workstation includes:

  • EDA Software: KiCad (free/open-source), Altium Designer (professional), EasyEDA (web-based)
  • Simulation: LTspice (free, SPICE), MATLAB/Simulink (system-level)
  • Test Equipment: Digital oscilloscope (≥100MHz), logic analyser, bench power supply, multimeter
  • Firmware IDEs: STM32CubeIDE, PlatformIO + VS Code, SEGGER Embedded Studio
  • Version Control: Git for firmware + KiCad native Git support for schematics
  • Documentation: Markdown + Mermaid diagrams, hardware BOM spreadsheets

Component Calculator Tool

Exercise 1: Power Budget Challenge

You’re designing an IoT weather station powered by a single 18650 Li-ion cell (3.7V, 2600mAh). Estimate battery life given these peripherals:

  1. STM32L4 MCU in sleep mode: 2 μA, active for 50ms every 60s at 12 mA
  2. BME280 sensor: active 1ms every 60s at 0.35 mA, sleep 0.1 μA
  3. LoRa radio: active 100ms every 300s at 120 mA, sleep 1 μA

Hint: Calculate each peripheral’s average current by weighting active vs sleep time, then sum them. Battery life = capacity / total average current.

Exercise 2: Voltage Divider Design

A 24V industrial sensor needs to be monitored by a 3.3V MCU ADC (0–3.3V input range, 12-bit resolution). Design a resistive voltage divider that:

  1. Maps the full 0–24V range to 0–3.0V (leave 0.3V headroom below ADC max)
  2. Draws less than 100 μA total current (to minimise power waste)
  3. Uses standard E24 resistor values

Hint: Vout = Vin × R2/(R1+R2). For 3.0V at 24V input, R2/(R1+R2) = 0.125. Try R2 = 33kΩ and solve for R1. Verify current at 24V stays below 100 μA.

Exercise 3: Register Manipulation

An 8-bit GPIO port register starts at 0b10110100. Write the bitwise operations to:

  1. Turn ON bit 0 and bit 1 without changing other bits
  2. Turn OFF bit 5 without changing other bits
  3. Toggle bits 2 and 4
  4. Check if bit 7 is set

Hint: Use OR to set bits, AND with inverted mask to clear bits, XOR to toggle. The starting value 0b10110100 = 0xB4.

Use this interactive tool to calculate common circuit values and download the results as a reference document.

Electronics Component Calculator

Enter your circuit parameters to calculate resistor values, power dissipation, and voltage divider outputs. Download results as Word, Excel, or PDF.

Draft auto-saved

Conclusion & Next Steps

You now have the electrical vocabulary and mathematical tools that every hardware engineer needs. You understand how voltage, current, and resistance interact through Ohm’s law, how Kirchhoff’s laws govern entire circuits, the difference between AC and DC, the role of analog components like voltage dividers and op-amps, digital logic fundamentals, and the embedded platform landscape.

Key takeaways: (1) V = IR is your most-used equation. (2) Always calculate power dissipation. (3) Never mix voltage levels without a level shifter. (4) The MCU is your workhorse — STM32 and ESP32 will appear in every subsequent part. (5) The hardware development lifecycle is iterative: prototype → design → test → revise.

Next in the Series

In Part 2: Prototyping & Proof of Concept, we’ll move from theory to practice — breadboarding circuits, setting up STM32 Nucleo and ESP32 dev boards, integrating sensors, and building systematic debugging habits with a multimeter and serial monitor.