Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Discover and connect to Bluetooth Low Energy (BLE) peripheral devices from MATLAB. Use this skill when the user wants to scan for BLE devices, connect to a BLE peripheral, read or write BLE characteristics, subscribe to notifications, or any task that requires a BLE connection as a prerequisite (e.g., read sensor data over BLE, monitor heart rate, log accelerometer, stream data from wearable, IoT device communication). Triggers on: BLE, Bluetooth Low Energy, blelist, ble device, BLE characterist
.claude/skills/matlab-matlab-connect-ble/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 126% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 68% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 86% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 114% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 100% | 0% |
Guides the agent through discovering, connecting to, and accessing characteristics on BLE peripheral devices, ensuring efficient use of filtering APIs and correct function signatures.
BLE functions are part of MATLAB — no additional toolbox is required. Do not reference the Bluetooth Toolbox for BLE functionality — it is not needed.
IoT communication, wearable monitoring)
characteristic UUID
bluetooth() object — different API)matlab-connect-arduino)Follow these steps in order. Do not skip steps or guess values.
Always check first — a connected BLE device stops advertising, so scanning will never find it:
matlab% Check for existing ble objects in workspace bleVars = whos; bleVars = bleVars(strcmp({bleVars.class}, 'ble'));
If a ble object exists and its Connected property is 1:
If a ble object exists but Connected is 0, it is stale — proceed to Step 1.
Use filtered scanning when possible. Do not scan all devices and then search through results manually.
| User provides | Use this call | |---------------|---------------| | Device name | blelist("Name", "<name>") | | Service UUID | blelist("Services", "<uuid>") | | Nothing specific | blelist("Timeout", 10) |
matlab% Filter by name (prefix match) devices = blelist("Name", "HeartSensor"); % Filter by advertised service UUID devices = blelist("Services", "180D"); % General scan with extended timeout devices = blelist("Timeout", 10);
Filters can be combined:
matlabdevices = blelist("Name", "Sensor", "Timeout", 15);
blelist returns a table with columns: Name, Address, RSSI, Advertisement. Results are sorted by signal strength (strongest first).
Present results to the user.
If blelist returns an empty table:
therefore not advertising).
and advertising?"
LightBlue, another MATLAB session)
blelist("Timeout", 20)is available.
Present the discovered devices and ask which to connect to. Never auto-select a device.
If only one device matches a filtered scan (e.g., blelist("Name","MyDevice") returned exactly one row), confirm with the user: "Found Name] at Address]. Shall I connect?"
matlab% Connect by name (substitute the user's actual device name) b = ble("HeartSensor"); % Connect by address (use when name is empty or ambiguous) b = ble("A1B2C3D4E5F6");
After connecting, confirm to the user:
If the connection succeeds but a service shows "Access denied":
connection to the same device. The Windows BLE stack denies access to services that are already claimed.
clear bin the other session, or close it), then reconnect from this session.
the cause for custom services that previously worked.
If the connection fails entirely:
Bluetooth adapter disabled
Inspect available services and characteristics:
matlab% View all services b.Services % View all characteristics (includes service, name, UUID, attributes) b.Characteristics
To access a specific characteristic, use the two-UUID signature:
matlab% Access by service UUID + characteristic UUID c = characteristic(b, "<serviceUUID>", "<characteristicUUID>"); % Access by service name + characteristic name (standard services only) c = characteristic(b, "Battery Service", "Battery Level");
Important: characteristic() always requires both a service identifier and a characteristic identifier. Never call it with just one UUID.
Never invent or assume device names, addresses, service UUIDs, or characteristic UUIDs. Use only values provided by the user or discovered from blelist / b.Characteristics.
If characteristic access fails:
b.Characteristicsto find the correct service and characteristic UUIDs.
Step 3: disconnect from other sessions first).
matlab% Read raw bytes from a characteristic (returns numeric array) data = read(c); % Read with timestamp [data, timestamp] = read(c); % Read oldest buffered notification (use in DataAvailableFcn callbacks) data = read(c, "oldest"); % Write data to a characteristic write(c, [1 0 1 0]); % Write without response (faster, no confirmation) write(c, [1 0 1 0], "WithoutResponse"); % Subscribe to notifications subscribe(c); c.DataAvailableFcn = @(src, evt) disp(read(src)); % Unsubscribe unsubscribe(c);
read and write operate on characteristic objects, not on the ble object directly. Never use read(b, uuid) — this will error.
| Function | Purpose | |----------|---------| | blelist | Scan for BLE peripherals (with optional Name/Services/Timeout filters) | | ble(name) | Connect to a BLE device by advertised name | | ble(address) | Connect to a BLE device by MAC address | | characteristic(b, svcID, charID) | Access a characteristic (requires both service and characteristic identifiers) | | read(c) | Read data from a characteristic object | | write(c, data) | Write data to a characteristic object | | subscribe(c) | Subscribe to notifications/indications | | unsubscribe(c) | Unsubscribe from notifications/indications |
All functions are part of MATLAB — no toolbox required.
matlab% TEMPLATE — not executable without hardware % Step 0: Check workspace bleVars = whos; bleVars = bleVars(strcmp({bleVars.class}, 'ble')); % Step 1: Filtered discovery devices = blelist("Name", "TempLogger"); % Step 3: Connect b = ble("TempLogger"); % Step 4-5: Access and read custom characteristic c = characteristic(b, "181A", "2A6E"); data = read(c);
matlab% TEMPLATE — not executable without hardware % Find devices advertising a specific service devices = blelist("Services", "180D"); % Connect to the first match (after user confirms) b = ble(devices.Name(1)); % List characteristics under that service b.Characteristics
matlab% TEMPLATE — not executable without hardware % Check if 'b' already exists and is connected if exist('b', 'var') && isa(b, 'ble') && b.Connected disp("Reusing existing connection to " + b.Name); else b = ble("MyDevice"); end % Access characteristic on existing connection c = characteristic(b, "180F", "2A19"); batteryLevel = read(c);
matlab% TEMPLATE — not executable without hardware c = characteristic(b, "180D", "2A37"); subscribe(c); c.DataAvailableFcn = @(src, evt) processHeartRate(read(src)); % Later: clean up unsubscribe(c);
When the user wants to log or collect BLE data over a time period, use DataAvailableFcn with subscribe/unsubscribe — do not poll with read(c) in a loop (polling misses data between reads and may flush the buffer).
Deploy scripts/bleDataCollector.m to the user's working directory and run:
matlab% TEMPLATE — not executable without hardware % Log notifications to a tab-separated text file for 10 seconds: bleDataCollector(b, "<serviceUUID>", "<charUUID>", 10, "sensorLog.txt")
Output file format (one row per notification):
2026-06-25 10:30:01.0529 3 12 255
2026-06-25 10:30:01.2478 4 13 0Key points for notification-based logging:
DataAvailableFcn to a callback that calls read(src, "oldest") —using "oldest" reads buffered notification data in order; "latest" may flush and lose earlier packets
subscribe(c) to start receiving notifications, unsubscribe(c) tostop
pause(duration) keeps MATLAB alive while callbacks fire — this is NOTpolling, it is the idle loop that allows notifications to be delivered
unsubscribe, clear DataAvailableFcn, and fclose when done.txt with tab separation — BLE packets vary in length, sofixed-column CSV is impractical
Script: scripts/bleDataCollector.m (bundled with this skill — deploy to the user's working directory before use)
| Mistake | Why It's Wrong | Correct Approach | |---------|---------------|-----------------| | Using unfiltered blelist when name/service is known | Scans all devices unnecessarily; slower and noisier | Use blelist("Name","...") or blelist("Services","...") | | Calling read(b, uuid) on the ble object | read works on characteristic objects, not ble objects — will error | Create characteristic first: c = characteristic(b, svc, char), then read(c) | | Using blescanner | This function does not exist in MATLAB | Use blelist (with optional name-value filters) | | Saying BLE requires "Bluetooth Toolbox" | BLE functions are part of MATLAB — no toolbox needed | Do not check for or reference the Bluetooth Toolbox | | Scanning for a device that is already connected | Connected devices stop advertising — scan will never find them | Check workspace for existing ble objects first (Step 0) | | Calling characteristic(b, uuid) with one UUID | Requires both service and characteristic identifiers | Use characteristic(b, serviceUUID, characteristicUUID) | | Auto-selecting a device without user confirmation | User may have multiple devices; wrong choice wastes time | Always present options and ask which device to connect to | | Diagnosing "Access denied" as a pairing issue | Usually caused by another session holding the connection, not missing pairing | Ask user to disconnect from other MATLAB sessions first |
ble connections before scanning — connected devices stop advertisingblelist when name or service UUID is known — never scan all and search manuallyread/write/subscribe operate on characteristic objects, not ble objectscharacteristic() requires two identifiers: service + characteristicCopyright 2026 The MathWorks, Inc.
Other measured skills in the registry, with their headline benchmark lift.