Skip to content

What is Bluetooth?

The tinyCore ESP32-S3 has built-in Bluetooth Low Energy (BLE) — a wireless protocol designed for low-power, short-range communication with phones, computers, and other devices. BLE is how fitness trackers send step counts to your phone, how wireless game controllers connect to PCs, and how smart home sensors report data.

BLE lets your tinyCore talk to phones and computers without WiFi or a router. Build a phone-controlled RGB light, stream sensor data to a custom app, or turn the tinyCore into a wireless game controller that any PC or phone recognizes as a standard Bluetooth device. All without installing special drivers.

BLE defines two primary roles:

  • Peripheral (your tinyCore) — advertises its presence and accepts connections
  • Central (your phone) — scans for peripherals and initiates connections

Your tinyCore broadcasts short advertising packets saying “I’m here, this is what I do.” A phone scanning nearby detects these packets and can connect.

Once connected, data is organized into a hierarchy called GATT (Generic Attribute Profile):

LevelWhat It IsExample
ServiceA group of related data, identified by a UUID”Environmental Sensing”
CharacteristicA single data value with read/write/notify properties”Temperature”
DescriptorMetadata about the characteristic”Enable notifications”

Your tinyCore acts as the GATT Server — it holds the data. Your phone acts as the GATT Client — it reads, writes, or subscribes to updates.

When a characteristic has the Notify property, the tinyCore pushes updates to the phone automatically — no polling needed. This is how fitness trackers stream heart rate data in real time.

Before any connection happens, the tinyCore broadcasts advertising packets on three dedicated channels. These packets carry up to 31 bytes of data — enough for a device name, service UUIDs, and basic info. The advertising interval is configurable (20 ms to 10.24 seconds): shorter = faster discovery but higher power draw.

Phone-controlled hardware. The tinyCore exposes a writable characteristic; your phone app sends color values, speed commands, or control signals. The firmware reads them and drives LEDs, motors, or relays.

Sensor data streaming to phone. Read a sensor on the tinyCore, update a characteristic, and notify the connected phone in real time. This is how commercial fitness trackers and environmental monitors work.

Wireless game controllers. Using the HID over GATT profile, the tinyCore can appear as a standard BLE gamepad or keyboard to PCs, phones, and TVs. The ESP32-BLE-Gamepad library supports up to 128 buttons and multiple axes.

Proximity triggers. Scan for BLE advertisements and read the RSSI (signal strength). When a known device gets close enough, trigger an action — unlock a door, turn on lights, start a display.

BLE sensor gateway. The tinyCore can also act as a Central, connecting to external BLE sensors (heart rate monitors, environmental sensors) and aggregating their data.

nRF Connect (Nordic Semiconductor) — the standard BLE debugging tool. Scans devices, shows raw advertising data, lets you browse services, read/write characteristics, and subscribe to notifications. Free on Android and iOS. Start here when testing your BLE project.

LightBlue (Punch Through) — similar to nRF Connect, plus a virtual peripheral mode that turns your phone into a simulated BLE device. Free on iOS, macOS, and Android.

MIT App Inventor — build custom Android apps with drag-and-drop blocks that talk to your tinyCore over BLE. Uses an official BluetoothLE extension.

Flutter / React Native — for production apps, use flutter_reactive_ble (maintained by Philips Hue) or react-native-ble-plx for cross-platform BLE.

The ESP32-S3 supports BLE 5.0 with 2M PHY (2 Mbps for faster transfers), Coded PHY (extended range at lower speed), and extended advertising.

Two BLE stacks are available. NimBLE is strongly recommended — it uses roughly half the flash space and frees ~100 KB more RAM than Bluedroid:

BluedroidNimBLE
Flash usage~1,216 KB~617 KB
Free heap after connection~171 KB~270 KB
Max connections79

For Arduino, install the NimBLE-Arduino library (by h2zero) as a drop-in replacement for the default BLE library.

StateCurrent
Deep sleep~8 µA
BLE TX (0 dBm)~100–130 mA
Advertising (between packets)~100 mA without light sleep

Typical indoor range is 10–30 meters with standard 1M PHY.

Device not showing up on phone scans

  • Verify startAdvertising() is actually being called in your code
  • Keep device names under 15 characters (the 31-byte advertising packet fills up fast)
  • Android requires Location permission (BLUETOOTH_SCAN on Android 12+) — without it, scans silently return nothing

GATT stale cache (the invisible killer) When you change your firmware’s services or characteristics and re-flash, the phone still uses its cached GATT layout from before. Everything looks connected but data doesn’t flow correctly.

  • Android fix: Settings → Apps → Bluetooth → Storage → Clear Cache
  • iOS fix: “Forget This Device” in Bluetooth settings, then reconnect

Connection drops

  • Increase supervision timeout to 2–4 seconds
  • Check for 2.4 GHz interference (WiFi, microwaves)
  • Don’t call delay() inside BLE callbacks — it can trigger watchdog resets
  • Check Serial Monitor for reboot messages

iOS quirks

  • iOS does not show BLE devices in system Bluetooth settings — users must connect through your app or nRF Connect
  • iOS hides the real MAC address, assigning a random per-app identifier instead
  • iOS aggressively caches GATT tables with no user-facing way to clear
  • MTU negotiation: iOS handles it automatically, but on Android you must call requestMtu(). Default MTU is 23 bytes (20 usable) — if you’re sending more than 20 bytes per write without negotiating a larger MTU, data gets silently truncated
FeatureESP32-S3
BLE version5.0
Classic BluetoothNot supported
PHY modes1M, 2M, Coded
Max TX power20 dBm
Indoor range10–30 m (1M PHY)
Recommended stackNimBLE
Max connections (NimBLE)9
Arduino libraryNimBLE-Arduino (by h2zero)

DroneBot Workshop — ~38 minutes. Covers BLE vs Classic differences, GAP/GATT concepts, and hands-on Arduino IDE examples for BLE server and client. Companion article with downloadable code at dronebotworkshop.com.