Step-by-Step: Component Integration for Your First BLE Device

Most people abandon their first BLE project before they ever transmit a single advertising packet. Not because it’s impossibly hard, but because they try to learn RF design, component selection, PCB layout, and firmware simultaneously, then drown in a 600-page datasheet before writing a line of code. You don’t need to master all of that to get a BLE device working. You need to understand about six components, make one opinionated platform choice, and follow a bringup sequence that professional engineers use every day. This guide walks you through BLE component integration from hardware fundamentals to a working, advertising device, using a path that skips the quicksand and gets you to “it works” as fast as possible.
Pick the nRF52840 and Stop Second-Guessing
Alternatives exist. The TI CC2640, ESP32, and Silicon Labs EFR32 are all capable BLE SoCs. Ignore them for now. For your first BLE project, use the Nordic nRF52840. The reasons are practical: BLE 5.0 support, built-in USB, excellent documentation, and the largest beginner community in embedded BLE. When you’re stuck at 11 PM wondering why your device won’t advertise, community size matters more than any spec sheet advantage.
Buy the nRF52840 DK (development kit, roughly $40). It has the SoC, antenna, crystals, power regulation, and a debugger all integrated on one board. You’re not cutting corners by using a DK. You’re doing exactly what professionals do before they spin a custom PCB. The DK lets you skip hardware complexity and focus entirely on firmware, which is where you’ll spend 90% of your time anyway.
What’s Actually on a BLE Board (And Why Firmware Cares)
Even though the DK handles hardware integration for you, understanding the core components will save you hours of confusion later, especially when you eventually move to a custom board. Every minimal BLE circuit has the same handful of parts. Here’s what each one does and why your firmware needs to know about it.
The SoC (nRF52840). This single chip contains an ARM Cortex-M4 processor, a 2.4 GHz radio, and dozens of peripherals (GPIO, SPI, I2C, ADC, USB). Your firmware lives here. Every initialization call in your code is configuring some block inside this chip.
Antenna and matching network. This is how your BLE signal reaches the outside world. On the DK, it’s a pre-tuned PCB trace antenna. On a custom board, you’d follow Nordic’s reference layout precisely: antenna matching is one area where creativity gets punished. Firmware doesn’t configure the antenna directly, but your transmit power settings determine how hard the radio drives it.
32.768 kHz crystal (LFXO). This low-frequency crystal provides the timing reference for sleep modes and BLE connection event scheduling. Your firmware must specify which low-frequency clock source to use during BLE stack initialization, either the internal RC oscillator or the external crystal. The crystal is more accurate, which means better power efficiency during sleep.
32 MHz crystal (HFXO). The radio needs this high-frequency crystal to transmit and receive. The firmware activates it automatically when the BLE stack brings up the radio. If this crystal isn’t present or isn’t working, the radio simply won’t function.
Decoupling capacitors. These small capacitors sit next to the SoC’s power pins and filter noise from the supply voltage. You’ll never configure them in firmware, but if they’re missing or poorly placed on a custom board, you’ll see random crashes, corrupted data, and radio failures that look like firmware bugs but aren’t.
Power supply / voltage regulator. The nRF52840 operates from 1.7V to 5.5V. The DK includes an onboard regulator that handles USB power cleanly. On a custom board, a poorly chosen regulator introduces noise that degrades radio performance.
Using the DK? All of this hardware integration is already done for you. But when mysterious bugs appear in future projects, and they will, understanding these components is what separates someone who debugs for 20 minutes from someone who debugs for 20 hours.
┌──────────────────────────────────┐
│ nRF52840 SoC │
│ │
│ ┌───────────┐ ┌──────────────┐ │
│ │ ARM │ │ 2.4 GHz │ │
│ │ Cortex-M4 │ │ BLE Radio │──┼──── Antenna & Matching Network
│ └───────────┘ └──────────────┘ │
│ │
└──┬──────────┬──────────┬──────────┘
│ │ │
│ │ │
┌─────┴─────┐ ┌─┴────┐ ┌───┴───────┐
│ 32.768 kHz│ │32 MHz│ │ Decoupling │
│ Crystal │ │Crystal│ │ Caps │
│ (LFXO) │ │(HFXO)│ │ (per Vcc │
│ │ │ │ │ pin) │
│ Sleep & │ │Radio │ │ Noise │
│ scheduling│ │clock │ │ filtering │
└───────────┘ └──────┘ └────────────┘
│
┌────────┴────────┐
│ Voltage Regulator│
│ (1.7V–5.5V in) │
└─────────────────┘Setting Up the nRF Connect SDK Toolchain
Use the nRF Connect SDK (NCS), not the legacy nRF5 SDK. Many tutorials you’ll find online still reference the older SDK or Segger Embedded Studio. Skip those. NCS is Nordic’s current platform, built on Zephyr RTOS, which means you’re simultaneously learning an industry-standard real-time operating system. Two skills for the price of one.
Here’s the installation sequence:
- Download and install nRF Connect for Desktop from Nordic’s website. This is the launcher app that manages Nordic’s toolchain.
- Open the Toolchain Manager inside nRF Connect for Desktop. Install the latest nRF Connect SDK version. This pulls down the SDK, Zephyr, and all required compilers automatically.
- Install VS Code and the nRF Connect Extension Pack from the VS Code marketplace. The extension pack integrates build, flash, and debug directly into your editor.
- Verify the installation: Open VS Code, use the nRF Connect extension to open the
zephyr/samples/basic/blinkysample, selectnrf52840dk_nrf52840as your board target, and click Build. A successful build confirms your toolchain is working.
Expected output: After clicking Build in VS Code with the nRF Connect extension, the terminal panel shows:
[1/142] Building C object ... ... [142/142] Linking C executable zephyr/zephyr.elf Memory region Used Size FLASH: 32784 1024KB SRAM: 8640 256KB Build completed successfully.
One critical piece of advice: resist the urge to go bare-metal. The BLE protocol stack is tens of thousands of lines of timing-critical code managing radio state machines, encryption, and connection scheduling. Nobody writes this from scratch. You write application code on top of the SDK. That’s not a crutch; it’s how every commercial BLE product is built.
The Embedded Hardware Bringup Sequence: Power-On to BLE Advertising
Professional embedded engineers don’t flash complex firmware and hope everything works. They follow a bringup sequence, verifying each layer of functionality before adding the next. This takes maybe 30 minutes on a DK and saves hours of debugging blind. Here are the five steps.
Step 1: Confirm power and basic boot. Connect the nRF52840 DK to your computer via USB. Open a serial terminal (PuTTY, minicom, or VS Code’s built-in terminal) at 115200 baud on the DK’s COM port. Flash the zephyr/samples/basic/hello_world sample. You should see “Hello World” printed to the terminal. If you see it, your board is powered, booting, and executing code. If not, check your USB cable (some cables are charge-only) and verify you selected the correct COM port.
Step 2: Verify GPIO. Flash the zephyr/samples/basic/blinky sample. Confirm that LED1 on the DK toggles on and off. This validates that your toolchain can build, flash, and that basic peripheral access works. A blinking LED is the embedded engineer’s “Hello World.”
Step 3: Enable UART logging. Flash a sample that uses printk() or Zephyr’s LOG module (the hello_world sample already does this). Confirm you see serial output in your terminal. This UART output is your primary debugging tool for everything that follows. If you can’t see log output, fix it now. Don’t proceed.
Step 4: Initialize the BLE stack. Flash the zephyr/samples/bluetooth/peripheral_hr sample. This is Nordic’s canonical BLE example: it initializes the full BLE stack, creates a Heart Rate GATT service (a standardized BLE service for transmitting heart rate data), and starts advertising. Watch the serial output for initialization messages confirming the BLE stack started successfully.
Step 5: Verify BLE advertising from a phone. Download the free nRF Connect mobile app (available on iOS and Android). Open the app and tap Scan. You should see a device named “Nordic_HRM” appear in the scan results. Tap Connect. The app will show the Heart Rate service and its characteristics. You now have a working BLE device.
Here’s the full bringup sequence. If any step fails, stop and debug that step before moving forward. Failing at Step 3 and jumping to Step 4 guarantees confusion. This sequential discipline is not slow — it’s the fastest path to a working system.
┌─────────────────────────────┐
│ Step 1: Power & Basic Boot │
│ Flash hello_world sample │
│ See "Hello World" on serial?│
└─────────┬───────────────────┘
│
Pass?├──── No ──→ Check USB cable, COM port, board power
│
▼
┌─────────────────────────────┐
│ Step 2: Verify GPIO │
│ Flash blinky sample │
│ LED1 toggling? │
└─────────┬───────────────────┘
│
Pass?├──── No ──→ Verify board target is nrf52840dk_nrf52840
│
▼
┌─────────────────────────────┐
│ Step 3: Enable UART Logging │
│ Confirm printk() output │
│ Serial text visible? │
└─────────┬───────────────────┘
│
Pass?├──── No ──→ Try other COM port, confirm 115200 baud 8N1
│
▼
┌─────────────────────────────┐
│ Step 4: Init BLE Stack │
│ Flash peripheral_hr sample │
│ Stack init messages in log? │
└─────────┬───────────────────┘
│
Pass?├──── No ──→ Check SDK version, board config, build errors
│
▼
┌─────────────────────────────┐
│ Step 5: Verify Advertising │
│ Open nRF Connect mobile app │
│ "Nordic_HRM" in scan list? │
└─────────┬───────────────────┘
│
Pass?├──── No ──→ Confirm BLE is enabled on phone, retry scan
│
▼
┌───────────┐
│ ✓ Done │
│ BLE is │
│ working │
└───────────┘What the peripheral_hr Sample Actually Did
Your device is advertising and connecting. Here’s what happened under the hood, in the order it happened:
Zephyr’s boot sequence ran first, initializing clocks (starting the HFXO and LFXO), configuring GPIO pins, and setting up interrupt handlers. You didn’t write any of this. Zephyr’s board support package for the nRF52840 DK handled it based on the devicetree configuration.
The BLE Controller (the lower half of the BLE stack) took control of the radio hardware, configuring it for BLE operation on the 2.4 GHz band with frequency hopping across 40 channels.
The BLE Host (the upper half of the stack) initialized GAP (Generic Access Profile, which controls advertising and connections) and GATT (Generic Attribute Profile, the framework for services and characteristics that exchange data).
Your application code defined a Heart Rate service, registered it with the GATT layer, and called a function to start advertising.
This layered architecture is the entire reason SDKs exist. You wrote application logic. Four layers of infrastructure made it work. Your next step is modifying this sample, changing the device name, adding a custom service, or adjusting advertising parameters, to learn how each layer responds.
Pitfalls That Catch Every Beginner
- Wrong board target. Building for
nrf52dk_nrf52832when you have an nRF52840 DK means the firmware targets the wrong chip. Always selectnrf52840dk_nrf52840. - Mixing up SDKs. A tutorial using
#include "nrf_sdh.h"is the legacy nRF5 SDK. NCS/Zephyr code uses#include <zephyr/bluetooth/bluetooth.h>. These are not interchangeable. - Serial port confusion. The DK exposes multiple COM ports. If you see no output, try the other port. Confirm 115200 baud, 8N1.
- Skipping the DK. Custom boards introduce antenna tuning, power design, and programming header issues simultaneously. Use the DK until your firmware is solid.
- Writing BLE code from a blank file. Always start by modifying a working sample. Nordic’s examples exist for exactly this purpose.
Your First BLE Device Is Working. Here’s Where to Go Next.
You now understand the six essential components in any BLE circuit, have a working nRF Connect SDK toolchain, and have a device that’s advertising and accepting connections. More importantly, you’ve learned the bringup methodology (verify power, then GPIO, then logging, then the BLE stack) that scales to every embedded project you’ll ever work on.
From here, three paths will accelerate your learning fastest:
- Customize BLE services and characteristics by modifying the
peripheral_hrsample to expose your own data. (See: Customizing BLE Services — coming soon) - Learn BLE connection parameters (intervals, latency, timeout) to understand the power/performance tradeoffs that define every BLE product. (See: BLE Protocol Fundamentals — coming soon)
- Move from the DK to a custom PCB when your firmware is stable and you’re ready to tackle hardware integration for real. (See: From Dev Kit to Custom BLE Hardware — coming soon)
Every commercial BLE product on the market went through the same sequence: dev kit, working firmware, then custom hardware. You just completed step one. Keep going.
Hubble Network connects your BLE devices directly to millions of gateways across the world and in space-no hardware changes required. See how it works →