Learn Embedded Systems: Microcontrollers and the World Beyond Arduino
What Is an Embedded System?
An embedded system is a specialized computer designed to perform a dedicated function inside a larger mechanical or electrical system. Unlike a general-purpose computer that runs spreadsheets and web browsers, an embedded system controls one thing and does it reliably, often for years without rebooting.
In a factory, embedded systems are everywhere: the controller inside a CNC machine, the temperature regulator in a furnace, the motor driver on a conveyor belt, and the sensor node measuring vibration on a pump. Each one runs firmware — software burned directly into hardware — that executes the same control loop thousands of times per second.
The key characteristics of an embedded system are real-time response, low power consumption, deterministic behavior, and direct hardware access. When a pressure sensor detects a dangerous spike, the system must react in microseconds, not whenever the operating system feels like scheduling the task.
Microcontroller vs Computer
A microcontroller (MCU) is a complete computer on a single chip: processor, memory, and peripherals all integrated together. A typical industrial MCU like the STM32F407 has a 168 MHz ARM core, 1 MB of Flash, 192 KB of SRAM, and dozens of peripherals — all on a chip smaller than a fingernail.
A single-board computer (SBC) like the Raspberry Pi runs a full operating system and handles complex tasks like image processing or running a web server. But it cannot guarantee microsecond response times because the OS scheduler introduces unpredictable delays.
| Feature | Microcontroller (STM32) | Single-Board Computer (RPi) |
|---|---|---|
| Boot time | Milliseconds | 30+ seconds |
| Power consumption | 10-200 mW | 2-5 W |
| Real-time guarantee | Yes (bare metal) | No (Linux scheduler) |
| Cost | $2-10 | $35-75 |
| Typical use | Sensor reading, motor control | HMI, data aggregation |
In industrial systems, MCUs handle the critical real-time control while SBCs serve as gateways that aggregate data and communicate with cloud platforms.
ARM Cortex-M Architecture: The Industrial Standard
The ARM Cortex-M family dominates industrial embedded systems. Unlike desktop processors, Cortex-M cores are designed for deterministic real-time operation with guaranteed interrupt latency.
The family includes several profiles:
- Cortex-M0/M0+: Ultra-low-power, simple sensors and actuators (e.g., STM32L0)
- Cortex-M3: General-purpose industrial control (e.g., STM32F1)
- Cortex-M4: DSP instructions for signal processing, motor control (e.g., STM32F4)
- Cortex-M7: High performance for complex algorithms (e.g., STM32H7)
The Cortex-M4 is the workhorse of industrial applications. Its hardware floating-point unit processes sensor math without the overhead of software emulation, and its DSP instructions accelerate filtering algorithms used in vibration analysis and motor control.
Memory: Flash, SRAM, and EEPROM
Embedded systems use three distinct types of memory, each serving a specific purpose:
Flash is non-volatile memory where your firmware lives. When you compile and upload your program, it goes into Flash. On power-up, the MCU begins executing instructions directly from Flash. A typical industrial MCU has 256 KB to 2 MB of Flash.
SRAM (Static RAM) is fast volatile memory used for variables, stack, and heap during execution. It loses all data when power is removed. Industrial MCUs typically have 64 KB to 512 KB of SRAM.
EEPROM (or Flash-emulated EEPROM) stores calibration data, configuration parameters, and accumulated values like operating hours. This data must survive power cycles but changes infrequently.
// Storing calibration data in EEPROM (STM32 HAL)
#define CALIBRATION_ADDR 0x08080000 // EEPROM base address
void save_calibration(float offset, float gain) {
HAL_FLASHEx_DATAEEPROM_Unlock();
HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_WORD,
CALIBRATION_ADDR, *(uint32_t*)&offset);
HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_WORD,
CALIBRATION_ADDR + 4, *(uint32_t*)&gain);
HAL_FLASHEx_DATAEEPROM_Lock();
}
Clock and Peripherals: The Heart of Embedded Systems
Every MCU runs on a clock signal that determines how fast instructions execute. The STM32F407, for example, uses an 8 MHz external crystal oscillator that gets multiplied by internal PLLs to reach 168 MHz.
The clock tree distributes timing signals to all peripherals through configurable buses (AHB, APB1, APB2). Each peripheral can be individually enabled or disabled to save power — a critical feature for battery-powered sensor nodes.
Key peripherals found on industrial MCUs include:
- GPIO: General-purpose pins for digital input/output
- ADC: Analog-to-digital converters for sensor reading
- UART/USART: Serial communication for Modbus RTU and debug consoles
- SPI/I2C: Bus protocols for connecting external sensors and memory
- Timers: PWM generation, input capture, and precise timing
- DMA: Direct Memory Access for moving data without CPU involvement
- CAN: Controller Area Network for industrial and automotive buses
Popular MCU Families: STM32, ESP32, and RP2040
Three MCU families dominate modern embedded development:
STM32 by STMicroelectronics is the industry standard for professional embedded systems. With over 1,000 variants across 18 series, there is an STM32 for every industrial application. The ecosystem includes STM32CubeIDE, extensive HAL libraries, and decades of proven reliability.
ESP32 by Espressif is the go-to choice for IIoT applications requiring WiFi or Bluetooth connectivity. Its dual-core 240 MHz processor and integrated wireless make it ideal for sensor nodes that need to communicate with MQTT brokers and cloud platforms.
RP2040 by Raspberry Pi Foundation is a newcomer with excellent documentation and a unique PIO (Programmable I/O) subsystem that can emulate custom communication protocols in hardware.
// A minimal blink program — the "Hello World" of embedded systems
// Target: STM32F4 with HAL library
#include "stm32f4xx_hal.h"
int main(void) {
HAL_Init();
SystemClock_Config();
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef gpio = {0};
gpio.Pin = GPIO_PIN_5;
gpio.Mode = GPIO_MODE_OUTPUT_PP;
gpio.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &gpio);
while (1) {
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
HAL_Delay(500);
}
}
In this series, we will primarily use STM32 for core embedded concepts and ESP32 when we cover wireless IIoT communication.
Summary
An embedded system is a dedicated computer that controls hardware in real time. Microcontrollers integrate CPU, memory, and peripherals on a single chip, making them ideal for industrial applications where reliability, low power, and deterministic timing matter. The ARM Cortex-M architecture is the industry standard, with the STM32 family offering the broadest range of industrial MCUs. Understanding memory types (Flash, SRAM, EEPROM), the clock tree, and available peripherals is essential before writing any firmware. In the next lesson, we will get hands-on with the most fundamental peripheral: GPIO for digital input and output.