Microcontroller Electronics

The hardware around a microcontroller: power and reset, crystals, GPIO limits, level shifting, pull-ups and debounce, the ADC, I2C pull-ups, programming headers and battery life.

A microcontroller board runs on code, but it only works if the electronics around the chip are right: a clean supply, a reset, a clock, inputs with defined levels, and outputs that are not asked for more than they can give. This page is the hardware side of building with microcontrollers (Arduino, ESP32, STM32, Raspberry Pi Pico and bare chips alike). For the software and peripherals see Embedded Systems.

Power, decoupling and reset

  • Check the supply voltage and current. Most modern chips run at 3.3 V (some 1.8 V or 5 V); a few use two supply rails (core and I/O). Use a regulator with some current to spare (see Batteries and Power Supplies).
  • Decouple every supply pin with a 100 nF ceramic capacitor as close as possible to the pin, plus 4.7–10 µF per rail near the regulator. The chip’s switching draws sharp current pulses that the capacitor must supply locally (see Capacitors).
  • Analog supply. Many chips have separate AVCC/VDDA pins for the ADC: connect them to the supply through a small ferrite bead or 10 Ω resistor with a decoupling capacitor.
  • Reset. A pull-up (10 kΩ) on the reset pin and a 100 nF capacitor to ground hold the chip in reset until the supply is stable; a push button to ground gives a manual reset. Chips with a built-in brown-out detector reset themselves when the supply droops; turn it on for battery projects.
  • Boot and strapping pins. Some pins set the start-up mode (for example GPIO0 on the ESP32, BOOT0 on the STM32). Do not load them with circuits that pull them to the wrong level at power-up.
  • Power-up order and back-feeding. A signal driven into a pin before the chip is powered can power it through the protection diodes; keep connected devices on the same supply or switch them together.

Clocks and crystals

Most chips have an internal oscillator that is accurate to a percent or two, good enough for blinking and slow serial links. Use a crystal (quartz) when you need accurate timing (USB, a real-time clock at 32.768 kHz, fast UART, CAN) or a precisely known frequency. A crystal oscillator needs two small load capacitors, one from each pin to ground.

Worked example: load capacitors for a crystal

  • The crystal’s datasheet gives its load capacitance CL, say 12 pF. The oscillator sees the two capacitors in series plus the stray capacitance of the board and pins (about 5 pF): CL = C1 × C2 ÷ (C1 + C2) + Cstray.
  • With C1 = C2 = C: C ÷ 2 + 5 = 12, so C = 2 × (12 − 5) = 14 pF. Use the nearest standard value (15 pF).
  • Keep the crystal and its capacitors close to the chip, with short traces, a ground pour under them and no other signals nearby. A wrong capacitor value makes the frequency a little off; a bad layout makes it fail to start.

GPIO: outputs, inputs and limits

ModeWhat the pin doesNotes
Push-pull outputDrives high and lowTypical source/sink limit 4–25 mA per pin; read the datasheet for the voltage drop at the current you use
Open-drain outputPulls low or releasesUsed for I2C, shared lines and level shifting; needs a pull-up
Input (floating)Reads the voltageNever leave an input floating: it picks up noise
Input with pull-up or pull-downInternal resistor (20–100 kΩ) sets the idle levelFine for buttons; too weak for long wires or noisy places
Analog inputConnected to the ADCSee below; the digital input stage is switched off
Alternate functionConnected to a peripheral (UART, SPI, I2C, timer)The datasheet table says which pins can do what

Worked example: an LED on a 3.3 V pin

  • A red LED has a forward voltage of about 2 V. For 5 mA from a 3.3 V pin: R = (3.3 − 2) ÷ 0.005 = 260 Ω; use 270 Ω.
  • Modern LEDs are bright at 2 to 5 mA. The pin’s current is the LED current, so keep the total of all pins within the chip’s limit (often 100–200 mA for the whole package).
  • Do not drive more than the pin’s rating: for a motor, a relay or a strip of LEDs, use a transistor (see the next sections and Driving Motors and Actuators).
  • Total current. The sum of the currents from all pins, and the current through the supply pins, has its own limit: add up the loads.
  • Unused pins: configure them as outputs (left unconnected) or as inputs with a pull-up; never as floating inputs.
  • Series resistors (100–470 Ω) on pins that go off the board limit current into a short and reduce noise.
  • Pin state at power-up and reset is usually an input: a connected transistor or relay may briefly turn on; use a pull-down on its gate or base.

Logic levels and level shifting

TermMeaningTypical value (3.3 V logic)
VOHOutput high voltage at the stated loadAt least 2.4 V
VOLOutput low voltageNo more than 0.4 V
VIHLowest voltage read as highAbout 0.7 × VDD = 2.3 V
VILHighest voltage read as lowAbout 0.3 × VDD = 1.0 V
5 V tolerantThe pin accepts 5 V though the chip runs at 3.3 VOnly if the datasheet says so (many ESP32, RP2040 and STM32 pins are not)

Connecting a 5 V output to a 3.3 V input can damage the input; connecting a 3.3 V output to a 5 V input may not be read as high (a 5 V chip may need 3.5 V). Match the levels.

MethodDirectionUse forNotes
Resistor dividerHigh to low, one waySlow inputs from a 5 V outputSimple; 1 kΩ and 2 kΩ turn 5 V into 3.33 V; slows fast edges
Series resistor and clampHigh to lowOccasional 5 V into a tolerant pinRelies on the protection diode; limit current to a milliamp
MOSFET level shifter (BSS138)Both waysI2C and open-drain busesBidirectional with a pull-up on each side
Level-shifter IC (74LVC, TXS0108, 74HCT)One or both waysSPI, UART, parallel; fast signalsCheck the speed and the direction control
74HCT or 74AHCT gateLow to high3.3 V into 5 V logicA 5 V HCT gate reads 3.3 V as high
Opto-isolator or digital isolatorEitherDifferent grounds, noisy or mains-related circuitsSee Switches, Connectors and Protection

Switches, pull-ups and debounce

A button connects the pin to ground when pressed; a pull-up resistor (internal or 10 kΩ external) holds it high otherwise (see Resistors). A real switch bounces: for a few milliseconds the contacts make and break, and the microcontroller sees many presses. Fix it in software (ignore changes for 10–20 ms) or in hardware with an RC filter.

Worked example: a hardware debounce

  • A 10 kΩ pull-up with a 1 µF capacitor across the switch gives τ = R × C = 10 ms. The voltage takes about 4.6 τ = 46 ms to settle to within 1 percent, longer than the typical bounce of a few milliseconds.
  • The capacitor discharges through the switch when it closes: a brief current spike (V ÷ contact resistance); add a 100 Ω series resistor to limit it.
  • A Schmitt-trigger input (or a 74HC14 gate) gives a clean edge from the slow RC; most microcontroller pins have hysteresis, but check the datasheet.
  • Long wires pick up noise: use a stronger pull-up (1–4.7 kΩ) and a small capacitor (10–100 nF), and shielded or twisted cable.

Analog inputs and the ADC

An analog-to-digital converter turns a voltage between 0 and its reference (often the supply, 3.3 V or 5 V) into a number. An n-bit ADC has 2n steps; one step (the LSB) is Vref ÷ 2n.

ADCReferenceStepsOne LSB
10-bit (AVR, Arduino Uno)5 V1 0244.88 mV
12-bit (STM32, RP2040, ESP32 nominal)3.3 V4 0960.81 mV
16-bit (external ADS1115 and similar)3.3 V65 5360.050 mV
Scale, filter and protect an analog input (12 V signal to a 3.3 V ADC pin)12 Vsignal27 kΩ10 kΩ1 kΩ100 nF+3.3 V (clamp diode)MCU ADC pin0 to 3.3 VDivider: 12 × 10 ÷ (27 + 10) = 3.24 V at full scale. Filter: fc = 1 ÷ (2π × 1 kΩ × 100 nF) = 1.6 kHz.Clamp: a spike on the signal goes to the supply through the diode, not into the pin.
An analog input stage: divider to scale, an RC filter to remove noise, and a clamp diode to protect the pin.

Worked example: bringing a 12 V signal into a 3.3 V ADC

  • Scale: a divider of 27 kΩ and 10 kΩ gives 12 × 10 ÷ (27 + 10) = 3.24 V at 12 V in, within the 3.3 V range. Use resistors of 1 percent for accuracy; the 37 kΩ total draws only 0.3 mA.
  • Source impedance: the ADC’s sampling capacitor needs a source of a few kilohms or less. The divider’s output impedance is 27 kΩ ∥ 10 kΩ = 7.3 kΩ, a little high for some chips: the 100 nF capacitor across the pin supplies the sampling charge and averages it, or use an op-amp buffer.
  • Filter: a 1 kΩ resistor and a 100 nF capacitor give a cutoff of 1 ÷ (2π × 1 kΩ × 100 nF) = 1.6 kHz, removing noise above that. For slow signals (a temperature) use a lower cutoff.
  • Resolution: a reading of 2048 on a 12-bit, 3.3 V ADC is 2048 ÷ 4096 × 3.3 = 1.65 V at the pin, which is 6.11 V at the input. One step at the pin (0.81 mV) is 2.98 mV at the input.
  • Protect it: the clamp diode (or the pin’s internal one with a series resistor) keeps spikes from reaching the chip.
  • Averaging and oversampling reduce noise: averaging N samples improves the noise by √N; oversampling 16 samples and shifting adds about 2 bits of resolution for slow signals.
  • The reference matters. If Vref is the noisy supply, so is every reading: use a reference chip or a well-filtered supply for accurate work.
  • Keep analog wires short, away from switching signals; use a ground plane and the separate analog ground pin.
  • Check linearity and offset of cheap on-chip ADCs (some are non-linear near the ends of the range); calibrate against a known voltage.

PWM and timers

A timer counts the clock and can toggle a pin when it reaches set values, giving a PWM output with no CPU effort. The frequency is the clock divided by the timer period; the duty cycle is the compare value divided by the period. Resolution and frequency trade off: a 16 MHz timer with 8-bit resolution runs at 62.5 kHz at most (16 MHz ÷ 256), while 16 bits gives only 244 Hz. PWM drives LEDs (dimming), motors (see Driving Motors and Actuators) and servos, and with a filter it makes a crude analog output: an RC low-pass turns the pulses into a voltage proportional to the duty cycle.

I2C, SPI and UART at the wire level

BusWiresSpeedElectrical notes
I2CSDA, SCL (+ ground)100 kHz, 400 kHz, 1 MHzOpen-drain with a pull-up on each line; many devices on one bus; each has an address
SPIMOSI, MISO, SCK, CS per deviceUp to tens of MHzPush-pull, point to point; short wires; keep the clock clean
UARTTX, RX (+ ground)9 600 to 3 MbaudCross TX to RX; common ground; 3.3 V and 5 V levels differ; RS-232 and RS-485 need transceivers (see Serial Communication)
1-WireOne data wire and groundSlowPull-up of 4.7 kΩ; Dallas temperature sensors
CANCANH, CANLUp to 1 Mbit/sNeeds a transceiver and 120 Ω terminators (see Fieldbuses)
I2C: two shared lines, each pulled up to the supply+3.3 V4.7 kΩ4.7 kΩSDASCLController (MCU)Sensor 0x48Display 0x3CRising edge (released line)3.3 VLine capacitance 100 pF with 4.7 kΩ: the I2C rise time (30 to 70 percent) is 0.847 × R × C = 398 ns (limits: 1000 ns at 100 kHz, 300 ns at 400 kHz).A smaller pull-up gives a faster edge but more current when the line is pulled low (3.3 V ÷ 4.7 kΩ = 0.7 mA).
An I2C bus: two open-drain lines with pull-ups, and the exponential rising edge that sets the speed limit.

Worked example: choosing the I2C pull-up

  • Minimum value: a device must pull the line below 0.4 V while sinking 3 mA: Rmin = (3.3 − 0.4) ÷ 3 mA = 967 Ω.
  • Maximum value: the rise time (30 to 70 percent) is 0.8473 × R × Cbus. With 100 pF of wiring and device capacitance, standard mode (100 kHz, 1 000 ns allowed) allows R up to 1 000 ns ÷ (0.8473 × 100 pF) = 11.8 kΩ, and fast mode (400 kHz, 300 ns) up to 3.5 kΩ.
  • 4.7 kΩ sits between the limits and is the usual choice for 100 kHz: its rise time is 0.8473 × 4.7 kΩ × 100 pF = 398 ns, too slow for 400 kHz, where 2.2 kΩ (186 ns) is needed.
  • Many breakout boards already have 4.7 kΩ or 10 kΩ pull-ups: several in parallel lower the value. If an I2C bus is unreliable, measure the edge with a scope.
  • Keep I2C short (tens of centimeters); a longer bus needs lower pull-ups, a buffer chip or differential drivers.
  • Address clashes: two devices with the same address cannot share a bus: use an address pin, an I2C multiplexer, or another bus.
  • SPI chip selects idle high; unused slaves must be deselected, and the clock should be kept clean (a series resistor of 22–47 Ω helps).
  • UART: a common ground, crossed TX/RX, and the same baud rate, data bits, parity and stop bits at both ends.

Driving loads from a pin

LoadCircuitNotes
LED, up to ~10 mAPin, series resistor, LED to groundSee above; set the current with the resistor
LED strip, buzzer, relay, solenoidPin, 1 kΩ to the gate of a logic-level N-MOSFET (or the base of an NPN through 1 kΩ), load to the supply, a 10 kΩ pull-down, flyback diode for coilsSee Transistors and Driving Motors and Actuators
Mains loadA relay module or an SSR with opto-isolationMains is lethal: enclose and follow the rules
High-side switchingP-channel MOSFET or a load switch ICThe load keeps a ground reference; the gate must swing to the supply
5 V logic from a 3.3 V pinSee level shiftingA 74HCT gate does it for one way

Programming and debug connections

InterfacePinsUsed byNotes
USB-serial bootloaderTX, RX, DTR/RTS for auto-resetArduino, ESP32, many STM32Needs the right boot pin state and a USB-serial adapter at 3.3 V logic
SWDSWDIO, SWCLK, GND, Vref, resetARM Cortex-M (STM32, RP2040, nRF)Two wires; breakpoints and live debugging; 10-pin or 6-pin headers
JTAGTCK, TMS, TDI, TDO, resetMany chips; FPGAsMore pins than SWD
ISP / UPDIMOSI, MISO, SCK, reset; or UPDI single wireAVR chips6-pin ICSP header; UPDI on newer parts
USB nativeD+, D− (+ 5 V and ground)RP2040 (UF2), ESP32-S, STM32 DFUSeries resistors of about 22 Ω on D+ and D− if required by the datasheet
  • Always put a programming header on a custom board. It is cheap and it saves a board that arrived with the wrong firmware.
  • Break out ground, supply, reset and the debug pins, and a UART for log messages.
  • Protect the header from backwards connection with a keyed connector.

Low power and battery life

Battery life depends on the average current, and a microcontroller that sleeps most of the time needs a tiny fraction of the current it uses when it is running. The power budget has three parts: the chip in active and sleep modes, the sensors and radios you switch on, and the always-on circuits (the regulator’s quiescent current, pull-up resistors, LEDs).

Worked example: how long on a 1 000 mAh cell?

  • The board draws 40 mA while awake and 0.010 mA (10 µA) asleep, and is awake 1 percent of the time.
  • The average current is 40 × 0.01 + 0.010 × 0.99 = 0.410 mA.
  • With 80 percent of the 1 000 mAh usable, the life is 800 ÷ 0.410 = 1 952 hours (81 days), against 20 hours (0.8 days) if it never slept.
  • The always-on parts matter: an LDO with 100 µA of quiescent current alone would dominate a 10 µA sleep current. Choose a regulator with a quiescent current of a few microamperes, switch off sensors with a MOSFET, and measure the real sleep current with a meter or a current-profiler.
  • Use sleep modes and wake on an interrupt or a timer instead of polling.
  • Slow down the clock when full speed is not needed; lower the supply voltage.
  • Turn off the radio and the sensors between readings.
  • Remove power LEDs on cheap boards for battery projects (they draw milliamperes), and note that USB-serial chips and regulators on dev boards waste power.

Protection and robustness

RiskMeasure
Reversed supplyA series Schottky diode or a P-MOSFET reverse-polarity circuit (see Switches, Connectors and Protection)
Overvoltage and spikes on the supplyA TVS diode, a fuse or a polyfuse, a regulator rated for the input range
ESD and spikes on I/O pinsSeries resistors, TVS arrays on connectors, clamp diodes
Noise and glitchesDecoupling, a ground plane, ferrites; watchdog timer in software
Brown-outBrown-out detector enabled; a supervisor chip; enough bulk capacitance
Hot-pluggingConnect grounds first; use connectors with long ground pins; add series resistors
Long cablesBuffer or isolate the signals; use RS-485 or CAN for distance; see Cabling, Grounding and Noise

Common faults

SymptomLikely causeTry
The board does not start or keeps resettingSupply droop, missing decoupling, a boot pin held in the wrong state, a floating resetScope the supply and reset; add 100 nF per supply pin; check the boot strapping
Programmer cannot connectWrong voltage, no reset or boot control, an SWD pin used by the program, a damaged chipCheck the supply, the header wiring and the boot mode; try slower speed
Random pin states or inputs that flickerFloating inputs, no pull-up, noiseAdd pull-ups; shorten wires; filter
Analog readings noisy or wrongNoisy reference, high source impedance, switching close byAdd the RC filter; average; separate the analog supply
I2C works on the bench and fails on a cableToo much capacitance, pull-ups wrong, noiseShorten; reduce the pull-up value; lower the speed; use a buffer
A pin is damaged or stuckOvercurrent, 5 V on a 3.3 V pin, a spikeTest the pin with nothing connected; use another pin; add protection
Serial garbageWrong baud rate, wrong voltage level, TX and RX not crossedMatch the settings; cross the lines; check levels
The board is hotLinear regulator dropping a high voltage, a short, a driven pin fighting anotherMeasure supply current; fit a switching regulator; check for contention
Works on USB, fails on batteryBattery voltage too low or sagging, a regulator that needs more input voltageMeasure the supply under load; use a low-dropout regulator or a boost converter

Related

FAQ

Do I need a crystal?

Only for accurate timing: USB, a real-time clock, fast UART or CAN. The internal oscillator is fine for most hobby work.

Can I connect a 5 V sensor to a 3.3 V board?

Only if its output is not above the pin’s limit. A 5 V digital output needs a divider or a level shifter; a 5 V analog output needs a divider. Many modules have a regulator and level shifting built in: check the module.

What pull-up value should I use?

For a button, 10 kΩ (or the internal pull-up). For I2C, 2.2 kΩ at 400 kHz and 4.7 kΩ at 100 kHz, adjusted for the bus capacitance. For a long wire or a noisy place, a smaller value (1–4.7 kΩ).

Why do my analog readings jump around?

Noise on the input or the reference, a high source impedance, or a floating pin. Add the RC filter, buffer high-impedance sources, average several samples and keep wires short.

How do I make a board last a year on a battery?

Sleep nearly all the time, wake on a timer or an interrupt, switch off sensors and radios between readings, choose a regulator with a microampere quiescent current, and measure the real average current.

References

  • NXP Semiconductors, UM10204 I2C-bus specification and user manual (rise-time and pull-up limits).
  • Microchip AVR, STMicroelectronics STM32, Espressif ESP32 and Raspberry Pi RP2040 datasheets and hardware design guides (decoupling, boot pins, ADC, GPIO limits).
  • Horowitz, P. and Hill, W., The Art of Electronics, 3rd ed., Cambridge University Press: chapters on digital logic and microcontrollers.
  • Crystal manufacturers’ application notes on load capacitance (Epson, Abracon, NDK).

Last reviewed: October 2026. Values are typical: check the datasheets of the parts you use.