BLE
Let’s take a look at the hierarchy of the system we are about to design:
graph LR subgraph "DevBoard (Rust)" subgraph "Front End" A2(LED) end subgraph "Back End" B2(BLE) C2(Events) D2(Logic) end B2 --> C2 --> D2 --> A2 D2 --> B2 end subgraph "Phone (Swift)" subgraph "Front End" A1(UI) B1(Alerts) end subgraph "Back End" C1(Delegate) D1(Logic) E1(BLE) end A1 --> C1 --> D1 <--> E1 D1 --> B1 end B2 <--> E1
Now, I know this looks complicated, but we will tackle each block one by one, nice and slow.
Once you are done with this, you will have a solid understanding of creating systems involving bidirectional communication between 2 devices, which is super useful for a ton of applications (including your final project).
So let’s get started.
How Does BLE Work?
Modern BLE (Bluetooth Low Energy) systems rely on the Service -> Characteristic architecture.
Your iPhone can scan for BLE devices advertising services, to decide whether to connect to them or not.
A service is like an Object, it contains states, and represents some kind of data or behavior.
Services contain characteristics, which are the states of the service. You can configure characteristics to be readable and writable.
In this case, we will have one service with one characteristic: LED.
Here is a flowchart of how our BLE system will work:
flowchart TD P(Peripheral) --> L subgraph "Client (iPhone)" C(Central Manager) --> P end subgraph "Server (ESP32)" subgraph Services L(MyFirstService) --> R L --> G L --> B subgraph Characteristics R(C0) G(C1) B(C2) end end end
This layout is called GATT (Generic ATTribute Profile)