Skip to content

BLE for Edge Products

Course 1 · Module 7 Suggested time: about 3–3.5 hours (concepts + peripheral status/ADV + a host demo) Format: a hands-on lesson — comparing with MQTT (M06), connecting a local host over BLE

Lab · Cheatsheet · ← Table of Contents · ← M06 · M08 →

Note: which firmware the code in this lesson is written for (checked on 2026-09-26)

The C code in this lesson calls the API of the TESAIoT Bitstream firmware, called “TESA Firmware SDK” in the original, which is published as a ready-made HEX file (tesaiot-bitstream-<version>.hex) alongside Bitstream Studio in the TESAIoT_Hackathon lab pack. The source code of this firmware is not yet public. Functions such as cm55_ble_periph_status_get_sync, cm55_ble_periph_adv_ctrl_sync, cm55_trigger_ble_periph_*, cm55_ble_request_scan_* and cm55_ble_ipc_set_event_handler therefore have no header you can open or build yourself. Read the snippets as concepts and a calling order. The calls to FreeRTOS and the Infineon PDL (such as xTaskCreate, vTaskDelay, Cy_GPIO_*) are ordinary public APIs.

If you want code you can read and build from open source, see tesaiot-pse84-devkit-sdk (Apache-2.0), which is a different codebase with different API names. An example already checked to do the same job as this lesson (commit ef72c1b):

  • proj_cm33_ns/examples/ble/01_nus_bring_up_and_talk.c — a BLE peripheral using the Nordic UART Service: advertise, read the link status, and send data (ble_nus_init, ble_nus_get_state, ble_nus_rearm_advertising, ble_nus_send) — this file itself notes that it still runs on a template that cannot be delivered, because libbento_secure.a is not yet in LDLIBS

No equivalent found yet in the public SDK: the scan / observer path (cm55_ble_request_scan_*) — ble_nus in the SDK is a peripheral-only role

The ble-flet host is not yet published — the TESAIoT_Hackathon README (commit f5f09a6) states that python-app/, ble-react/ and ble-flet/ belong to the maintainers and are not in the public repo. Use the backup path the lesson already suggests: a general GATT explorer such as nRF Connect, LightBlue, or AIROC™ Bluetooth® Connect


By the end of this lesson you should be able to:

  1. Explain the role of BLE in an edge product (local / phone / desktop) compared with MQTT (cloud / broker)
  2. Explain the key terms: GAP, GATT, Peripheral, Central, Advertising, Connection, Notification
  3. Point out that in the TESA Firmware SDK, the CM33 owns the BLE stack and the CM55 drives it over IPC
  4. Read the peripheral’s status with cm55_ble_periph_status_get_sync / cm55_get_ble_periph_status
  5. Control advertising with cm55_ble_periph_adv_ctrl_sync (stop / start / restart)
  6. Explain the scan path (the CM55 requests a scan → the CM33 reports the result) for observer mode
  7. Use a lab host: TESAIoT_Hackathon ble-flet/, or a general GATT scanning app
  8. Do the exercise on the real board and keep evidence of the link

The snippets in this lesson reference function names from the TESA Firmware SDK — use them together with an example project, or an example on the Developer Hub. More hosts: TESAIoT Developer Hub · Hackathon BLE · Bitstream Studio

Document Use when
Bluetooth LE overview (Bluetooth SIG) The GAP / GATT concepts
Infineon Find Me CE (PSoC Edge) A vendor example (peripheral + mobile app)
TESAIoT_Hackathon — ble-flet A desktop BLE dashboard (scan → connect → stream)
Bitstream Studio The main host, usually using USB/UART; compare against the BLE lab
M06 — MQTT A comparison point for cloud connectivity
M04 — RTOS A task that waits on status / calls IPC

Bluetooth Low Energy (BLE) is a short-range, low-power radio, suited to a phone, tablet, or desktop near the board — no Wi‑Fi or broker needed.

Term Meaning
Peripheral The device that advertises and waits for a host to connect (the TESA board is usually this role)
Central The host that scans and connects (phone / PC / ble-flet)
GAP The discovery-and-connection layer (the ADV name, address, connection)
GATT The service/characteristic layer (Service / Characteristic / Notify / Write)
Advertising Announcing yourself over the air before any connection exists
Notification The peripheral sends data to the Central without waiting to be polled every time
BLE MQTT
Range Close (a room / a desk) Over a network / the cloud
Middle bridge No broker required Requires a broker
Power / setup No need to join Wi‑Fi Needs Wi‑Fi (+ TLS if MQTTs)
Lab host ble-flet, nRF Connect, the AIROC app MQTTX, the Studio broker, the web-app
In the Capstone (M08) The local path The cloud path

Key phrase MQTT carries data up onto a network — BLE carries data into a nearby phone/PC.

Further reading: Bluetooth LE tech overview


On the Evaluation Kit, the radio is usually an AIROC™ Wi‑Fi & Bluetooth® combo — the BLE stack runs on the CM33; the sensor app on the CM55 drives it through IPC.

Role Core API learners call often
The BLE stack + a GATT peripheral CM33 ble_periph_* (the real owner)
Status / commanding ADV from the app CM55 cm55_trigger_ble_periph_*, cm55_ble_periph_*_sync
Scanning (observer) CM33 runs the scan · CM55 requests it and receives events cm55_ble_request_scan_*, cm55_ble_ipc_set_event_handler
BS2 over BLE (a lab host) The CM33 bridge + a host GATT client The host: the Hackathon ble-flet
[Phone / PC central] ──GATT──► [BLE peripheral on CM33]
▲
│ IPC
│
[App on CM55]
cm55_trigger_ble_periph_*
cm55_ble_request_scan_*

Honest note Wi‑Fi (M06) and BLE share the same radio on many kits — don’t expect maximum throughput on both at once without testing coexistence in a real room.


Before “connecting to a phone”, confirm the BLE profile on the firmware is working.

The status structure (a summary of its important fields):

typedef struct {
uint8_t profile_ble_active;
uint8_t manager_inited;
uint8_t stack_ready;
uint8_t tx_notify_enabled;
uint32_t last_error;
uint16_t connection_id; /* 0 = no link */
} ipc_ble_periph_status_t;
Section titled “Reading the status synchronously (recommended in the lab)”
#include "cm55_ipc_app.h"
#include "ipc_ble_periph_types.h"
ipc_ble_periph_status_t st;
if (cm55_ble_periph_status_get_sync(&st, 5000U)) {
/* check stack_ready, connection_id, tx_notify_enabled */
} else {
/* timeout / IPC did not respond — check the firmware has the BLE profile on */
}

Or fire the request without waiting, and read the snapshot later:

(void)cm55_trigger_ble_periph_status_get();
/* … wait for the event / a short delay … */
(void)cm55_get_ble_periph_status(&st);
Field Approximate meaning
profile_ble_active This build’s BLE profile is turned on
manager_inited / stack_ready The stack is ready
tx_notify_enabled The Central has turned on notify (the link is genuinely in use)
connection_id A GATT connection exists when this is not 0
last_error The most recent error code (0 = normal)

Advertising makes the device visible to a Central — the name in TESA labs usually starts with TESAIoT-

uint8_t result = 0xFF;
/* action: 0 = stop, 1 = start, 2 = restart */
if (cm55_ble_periph_adv_ctrl_sync(1U, &result, 5000U)) {
/* result 0 = ok, per the bridge */
}
action Meaning
0 Stop advertising
1 Start advertising
2 Restart advertising (worker-safe)

Key phrase from the firmware While a connection exists, stopping ADV does not cut the link — and starting ADV may not be necessary since it’s already connected.

If the host doesn’t see the device after being on for a long time: check the ADV timeout / reboot the board (the Hackathon ble-flet README describes this symptom).


When the role is scanning for other devices (not just being a peripheral):

#include "cm55_ipc_app.h"
static void on_ble_ipc(const ipc_msg_t *msg, void *user)
{
(void)user;
/* classify the event by IPC_EVT_BLE_*'s cmd */
}
void ble_scan_lab_start(void)
{
cm55_ble_ipc_set_event_handler(on_ble_ipc, NULL);
cm55_ble_request_scan_all(); /* or scan_name / scan_addr */
/* stop with a scan-stop command per the SDK example once time's up */
}

Common helpers:

API Use when
cm55_ble_request_scan_all A full scan, no filtering
cm55_ble_request_scan_name Filtering by a partial name
cm55_ble_request_scan_addr Filtering by a 6-byte address
cm55_ble_ipc_set_event_handler Receiving scan results/status in a task

Examples in this firmware are usually named around example_ble (toggling scan on/off periodically) — see them on the Developer Hub / the firmware’s example project.


The TESAIoT_Hackathon pack has a desktop app built with Python + Flet + bleak:

  1. Flash a HEX with the BLE module profile turned on
  2. Run ble-flet per the repo’s README
  3. The app will hunt for a name starting with TESAIoT-* → connect → stream

Suited to a lab that needs live evidence, without relying on Web Bluetooth in a browser.

  • nRF Connect / LightBlue / AIROC™ Bluetooth® Connect (per the Infineon Find Me example)
  • Use these to confirm the device advertises and connects, even before decoding BS2

Bitstream Studio is the course’s main host for USB/UART and MQTT — in M07 it is used as a comparison point for when to choose local BLE instead of a cable or a broker.

The lab host references the BS2 family’s service/characteristic (a UUID fixed in ble-flet), and an ADV name starting with TESAIoT- — don’t hardcode the UUID in your deliverable documents unless you need to; instead, state which version of the Hackathon pack you used.


Topic Practice
Pairing / bonding The lab usually uses a short link — don’t assume it’s production-grade secure pairing
Data over the air BLE doesn’t go through a broker, but is still within the radio range of the lab room
Secrets There is no Wi‑Fi password in this path — but other credentials still must not be embedded in public files
A single Central Don’t open nRF Connect and ble-flet at the same time on one machine, both pointed at the same board

8. Design Patterns for Capstone (Preview M08)

Section titled “8. Design Patterns for Capstone (Preview M08)”

Choose at least one connectivity path in the Capstone:

Sensor task ──► window/filter ──► LED/UART
│
┌───────────┴───────────┐
▼ ▼
MQTT publish (M06) BLE notify / host (M07)
MQTT subscribe cmd BLE write / command

M08’s minimum bar: MQTT or BLE — using both is a bonus.


Symptom Common cause
The scan finds nothing The BLE profile is off · not advertising yet · the ADV timed out · too far away / interference
Status sync times out The CM33 isn’t ready yet · IPC hasn’t come up · the build has no BLE
It connects, then drops Another Central grabbed it · the board rebooted · a firmware policy timeout
Wi‑Fi + BLE together behave oddly Combo radio coexistence — test them separately before combining
Confused with MQTT A different transport layer entirely — don’t go looking for a broker in a BLE lab

  1. Do the lab: Lab
  2. Keep the summary sheet: ble-connectivity.md
  3. When ready, continue to M08 — Capstone (M08 lesson)

  1. Bluetooth LE overview
  2. Infineon mtb-example-psoc-edge-btstack-findme
  3. Infineon BLE + Wi‑Fi IoT gateway CE
  4. TESAIoT_Hackathon (ble-flet/)
  5. TESAIoT Developer Hub
  6. Bitstream Studio
  7. M06 MQTT · M08 Capstone
  8. PSOC™ Edge E84

Three short questions in quiz.yaml, one per objective of this lesson. Try answering them yourself first, then compare with the answer key and explanations in the file.

Continue hands-on at Lab: BLE connectivity

Lab · Cheatsheet · ← Table of Contents · ← M06 · M08 →

Review questions

Answer on your own first, then open the answer.

  1. ข้อใดตรงกับ Key phrase ของบทเรียนเรื่อง BLE กับ MQTT (Objective 1)

    1. MQTT พาข้อมูลขึ้นเครือข่าย ส่วน BLE พาข้อมูลเข้ามือถือหรือพีซีที่อยู่ใกล้
    2. BLE ต้องมี broker เสมอ
    3. MQTT ไม่ต้องใช้ Wi-Fi
    4. BLE กับ MQTT เป็นชั้นขนส่งเดียวกัน
    Show answer

    Answer: A. MQTT พาข้อมูลขึ้นเครือข่าย ส่วน BLE พาข้อมูลเข้ามือถือหรือพีซีที่อยู่ใกล้

    Key phrase ในหัวข้อ BLE vs MQTT และตาราง Common Pitfalls: คนละชั้นขนส่ง อย่าหา broker ในแล็บ BLE

  2. อุปกรณ์ที่ “สแกนแล้วเชื่อม” เช่นโทรศัพท์หรือพีซี มีบทบาทใด (Objective 2)

    1. Advertising
    2. Notification
    3. Central
    4. Peripheral
    Show answer

    Answer: C. Central

    ตารางในหัวข้อ 1: Central คือโฮสต์ที่สแกนแล้วเชื่อม ส่วนบอร์ดมักเป็น Peripheral ที่ advertise

  3. ในเฟิร์มแวร์ของบทเรียนนี้ BLE stack รันบนคอร์ใด (Objective 3)

    1. CM33 โดย CM55 สั่งงานผ่าน IPC
    2. CM55 โดยตรง
    3. Ethos-U55
    4. NNLite
    Show answer

    Answer: A. CM33 โดย CM55 สั่งงานผ่าน IPC

    หัวข้อ 2: สแต็ก BLE รันบน CM33 ส่วนแอปเซ็นเซอร์บน CM55 สั่งผ่าน IPC

Cite this lesson

If you teach from this lesson or reuse it in slides or documents, credit it with the text below. If you changed it, add (adapted) after the title.

"BLE for Edge Products" from TESA Open Knowledge by the Thai Embedded Systems Association (TESA), https://github.com/tesaiot/tesa-qualification-program, licensed under CC BY-NC 4.0

Thai attribution: "BLE สำหรับผลิตภัณฑ์ Edge" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0

Lesson link: https://tesaiot.github.io/tesa-qualification-program/en/courses/firmware-sdk-edge-ai/m07-ble/l01-ble-connectivity/

This lesson adapts the source below; keep its credit too.
https://github.com/drsanti/TESAIoT-Courses/blob/287c21814ba8c75f693136616dcd270349a15966/C1/M07/README.md · Original content by Asst. Prof. Dr. Santi Nuratch (ผศ.ดร.สันติ นุราช), KMUTT. Course 1 (C1/) of drsanti/TESAIoT-Courses. TESA funded the work and holds the rights; published here under CC BY-NC 4.0. The upstream repository carries no licence file. Text kept faithful; structure, front matter, quizzes and notes added by TESA Open Knowledge.

Full guide: how to cite TESA

TESA Open Knowledge · © 2026 สมาคมสมองกลฝังตัวไทย (TESA) · CC BY-NC 4.0

Content is licensed CC BY-NC 4.0. Reuse it non-commercially and credit the Thai Embedded Systems Association (TESA) every time. · How to cite TESA