100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Bluetooth Communication with Arduino

How to add wireless links to Arduino projects using Classic Bluetooth serial modules like the HC-05 and Bluetooth Low Energy on the ESP32, including pairing and data exchange.

Communication & LibrariesIntermediate10 min readJul 10, 2026
Analogies

Two Flavors of Bluetooth

Bluetooth on Arduino comes in two distinct forms. Classic Bluetooth (BR/EDR) creates a continuous serial-style link, perfect for streaming a steady flow of data such as sensor readings to a phone terminal app. Bluetooth Low Energy (BLE) is a newer, power-sipping protocol built around short bursts of data exchanged through structured attributes, ideal for battery devices like fitness bands and beacons. They are not interoperable: a BLE central cannot talk to a Classic device and vice versa, so choosing the right one up front matters. For an Uno you typically add a module like the HC-05 (Classic); the ESP32 supports both in firmware.

🏏

Cricket analogy: Classic vs BLE is like Test cricket's continuous grind versus T20's short explosive bursts, two formats for different demands.

Classic Bluetooth with HC-05 Modules

The HC-05 is the workhorse Classic module for Arduino. It exposes a UART serial interface: you wire its TX and RX pins to the Arduino (often through SoftwareSerial on an Uno so the hardware UART stays free for the USB monitor), pair it from your phone with a PIN like 1234, and then data written to the serial port simply arrives on the other side. From the sketch's perspective it feels exactly like Serial.print(), which is why it is so beginner-friendly. AT commands let you rename the module, change the PIN, or set the baud rate while it is in command mode, entered by holding its EN/KEY pin high at power-up.

🏏

Cricket analogy: The HC-05 behaving like a plain serial port is like a wireless mic on the commentator: they speak normally and the words travel unchanged.

cpp
#include <SoftwareSerial.h>

SoftwareSerial bt(10, 11); // RX, TX to HC-05 TX, RX

void setup() {
  Serial.begin(9600);
  bt.begin(9600);          // HC-05 default baud
}

void loop() {
  // Forward phone -> Arduino
  if (bt.available()) {
    char c = bt.read();
    Serial.write(c);
  }
  // Forward Arduino -> phone
  if (Serial.available()) {
    char c = Serial.read();
    bt.write(c);
  }
}

The HC-05's RX pin is 3.3 V tolerant, but the Uno's TX outputs 5 V. Drive the module's RX through a voltage divider (e.g. 1 kΩ and 2 kΩ resistors) or a level shifter. Feeding raw 5 V into the RX pin can overstress the module over time.

Bluetooth Low Energy on the ESP32

BLE structures data differently from a serial stream. A device acts as a peripheral advertising one or more services, each identified by a UUID and containing characteristics that hold readable, writable, or notifiable values. A central device such as a phone app scans, connects, and then reads or subscribes to those characteristics. On the ESP32 the BLEDevice API lets you create a server, add a service and characteristic, and push updates via notify() so the phone is alerted only when data changes. This attribute-and-notification model is why BLE sensors sip so little power: the radio wakes briefly to advertise or notify, then sleeps.

🏏

Cricket analogy: BLE characteristics with UUIDs are like each player's fixed jersey number: the scoreboard subscribes to number 18 and gets only Kohli's runs.

cpp
#include <BLEDevice.h>
#include <BLEServer.h>

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

BLECharacteristic* pChar;

void setup() {
  BLEDevice::init("ESP32-Sensor");
  BLEServer* server = BLEDevice::createServer();
  BLEService* service = server->createService(SERVICE_UUID);
  pChar = service->createCharacteristic(
      CHARACTERISTIC_UUID,
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
  service->start();
  BLEDevice::getAdvertising()->start();
}

void loop() {
  pChar->setValue("23.5");
  pChar->notify();   // push to subscribed central
  delay(2000);
}

Reuse before you rebuild: the ESP32 also offers a BluetoothSerial (Classic SPP) API that mimics the HC-05's transparent serial behavior, so you can port HC-05 sketches with minimal changes when you don't need BLE's low-power notification model.

  • Classic Bluetooth gives a continuous serial link; BLE exchanges structured attributes in low-power bursts.
  • Classic and BLE are not interoperable, so choose based on data pattern and power needs.
  • The HC-05 exposes a UART interface and behaves like Serial.print, often via SoftwareSerial on an Uno.
  • AT commands (in command mode) rename the module, change PIN, or set baud rate.
  • Level-shift the HC-05 RX pin because the Uno's 5 V TX exceeds its 3.3 V input.
  • BLE uses services and characteristics identified by UUIDs, with notify() pushing changes.
  • The ESP32 supports both BLE (BLEDevice) and Classic SPP (BluetoothSerial) in firmware.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#ArduinoProgrammingStudyNotes#BluetoothCommunicationWithArduino#Bluetooth#Communication#Arduino#Two#StudyNotes#SkillVeris#ExamPrep