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.
A Brief History of Electronics & Embedded Systems
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.
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
=== 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 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)
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.
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))
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
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Ω).
- Calculate the voltage drop across the resistor (3.3V − 2.0V = ?)
- Using Ohm’s law, calculate the ideal resistance for 15mA
- Pick the nearest standard resistor value
- Calculate actual current with your chosen resistor
- 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)
=== 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)
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.
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:
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
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)
=== 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.
## 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}")
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
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 |
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
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:
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
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:
- STM32L4 MCU in sleep mode: 2 μA, active for 50ms every 60s at 12 mA
- BME280 sensor: active 1ms every 60s at 0.35 mA, sleep 0.1 μA
- 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:
- Maps the full 0–24V range to 0–3.0V (leave 0.3V headroom below ADC max)
- Draws less than 100 μA total current (to minimise power waste)
- 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:
- Turn ON bit 0 and bit 1 without changing other bits
- Turn OFF bit 5 without changing other bits
- Toggle bits 2 and 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.
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.
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.