Ovládání přes Web Bluetooth
Díl třetí: BT ovládání ESP32 z webové stránky
V článku si ukážeme, jak vcelku elegantně ovládat ESP32 přes BLE – a to přímo z webového prohlížeče. Díky Web Bluetooth API můžeme vytvořit ovládací panel v HTML a JavaScriptu, který ke komunikaci s mikrokontrolerem nepotřebuje žádnou instalovanou aplikaci.
Postačí nám k tomu běžný notebook s prohlížečem Chrome a zapnutým Bluetooth modulem.
Nyní zcela opustíme svět ESP32 s MicroPythonem a pozornost přesuneme z mikrokontroleru na druhou stranu spojení – konkrétně do webového prohlížeče na řídicím telefonu. Rázem tak místo aplikace nRF Connect získáme komfortnější způsob BLE komunikace.
- POZNÁMKA:
- Je důležité zdůraznit, že jsme dosud vycházeli z projektů napsaných v MicroPythonu.
- Informace uvedené v tomto článku však nejsou na MicroPython nijak vázány!
- Principy Web Bluetooth lze bez problémů použít i v projektech, kde je ESP32 naprogramováno například v prostředí Arduino IDE nebo jiném vývojovém prostředí.
Už jsme zprovoznili základní BLE komunikaci a pro testování používali aplikaci nRF Connect. Ta je sice skvělá pro vývojáře, ale pro běžné používání je poměrně nepraktická. Aplikace nRF Connect je neocenitelná aplikace při vývoji, protože ukazuje syrovou strukturu GATT, UUID adresy a binární data. My ale dnes chceme „jen tak někde mačkat“ na tlačítko  Rozsviť LED , ne ručně zapisovat hodnoty do položek GATT.
Využijeme k tomu tzv. Web Bluetooth, což je vlastnost moderních webových prohlížečů, které umí komunikovat s BLE zařízeními přímo pomocí JavaScriptu. Prakticky to znamená, že si můžeme vytvořit obyčejnou HTML stránku, otevřít ji v Chromu a ovládat ESP32 bez instalace jakékoli další aplikace. Prohlížeč se v tomto případě chová stejně nRF Connect – vyhledá zařízení, připojí se k němu a čte nebo zapisuje charakteristiky GATT.
Co je Web Bluetooth?
Web Bluetooth API je experimentální webové rozhraní, které umožňuje webovým stránkám komunikovat s Bluetooth Low Energy (BLE) zařízeními přímo z JavaScriptu, bez nutnosti instalovat jakoukoliv další aplikaci. Typickými zařízeními, pro které to bylo vyvinuto, jsou senzory, fitness náramky, mikrokontroléry (ESP32, nRF52), chytré zámky, měřicí přístroje nebo průmyslové BLE moduly. Technologie je vyvíjena v rámci W3C Web Bluetooth Community Group a jejím cílem je přiblížit webové aplikace možnostem tradičních aplikací v oblasti komunikace s hardwarem.
První veřejné návrhy Web Bluetooth se objevily kolem roku 2015. Prakticky použitelná implementace byla zpřístupněna již v prohlížeči Google Chrome 56 (leden 2017), nejprve především na Androidu a Chrome OS. Podpora ve Windows byla dokončena později (Chrome 70+). Od té doby se API postupně rozšiřovalo o další funkce, například možnost znovu získat dříve udělená oprávnění.
Je ale fér na samém začátku zmínit i několik důležitých omezení:
- Web Bluetooth je navrženo výhradně pro Bluetooth Low Energy (BLE), takže nepodporuje klasický Bluetooth.
- Web Bluetooth dnes spolehlivě funguje hlavně v Google Chrome na Windows a Androidu, případně na všech prohlížečích postavených na jádře Chromium (Chrome, Edge, Opera, Samsung Internet…). Firefox a Safari funkci z důvodů bezpečnosti a ochrany soukromí neimplementují.
- Na iPhonech Web Bluetooth není podporováno ani u Chrome. Všechny prohlížeče na iOS musí používat jádro WebKit, takže Web Bluetooth není dostupné v žádném běžném iOS prohlížeči.
- Stránka využívající Web Bluetooth musí běžet v zabezpečeném kontextu. V praxi to znamená
HTTPS, při vývojihttp://nebo lokální HTML soubor otevřený přeslocalhost file://v prohlížečích založených na Chromiu. - Vyhledávání Bluetooth zařízení v okolí musí být vyvoláno například kliknutím na tlačítko. Není možné spustit skenování automaticky po načtení stránky.
- Při používání Web Bluetooth v Androidu je často nutné mít povolené lokalizační služby systému, protože Android považuje skenování BLE zařízení za operaci související s určováním polohy. To ale neznamená, že je aktivně používána GPS.
- POZNÁMKA k povolení lokalizační služby systému:
- BLE zařízení v okolí mohou nepřímo napovědět, kde se uživatel nachází (například podle beaconů v obchodech, na letištích apod.). Proto Android historicky spojoval BLE skenování s oprávněním k poloze.
- Android 6–11: pro BLE skenování bylo obvykle nutné oprávnění k poloze a zapnuté lokalizační služby.
- Android 12+ zavedl samostatná oprávnění pro Bluetooth (
BLUETOOTH_aSCAN BLUETOOTH_). Díky tomu už v některých situacích není nutné udělit přístup k poloze.CONNECT - U webových aplikací ale stále záleží na kombinaci verze Androidu, verze Chromu a konkrétní implementace prohlížeče, takže v praxi se uživatel může s požadavkem na zapnutí lokalizačních služeb stále setkat.
Pro Web Bluetooth doporučujeme používat běžný notebook s plnohodnotným prohlížečem Chrome a zapnutým Bluetooth modulem. Máme tím zajištěnou plnou podporu na straně prohlížeče a obvykle odpadá i nutnost řešit oprávnění k poloze, která se mohou objevovat na telefonech s Androidem. Toto řešení je pro domácí projekty často ideální, protože uživatel nemusí nic řešit – stačí otevřít lokální HTML soubor v prohlížeči Chrome se zapnutým Bluetooth. Webová stránka navíc umožňuje vytvořit poměrně elegantní a přehledný ovládací panel.
Jako ukázku možné komunikace webové stránky s BT zařízením si nejdříve vytvoříme řídicí stránku pro rozsvěcení vestavěné LED, pak stavovou stránku pro hlášení zmáčknutého tlačítka BOOT.
Potřebné programy pro modul ESP32, se kterými budeme v obou ukázkách komunikovat, najdete v předchozích článcích:
PŘÍKLAD č. 1: HTML stránka pro změnu LED
V modulu ESP32 spustíme program: Program – ovládání LED. Je zcela jedno, jakou technikou, programovacím jazykem nebo v jakém prostředí byl program vytvořen. Důležité je jen, aby si odpovídaly struktura vytvořeného GATT a příslušná UUID.
Máme-li vyřešen BLE server, můžeme se pustit do vytvoření webové stránky, která bude tvořit stranu klienta.
Vytvořme si textový HTML soubor například v Poznámkovém bloku. Do tohoto textového souboru, který nazveme kupříkladu LED.htm, uložíme níže uvedený HTML kód.
- Po uložení otevřeme soubor lokálně v prohlížeči Google Chrome. (jako soubor přes
file://nebo na lokálním serveruhttp://)localhost - Pokud bychom chtěli tuto ovládací stránku používat na mobilu, je možné ji uložit do souborového systému telefonu a tam ji používat stejným způsobem – jde jen o to, jak moc jsme si uvědomili, že náš telefon je vlastně také počítač a ne jen herní konzole. 😊
- Posledním způsobem, jak tuto HTML stránku provozovat, je uložit soubor na některý z webových hostingů, který však podporuje protokol
https(!). Můžeme pak k tomuto souboru přistupovat z různých zařízení online pomocí zadané URL.
Upřímně řečeno, offline spuštění HTML souboru v notebooku se spuštěným Bluetooth modulem je ale asi pro naše testování varianta nejlepší.
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ESP32 - BLE LED ovládání</title>
<style>
body {
font-family: system-ui;
text-align: center;
margin-top: 40px;
background-color: #f4f4f9;
color: #333;
}
button {
font-size: 16px;
padding: 12px 24px;
margin: 8px;
border: none;
border-radius: 5px;
cursor: pointer;
}
.btn-connect {
background-color: #008CBA;
color: white;
}
.btn-on {
background-color: #4CAF50;
color: white;
display: none;
}
.btn-off {
background-color: #f44336;
color: white;
display: none;
}
#status {
font-weight: bold;
margin: 15px;
color: #555;
}
.card {
background: white;
max-width: 400px;
margin: 20px auto;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
</style>
</head>
<body>
<h1>ESP32 - BLE LED</h1>
<button class="btn-connect" id="connectBtn" onclick="connectBLE()">Zobrazit Bluetooth zařízení</button>
<div id="status">Stav: Odpojeno</div>
<div class="card" id="controlCard" style="display:none;">
<h3>Ovládání LED</h3>
<button class="btn-on" id="onBtn" onclick="sendLED(1)">ZAPNOUT LED</button>
<button class="btn-off" id="offBtn" onclick="sendLED(0)">VYPNOUT LED</button>
</div>
<script>
// UUID musí odpovídat MicroPythonu:
const SERVICE_CONTROL_UUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
const CHAR_LED_UUID = "6e400002-b5a3-f393-e0a9-e50e24dcca9e";
let bluetoothDevice = null;
let ledCharacteristic = null;
async function connectBLE() {
const statusDiv = document.getElementById("status");
statusDiv.innerText = "Otevírám Bluetooth...";
try {
bluetoothDevice = await navigator.bluetooth.requestDevice({
// zobrazí všechna BLE zařízení
acceptAllDevices: true,
// dovolí později přístup ke službě
optionalServices: [SERVICE_CONTROL_UUID]
});
statusDiv.innerText = "Připojuji k: " + (bluetoothDevice.name || "neznámé zařízení");
const server = await bluetoothDevice.gatt.connect();
statusDiv.innerText = "Hledám BLE službu...";
const service = await server.getPrimaryService(SERVICE_CONTROL_UUID);
ledCharacteristic = await service.getCharacteristic(CHAR_LED_UUID);
statusDiv.innerText = "ESP32 připojeno";
document.getElementById("connectBtn").style.display = "none";
document.getElementById("controlCard").style.display = "block";
document.getElementById("onBtn").style.display = "inline-block";
document.getElementById("offBtn").style.display = "inline-block";
bluetoothDevice.addEventListener("gattserverdisconnected", onDisconnected);
}
catch(error) {
// console.error(error);
statusDiv.innerText = "Chyba: " + error.message;
}
}
async function sendLED(value) {
if(!ledCharacteristic) {
alert("ESP32 není připojeno");
return;
}
try {
// MicroPython čeká:
//
// b'1' = LED ON
// b'0' = LED OFF
const data = new TextEncoder().encode(value ? "1": "0");
await ledCharacteristic.writeValue(data);
// console.log("Odesláno:", value ? "1" : "0");
}
catch(error) {
// console.error(error);
alert("Chyba zápisu: " + error.message);
}
}
function onDisconnected() {
document.getElementById("status").innerText = "Stav: Odpojeno";
document.getElementById("connectBtn").style.display = "inline-block";
document.getElementById("controlCard").style.display = "none";
document.getElementById("onBtn").style.display = "none";
document.getElementById("offBtn").style.display = "none";
ledCharacteristic = null;
}
</script>
</body>
</html>
Na obrázku č. 1 vidíme ovládací panel pro vestavěnou LED. Tento panel se zobrazí až po přihlášení k modulu ESP32. Na tomto panelu můžeme prostřednictvím BLE na modulu ESP32 zapínat vestavěnou LED.
Abychom našim čtenářům umožnili přímou možnost testování WEB Bluetooth, je níž v rámečku výše uvedený HTML kód připraven. Lze jej tedy okamžitě vyzkoušet! Kód však bude fungovat pouze:
- Pokud je váš počítač/mobil vybaven modulem Bluetooth a má jej zapnutý a aktivní.
- V dosahu počítače/mobilu je aktivní modul ESP32 se spuštěným ukázkovým programem: Program – ovládání LED
Jak v rámečku výše vidíme, na začátku se zobrazí tlačítko pro připojení k BT zařízení. Po jeho stisknutí začne vyhledávání blízkých BT zařízení – objeví se okno se seznamem zařízení. Tam vybereme zařízení, které se hlásí jménem: ESP32-LED. Po úspěšném připojení se objeví ovládací panel jako na obrázku č. 1.
Popis Javascriptu:
Pojďme se podívat na programovou část ovládací HTML stránky – tedy na funkci JavaScriptu. Na začátku skriptu jsou definovány UUID identifikátory služby a charakteristiky:
const SERVICE_CONTROL_UUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
const CHAR_LED_UUID = "6e400002-b5a3-f393-e0a9-e50e24dcca9e";
Tyto hodnoty musí přesně odpovídat UUID nastaveným v programu běžícím na ESP32. V BLE architektuře představuje:
- Service (služba): logický celek funkcí zařízení.
- Characteristic (charakteristika): konkrétní datový kanál pro čtení nebo zápis.
- DŮLEŽITÁ POZNÁMKA:
- V JavaScriptovém kódu Web Bluetooth je nutné zapisovat 128bitové UUID malými písmeny. Pokud použijeme stejný zápis jako máme u ukázkového programu v MicroPythonu, tedy například
6E40, prohlížeč vyhodí chybu.0001- B5A3-... - V JavaScriptu je třeba zapisovat 128bitová UUID malými písmeny
6e40, protože jde o běžně používaný normalizovaný tvar. MicroPython v tomto případě (kupodivu!) velikost písmen neřeší, ale Web Bluetooth vyžaduje UUID v normalizovaném tvaru.0001- b5a3-... - Nejlepší je v obou případech se držet normalizovaného tvaru. Na tuto drobnost je však snadné zapomenout! 😊
V našem případě služba reprezentuje ovládání zařízení a charakteristika slouží pro odesílání příkazů LED.
Po stisku tlačítka se spustí funkce connectBLE().
bluetoothDevice = await navigator.bluetooth.requestDevice({
acceptAllDevices: true,
optionalServices: [SERVICE_CONTROL_UUID]
});
Metoda request otevře systémové dialogové okno s dostupnými BLE zařízeními. Parametr accept zobrazí všechna nalezená zařízení, zatímco optional zajistí, že po připojení bude mít stránka oprávnění přistupovat ke zvolené službě.
Důležitá vlastnost Web Bluetooth: Uživatel musí zařízení vybrat ručně. Webová stránka nemůže zařízení vyhledávat ani připojovat automaticky, což je důležité z hlediska bezpečnosti a ochrany soukromí.
Po výběru zařízení se naváže BLE spojení:
const server = await bluetoothDevice.gatt.connect();
Každé BLE zařízení obsahuje GATT server, který zpřístupňuje své služby a charakteristiky. Úspěšné připojení znamená, že prohlížeč vytvořil aktivní BLE spojení s ESP32.
Následuje získání požadované služby:
const service = await server.getPrimaryService(SERVICE_CONTROL_UUID);
A poté konkrétní charakteristiky:
ledCharacteristic = await service.getCharacteristic(CHAR_LED_UUID);
Tím je připraven datový kanál pro komunikaci. Objekt led představuje rozhraní, přes které lze do ESP32 zapisovat data.
Funkce sendLED( realizuje vlastní Bluetooth komunikaci. Před samotným odesláním dat je ale třeba jim nastavit správný formát (v tomto případě znak „1“ nebo „0“):
const data = new TextEncoder().encode(value ? "1" : "0");
BLE přenáší binární data, proto je textový znak "1" nebo "0" převeden na pole bajtů (Uint8Array).
Metoda writeValue() odešle data do ESP32.
await ledCharacteristic.writeValue(data);
Na straně mikrokontroleru je charakteristika nastavena jako zapisovatelná a program v MicroPythonu očekává:
b'1'– zapnutí LEDb'0'– vypnutí LED
Tímto způsobem je realizována velmi jednoduchá, ale plně funkční BLE komunikace typu Write Without Response / Write Request podle konfigurace charakteristiky na ESP32.
BLE spojení může být ukončeno uživatelem, ztrátou signálu nebo restartem ESP32. Proto je registrován posluchač události:
bluetoothDevice.addEventListener("gattserverdisconnected", onDisconnected);
Při odpojení se zavolá funkce onDisconnected(), která:
- aktualizuje stav stránky,
- zobrazí tlačítko pro nové připojení,
- skryje ovládací prvky,
- vynuluje referenci na charakteristiku.
To je důležité, protože po ztrátě spojení již nelze do charakteristiky zapisovat.
Asynchronní charakter komunikace
Celý skript využívá async/. Bluetooth operace jsou totiž časově náročné:
- vyhledání zařízení,
- navázání spojení,
- vyhledání služby,
- zápis dat.
Použití await zajišťuje, že se jednotlivé kroky provedou ve správném pořadí, aniž by došlo k zablokování uživatelského rozhraní stránky.
PŘÍKLAD č. 2: HTML stránka pro načtení tlačítka
Před testem následující HTML stránky musíme v modulu ESP32 změnit program za program odesílající notifikace podle stavu vestavěného tlačítka BOOT. Nyní tedy spustíme program: Program – načítání tlačítka. Opět vůbec nezáleží na tom, jak je tento program pro BLE komunikaci vytvořen – musí jen odpovídat struktura vytvořeného GATT a příslušná UUID.
Druhá ukázka HTML stránky nazvaná TLACITKO.htm slouží pro ukázku načítání stavu tlačítka BOOT na modulu ESP32. Velká část kódu (jak HTML, tak JavaScriptu) je podobná předešlé ukázce. Proto se zde především zaměříme na reakci spojenou se změnou GATT charakteristiky s vlastností Notify.
Nejdříve si uvedeme kód stránky, princip činnosti si objasníme pod kódem.
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ESP32 - BLE tlačítko</title>
<style>
body {
font-family: system-ui;
text-align: center;
margin-top: 40px;
background-color: #f4f4f9;
color: #333;
}
button {
font-size: 16px;
padding: 12px 24px;
margin: 8px;
border: none;
border-radius: 5px;
cursor: pointer;
}
.btn-connect {
background-color: #008CBA;
color: white;
}
#status {
font-weight: bold;
margin: 15px;
color: #555;
}
.card {
background: white;
max-width: 400px;
margin: 20px auto;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
#buttonState {
font-size: 28px;
font-weight: bold;
margin-top: 20px;
padding: 20px;
border-radius: 10px;
background: #e9ecef;
}
.pressed {
background: #f44336 !important;
color: white;
}
.released {
background: #4CAF50 !important;
color: white;
}
</style>
</head>
<body>
<h1>ESP32 - BLE tlačítko</h1>
<button class="btn-connect" id="connectBtn" onclick="connectBLE()">Zobrazit Bluetooth zařízení</button>
<div id="status">Stav: Odpojeno</div>
<div class="card" id="controlCard" style="display:none;">
<h3>Stav tlačítka</h3>
<div id="buttonState" class="released">UVOLNĚNO</div>
</div>
<script>
// UUID musí odpovídat MicroPythonu:
const SERVICE_CONTROL_UUID = "a1b2c300-1234-5678-9abc-def012345678";
const CHAR_BUTTON_UUID = "a1b2c301-1234-5678-9abc-def012345678";
let bluetoothDevice = null;
let buttonCharacteristic = null;
async function connectBLE() {
const statusDiv = document.getElementById("status");
statusDiv.innerText = "Otevírám Bluetooth...";
try {
bluetoothDevice = await navigator.bluetooth.requestDevice({
acceptAllDevices: true,
optionalServices: [SERVICE_CONTROL_UUID]
});
statusDiv.innerText = "Připojuji k: " + (bluetoothDevice.name || "neznámé zařízení");
const server = await bluetoothDevice.gatt.connect();
statusDiv.innerText = "Hledám BLE službu...";
const service = await server.getPrimaryService(SERVICE_CONTROL_UUID);
buttonCharacteristic = await service.getCharacteristic(CHAR_BUTTON_UUID);
statusDiv.innerText = "ESP32 připojeno";
document.getElementById("connectBtn").style.display = "none";
document.getElementById("controlCard").style.display = "block";
// Zapnutí notifikací z ESP32
await buttonCharacteristic.startNotifications();
buttonCharacteristic.addEventListener("characteristicvaluechanged", receiveButtonState);
bluetoothDevice.addEventListener("gattserverdisconnected", onDisconnected);
}
catch (error) {
statusDiv.innerText = "Chyba: " + error.message;
}
}
function receiveButtonState(event) {
const value = event.target.value.getUint8(0);
const stateDiv = document.getElementById("buttonState");
// ESP32 posílá:
// 1 = stisknuto
// 0 = uvolněno
if (value === 1) {
stateDiv.innerText = "STISKNUTO";
stateDiv.className = "pressed";
} else {
stateDiv.innerText = "UVOLNĚNO";
stateDiv.className = "released";
}
}
function onDisconnected() {
document.getElementById("status").innerText = "Stav: Odpojeno";
document.getElementById("connectBtn").style.display = "inline-block";
document.getElementById("controlCard").style.display = "none";
buttonCharacteristic = null;
}
</script>
</body>
</html>
Obrázek č. 2 nám ukazuje panel naší HTML stránky zobrazující stav tlačítka.
V rámečku níže si opět lze HTML kód vyzkoušet. Po připojení k modulu ESP32 se barva a popis tlačítka bude měnit podle stisknutí tlačítka BOOT na použitém kitu s modulem ESP32.
Na začátku je opět zobrazeno tlačítko pro připojení k BT zařízení. Po stisknutí se objeví okno se seznam zařízení. Po zvolení zařízení se jménem: ESP32-BUTTON se objeví stavový panel, jako je zobrazeno na obrázku č. 2.
Popis Javascriptu:
Po připojení k BLE zařízení probíhá v této ukázce komunikace jiným způsobem než v předchozím příkladu s ovládáním LED. Zatímco u LED byl webový prohlížeč aktivní a pomocí writeValue() odesílal příkazy do ESP32, zde je situace opačná – aktivní je samotné ESP32, které při změně stavu tlačítka odešle notifikaci do prohlížeče.
Ale pojďme na to postupně…
Na začátku skriptu jsou opět definovány UUID služby a charakteristiky:
const SERVICE_CONTROL_UUID = "a1b2c300-1234-5678-9abc-def012345678";
const CHAR_BUTTON_UUID = "a1b2c301-1234-5678-9abc-def012345678";
Tyto hodnoty musí přesně odpovídat UUID nastaveným v programu MicroPythonu.
Samotné připojení probíhá stejně jako v předchozí ukázce. Funkce connectBLE() otevře dialog pro výběr BLE zařízení, naváže spojení s GATT serverem ESP32 a získá požadovanou službu i charakteristiku. Zásadní rozdíl nastává až po získání charakteristiky:
await buttonCharacteristic.startNotifications();
Tímto příkazem prohlížeč nečte aktuální hodnotu, ale požádá ESP32, aby mu automaticky posílalo informace pokaždé, když se hodnota charakteristiky změní. V BLE terminologii jde o GATT Notifications.
Na straně ESP32 je charakteristika vytvořena s příznakem _FLAG_NOTIFY a při změně stavu tlačítka se odešle notifikace funkcí gatts_. Program v MicroPythonu posílá pouze jediný bajt:
0x01– tlačítko stisknuto0x00– tlačítko uvolněno
ESP32 tedy funguje jako BLE server, který aktivně informuje připojené klienty o změně stavu.
Po zapnutí notifikací je zaregistrována obsluha události:
buttonCharacteristic.addEventListener("characteristicvaluechanged", receiveButtonState );
Událost characteristic se vyvolá vždy, když z ESP32 dorazí nová hodnota. Funkce receive tak představuje příjmovou část komunikace.
Přijatá data se v této funkci čtou příkazem:
const value = event.target.value.getUint8(0);
Objekt event. obsahuje binární data přijatá z BLE a metoda getUint8(0) přečte první bajt. Očekáváme, že
to bude číslo 0 nebo 1. Na rozdíl od LED ukázky zde není potřeba používat TextEncoder, protože data nepřevádíme z textu na bajty – přijímáme již hotová binární
data z BLE spojení.
Podle přijaté hodnoty se následně aktualizuje zobrazení stránky:
if (value === 1) {
stateDiv.innerText = "STISKNUTO";
} else {
stateDiv.innerText = "UVOLNĚNO";
}
Komunikace je tedy velmi úsporná. Přenáší se pouze jeden bajt a pouze v okamžiku změny stavu tlačítka. Právě v tom spočívá hlavní výhoda notifikací, jak už jsme si několikrát říkali. Kdybychom je nepoužili, musela by webová stránka pravidelně volat readValue() a neustále se zařízení dotazovat, zda se stav tlačítka změnil. To by znamenalo větší provoz na BLE, vyšší spotřebu energie a zbytečné přenosy i ve chvíli, kdy se nic neděje. Nemluvě o zbytečném blokování prostředků na straně webové stránky.
Obsluha odpojení zůstává stejná jako v předchozím příkladu. Událost gatt zajistí aktualizaci stavu stránky,
zobrazení tlačítka pro nové připojení a zrušení reference na charakteristiku. Notifikace jsou totiž vázány na konkrétní BLE spojení a po opětovném připojení je nutné je znovu aktivovat.
Závěr
V dnešním článku jsme si ukázali, že Web Bluetooth umožňuje vytvořit plnohodnotné ovládací rozhraní pro ESP32 přímo ve webovém prohlížeči. Hlavní výhodou tohoto přístupu je, že celé uživatelské rozhraní vytvoříme pomocí běžných webových technologií – HTML, CSS a JavaScriptu. Ovládací panel tak může být přehledný, snadno upravitelný a přenositelný mezi různými počítači bez závislosti na dalším softwaru.
V našich ukázkách jsme nejprve odesílali příkazy pro zapnutí a vypnutí vestavěné LED, poté jsme využili GATT notifikace a automaticky zobrazovali stav tlačítka BOOT. Na obou příkladech je vidět, že webová stránka může v BLE komunikaci vystupovat jak jako aktivní klient zapisující data do ESP32, tak jako příjemce událostí odesílaných mikrokontrolerem.
Web Bluetooth má sice několik důležitých omezení – funguje pouze s Bluetooth Low Energy, vyžaduje zabezpečený kontext, ruční výběr zařízení uživatelem a není podporováno ve Firefoxu ani Safari – pro domácí projekty a výuku však představuje velmi zajímavé řešení.
Pro praktické použití se jako nejpohodlnější ukázala kombinace:
- ESP32 s BLE,
- Google Chrome (nebo jiný prohlížeč Chromium),
- lokálně spuštěná HTML stránka nebo stránka dostupná přes HTTPS.
Což jsou vcelku „snesitelné“ a snadno splnitelné požadavky.
Ať už stavíme dálkově ovládaný vypínač, bezdrátový senzor teploty nebo komplexní systém domácí automatizace, BLE je díky své nízké spotřebě a široké podpoře ideální volbou. Teď už zbývá jen jediné – vzít ESP32, otevřít Thonny a začít experimentovat.