Fyzikální kabinet FyzKAB

ESP32 a Bluetooth (Classic)

Modul ESP32 přichází nejen s konektivitou Wi-Fi, ale i s Bluetooth a Bluetooth Low Energy (BLE). V tomto dnešním tutoriálu se podíváme, jak používat modul ESP32 s Bluetooth pro výměnu dat mezi ESP32 a smartphonem (s operačním systémem Android). Naším cílem bude schopnost zasílat data do modulu ESP32 a také je umět načítat zpět. Tento způsob můžeme používat buď pro bezdrátové načítání naměřených hodnot, nebo pro vzdálené řízení modulu ESP32.

V tomto článku se budeme zabývat metodou Bluetooth Classic, na „novější“ metodu Bluetooth Low Energy se podíváme v některém z příštích návodů.

Bluetooth Classic vs. Bluetooth Low Energy (BLE)

Pro začátek se ale nejdříve podívejme, co je společné a čím se liší klasické Bluetooth a Bluetooth Low Energy (BLE). Bluetooth Classic i BLE fungují se stejnou technologií šifrování, ověřování a párování. Obě technologie zahrnují zařízení, která fungují ve standardním modelu master-slave. Zařízení Bluetooth musíme nejprve spárovat , aby došlo k přenosu dat. Klasický Bluetooth i BLE mají podobný RF výstupní výkon a fungují ve stejném pásmu 2,4 GHz. Verze Bluetooth 4.0, 4.1, 4.2 a 5.0 zahrnují klasické Bluetooth i BLE.

Při vývoji nebo používání aplikací Bluetooth bychom měli vědět, kterou verzi použít, protože fungují odlišně. Pokud jste si začali myslet, že jsou trochu jako jednovaječná dvojčata, byl to omyl, nejdůležitějším rozdílem mezi nimi je především spotřeba energie. Klasické Bluetooth je schopno zpracovat velké množství dat, ale rychle spotřebovává baterii. Naopak BLE se používá pro aplikace, které si nepotřebují vyměňovat velké množství dat, což jim umožňuje provoz na baterie s nižšími nároky na energii. BLE nabízí nízkou spotřebu energie, protože funguje v režimu spánku a uživatelé jej „probudí“ při zahájení připojení a výměně dat. Spotřeba BLE zařízení se obvykle pohybuje kolem pouhých 1-5 % spotřeby klasických Bluetooth zařízení. Je tedy jasné, že klasické Bluetooth se používá hlavně pro audio aplikace, jako jsou bezdrátové reproduktory nebo sluchátka. BLE se častěji používá pro bateriově napájené příslušenství (např. klávesnice a myš), fitness náramky, zařízení IoT atd. Nároky BLE na napájení oproti klasické Bluetooth jsou mnohem nižší. Klasický Bluetooth a BLE mají i různé způsoby modulace/demodulace fyzické vrstvy, proto vzájemně neumí komunikovat mezi sebou. Pokud je hlavním zařízením zařízení BLE, podřízené zařízení musí být také BLE. Jak si však probereme později, moderní smartphone dokáže komunikovat s klasickými i BLE zařízeními současně, i když mezi sebou zařízení komunikovat neumí.

Pokud jde o rychlost přenosu dat, zařízení BLE jsou rychlejší. V technologii BLE je zděděno mnoho klasických funkcí Bluetooth, včetně rozhraní adaptačního protokolu, části řízení logické linky a adaptivního přeskakování frekvence. Díky této dědičnosti je BLE robustní, snadno nastavitelný a spolehlivý v náročných prostředích. Kromě toho mohou BLE zařízení pojmout větší počet slave ve srovnání s klasickým Bluetooth (Toto číslo závisí na velikosti dostupné paměti a implementaci zařízení).

Bluetooth a smartphony

Jak jsme již naznačili dříve, moderní smartphony jsou nejběžnějšími příklady zařízení Bluetooth s duálním režimem, protože podporují klasické Bluetooth i Bluetooth Low Energy. Většina moderních smartphonů může komunikovat s oběma typy zařízení Bluetooth a dosahují toho pomocí mechanismu sdílení času pro komunikaci pomocí obou režimů. Smartphony umožňují čipům Bluetooth s duálním režimem přepínat mezi režimy, aby podporovaly klasické Bluetooth i BLE zařízení. Například moderní tablet může komunikovat s náhlavní soupravou, která používá klasiku, a zároveň komunikovat s periferiemi, jako je myš a klávesnice, které používají BLE.

Aplikace Serial Bluetooth Terminal

Chceme-li, aby náš modul ESP32 komunikoval s nějakým Bluetooth zařízením, asi nás jako první napadne propojení se svým chytrým telefonem (smartphone). Abychom ho mohli používat jako BT-komunkátor s modulem ESP32, musíme mít nainstalovanou aplikaci Bluetooth Terminal. My v tomto článku budeme používat aplikaci pro telefon s operačním systém Android Serial Bluetooth Terminal, která je dostupná v Play Store.

BT terminal - Google Play
Obrázek č 1 – Serial Bluetooth Terminal v aplikaci Play Store telefonu s OS Android.

Aplikace Serial Bluetooth Terminal, jak sám název říká, funguje podobně jako klasický sériový monitor (terminál), který známe z prostředí Arduino IDE. Jediným rozdílem bude, že spojení mezi modulem ESP32 a ovládacím okénkem sériového monitoru není zprostředkováno USB/COM kabelem, ale technologií Bluetooth. Koneckonců, pojďme to vyzkoušet!

Serial Port ↔ Serial Bluetooth

Pro následující program, napsaný v prostředí Arduino IDE, musíme do prostředí Arduino IDE přidat knihovnu BluetoothSerial.h. Instalaci rozšiřující knihovny jsme si zde již několikrát ukazovali v předešlých článcích, takže ji zde již nebudeme uvádět. V případě potřeby se podívejte do některého z následujících článků, např. Čidlo teploty DS18B20 a modul ESP32 nebo Rozhraní I²C a displej LCD s ESP32, kde je to zmíněno.

Následující kód je standardním ukázkovým programem, který po instalaci knihovny BluetoothSerial.h bude možné načíst přímo za seznamů ukázkových programů v prostředí Arduino IDE – viz obr. č. 2: Soubor > Příklady > BluetoothSerial > SerialtoSerialBT.

BT priklad - Arduino IDE
Obrázek č. 2 – Otevření ukázkového programu SerialToSerialBT v prostředí Arduino IDE.

Kód:

//This example code is in the Public Domain (or CC0 licensed, at your option.)
//By Evandro Copercini - 2018
//
//Tento priklad vytvari most mezi seriovym portem a klasickým Bluetooth (SPP)
//a take ukazuje, ze SerialBT ma stejnou funkci jako ma Seriovy port

#include "BluetoothSerial.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled ! Please run `make menuconfig` to and enable it
#endif

BluetoothSerial SerialBT;

// funkce SETUP se spusti jednou pri stisknuti tlacitka reset nebo pri zapnuti desky.
void setup() {
  Serial.begin(115200);   //nastaveni rychlosti sériového portu
  SerialBT.begin("ESP32test");   //Bluetooth device name
  Serial.println("Zarizeni se spustilo, nyni ho muzete spárovat s Bluetooth!");
}

// funkce LOOP bezi stale dokola.
void loop() {
  if (Serial.available()) {
    SerialBT.write(Serial.read());
  }

  if (SerialBT.available()) {
    Serial.write(SerialBT.read());
  }

  delay(20);
}

Vysvětlení kódu:

Kód začíná zahrnutím knihovny BluetoothSerial, která bude obsluhovat odesílání a příjem zpráv protokolem Bluetooth.

#include "BluetoothSerial.h"

Následující tři řádky zkontrolují, zda je správně povoleno Bluetooth.

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

Poté vytvoříme instanci BluetoothSerial nazvanou SerialBT.

BluetoothSerial SerialBT;

Sériovou Bluetooth linku inicializujeme v proceduře setup() příkazem begin, jehož argumentem je jednoznačný název, kterým se bude modul ESP32 v prostoru BT komunikace identifikovat – v našem případě modul pojmenujeme ESP32test.

SerialBT.begin("ESP32test");   //Bluetooth device name

V hlavní smyčce loop() jsou dvě podmínky, první kontroluje, zda jsou na sériovém portu dostupná data, která se pak odešlou (znak po znaku) na BT sériový port do spárovaného zařízení (odeslání z ESP32 na smartphone).

if (Serial.available()) {
  SerialBT.write(Serial.read());
}

Druhá podmínka funguje přesně naopak, tedy testuje BT sériový port a případná data se vypíší na klasický sériový port (přijetí dat ze smartphonu do modulu ESP32)

if (SerialBT.available()) {
  Serial.write(SerialBT.read());
}

Funkčnost si ukážeme po přeložení programu a jeho nahrání do modulu ESP32. Po nahrání kódu otevřete sériový monitor s přenosovou rychlostí 115200. Po několika sekundách by se měla zobrazit zpráva: „Zarizeni se spustilo, nyní ho muzete sparovat s Bluetooth! “ (viz obr. č. 3).

Serial monitor Ardiono IDE
Obrázek č. 3 – ůvodní výstup ukázkového kódu na sériovém monitoru.

Na svém smartphonu využijeme aplikaci „Serial Bluetooth Terminal“ (pochopitelně nezpomeňme ve  svém smartphonu povolit Bluetooth! 😉). Chcete-li se poprvé připojit k modulu ESP32, musíte nové zařízení se svým telefonem spárovat. Na smartphonu přejdeme do Nastavení > Připojení zařízení (Bluetooth) > Spárovat nové zařízení.

sparovat zarizeni     sparovane zarizeni
Obrázek č. 4 – Párovávání modulu ESP32 se smartphonem

Nyní přejdeme do aplikace Serial Bluetooth Terminal. Kliknutím na ikonu menu vybereme volbu Devices, kde v záložce Bluetooth Classic vybereme zařízení jménem ESP32.

BT-terminal Devices     BT-terminal ESP32test
Obrázek č. 5 – Postup přihlášení modulu ESP32 do Serial Bluetooth Terminal.

V okně sériového Bluetooth terminálu bychom měli obdržet zprávu Connected, jako na obrázku č. 6.

BT-terminal Connected.png
Obrázek č. 6 – Úspěšné přihlášení modulu ESP32 do Serial Bluetooth Terminal

Nyní zadáme do Serial Monitoru prostředí Arduino IDE nějakou zprávu - například „ahoj“.

BT-serial 1
Obrázek č. 7 – Zadání řetězce „ahoj“ pro odeslání na smartphone.

Tuto zprávu bychom měli okamžitě obdržet na smartphonu v Serial Bluetooth Terminalu.

BT-terminal ahoj
Obrázek č. 8 – Příjem textového řetězce a příprava odeslání odpovědi.

A hned i odpovíme – opět něco zcela inteligentního a originálního, například: „Ahoj, jak se mas?“. Zprávu ze svého smartphonu odešleme. Zpráva se okamžitě zapíše do modulu ESP32 a tedy se i ukáže v okně sériovém monitoru prostředí Arduino IDE.

BT-serial 2.png
Obrázek č. 9 – Zobrazení v sériovém monitoru textu odpovědi zaslané ze smartphone.

Máme hotovo! Vidíme, že lze zasílat zprávy z modulu ESP32 do našeho smartphonu a pochopitelně i naopak. Nezkusíme to využít v nějakém „praktickém“ příkladu?

Načítání dat a řízení stavu ESP32 pomocí Bluetooth Serial Terminálu

Jako ukázku konkrétního využití komunikace přes Bluetooth, si vytvoříme program, který bude načítat vnitřní magnetické čidlo (tzv. Hallova sonda) modulu ESP32 a v pravidelných časových intervalech odesílat do smartphonu. Naopak pozorovatelným výstupem modulu ESP32 na zaslané řídicí příkazy bude rozsvěcení a zhasínání vestavěné LED. Pochopitelně, pokud chcete místo magnetického pole načítat kupříkladu nějaké externí čidlo, můžete se inspirovat v některém z následujících článků:

Naopak pro ukázku reakce na vstupu ze smartphonu můžeme ovládat nějaké zařízení – např. servo, relé, LED segmentovku, DC motor, krokový motor, LCD displej… Viz články:

Ale my zde nyní nechceme nic „drátovat“, tak využijeme to, co máme na vývojové desce s modulem ESP32 již vestavěné – tedy LED a mag. čidlo.

Kód

/* Ovladani ESP32 pres BT - cti magnetismus, rozsvecej LED */

// Load libraries
#include "BluetoothSerial.h"

// Check if Bluetooth configs are enabled
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

BluetoothSerial SerialBT;   // Bluetooth Serial object

// GPIO, ke kterému je pripojena LED
// const int ledPin = 1;   // ESP32 rev.1 ma LED na GPIO1 (pozor rusi to serial port a stav ON/OFF je obracene)
const int ledPin = 2;

// Zpracovani prijatych a odeslanych zprav
String message = "";
char incomingChar;
String magnString = "";

// Timer: auxiliar variables
unsigned long previousMillis = 0;   // ulozeni casu posledního mereni
const long interval = 10000;   // interval, publikovani hodnot senzoru

// funkce SETUP se spusti jednou pri stisknuti tlacitka reset nebo pri zapnuti desky.
void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(115200);
  SerialBT.begin("ESP32");   // Bluetooth device name
  Serial.println("Zarizeni se spustilo, nyní ho muzete sparovat s Bluetooth!");
}

// funkce LOOP bezi stale dokola.
void loop() {
  unsigned long currentMillis = millis();

  // Send magn. readings
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    magnString = "Hall sensor value = " + String(hallRead());   // nacteni hodnoty z Hallovy sondy
    SerialBT.println(magnString);
  }

  // Read received messages (LED control command)
  if (SerialBT.available()) {
    char incomingChar = SerialBT.read();
    if (incomingChar != '\n') {
      message += String(incomingChar);
    } else {
      message = "";
    }
    Serial.write(incomingChar);
  }

  // Zkontrolujte prijatou zpravu a podle toho se ridi vystup
  if (message == "led_on") {
    digitalWrite(ledPin, HIGH);
  }

  else if (message == "led_off") {
    digitalWrite(ledPin, LOW);
  }

  delay(20);
}

Pojďme se podívat na kód a ukážeme si, jak funguje. Začátek kódu je stejný jako v předešlém programu, tedy musíme přidat potřebnou knihovnu BluetoothSerial.h a vytvořit instanci objektu BluetoothSerial.

V další části je vytvořena proměnná pro uložení hodnoty GPIO pinu, na které je zapojena integrovaná LED, a proměnné pro uložení odeslaných a přijatých zpráv. Následující proměnná a konstanta slouží pro obsluhu časování.

// GPIO, ke kterému je pripojena LED
// const int ledPin = 1;   // ESP32 rev.1 ma LED na GPIO1 (pozor rusi to serial port a stav ON/OFF je obracene)
const int ledPin = 2;

// Zpracovani prijatych a odeslanych zprav
String message = "";
char incomingChar;
String magnString = "";

// Timer: auxiliar variables
unsigned long previousMillis = 0;   // ulozeni casu posledního mereni
const long interval = 10000;   // interval, publikovani hodnot senzoru

V hlavní smyčce loop() se odesílají naměřené hodnoty magnetismu, provádí si odeslání naměřených hodnot a čtou se přijaté zprávy. Následující fragment kódu zkontroluje, zda od posledního čtení uplynulo požadovaných 10 sekund. Pokud již nastal čas odeslat novou hodnotu, načte se magnetické pole vestavěnou Hallovou sondou, vytvoří se řetězec pro odeslání a odešle se na Serial Bluetooth Terminal.

unsigned long currentMillis = millis();
// Send magn. readings
if (currentMillis - previousMillis >= interval) {
  previousMillis = currentMillis;
  magnString = "Hall sensor value = " + String(hallRead());   // nacteni hodnoty z Hallovy sondy
  SerialBT.println(magnString);
}

// Read received messages (LED control command)
if (SerialBT.available()) {
  char incomingChar = SerialBT.read();
  if (incomingChar != '\n') {
    message += String(incomingChar);
  } else {
    message = "";
  }
  Serial.write(incomingChar);
}

Následující příkaz if čte příchozí zprávy, postupně je čte ze seriového portu (znak po znaku) do proměnné message. Když zprávu přijmeme, tedy zpráva skončila znakem \n, je zkontrolováno, zda se proměnné message rovná některému příkazů pro rozsvícení a zhasnutí LED ("led_on", "led_off").

// Zkontrolujte prijatou zprávu a podle toho se ridi vystup
if (message == "led_on") {
  digitalWrite(ledPin, HIGH);
} else if (message == "led_off") {
  digitalWrite(ledPin, LOW);
}

Hotový kód programu nahrajeme na desku ESP32, poté otevřete Serial Monitor, resetujeme modul ESP32 a spárujeme jej se svým smartphonem. V okné aplikace Serial Bluetooth Terminal by měla situace vypadat, asi jako na obrázku č. 10.

BT-terminal magnetismus a LED
Obrázek č. 10 – Načtené hodnoty z magn. čidla modulu ESP32 a odeslané přikazy pro rozsvícení/zhasnutí LED.

V okně Bluetooth Serial Terminálu se postupně začnou zobrazovat načtené hodnoty z vestavěné Hallovy sondy modulu ESP32, naopak na druhou stranu můžeme zasílat příkazy led_on a led_off, kterými rozsvěcíme a zhasínáme vestavěnou LED. Tyto příkazy zaslané na modul ESP32 se také zobrazí na sériovém monitoru v prostředí Arduino IDE (viz obrázek č. 11).

BT-serial 3

Obrázek č. 11 – Výpis (na sériovém portu modulu ESP32) přijatých příkazů pro rozsvícení/zhasnutí LED.

Tvorba makra pro zadané příkazy

Aplikace Bluetooth Serial Terminal má pod komunikačním oknem několik tlačítek pro definici vlastních příkazů – tlačítka M1, M2…. My si můžeme například uložit do tlačítka M1 zprávu „led_on“ a do tlačítka M2 zprávou „led_off“, jak vidíme na obrázku 12.

BT-terminal M1     BT-terminal M2

Obrázek č. 12 – Nastavení předdefinovaných příkazů (maker) v Serial Bluetooth Terminal.

Rozsvěcet vestavěnou LED na vývojové desce s ESP32 nyní můžeme tapáním na tlačítka M1 a M2, zároveň je na náš smartphon z modulu ESP32 stále zasílána každých 10 sekund hodnota z magnetického čidla modulu ESP32.

Ještě celý příklad můžeme rozšířit o možné závěrečné vypnutí modulu Bluetooth pomocí příkazu btStop, který vyvoláme zasláním příkazu „stop“ na svém smartphonu. To by se v kanálu vytvořilo doplněním následující podmínky pro testování zaslaného řetězce (proměnná message):

if (message == "stop") {
  btStop();
}

Pochopitelně po ukončení Bluetooth již není možná další komunikace s modulem ESP32 přes Bluetooth Serial Terminal komunikovat (dojde k ukončení spojení). Možné opětovné zapnutí Bluetooh se provádí pomocí příkazu btStart(), ale tento příkaz by musel být již vyvolán nějakým jiným impulzem – pomocí časovače, příkazem přes Wi-Fi, stisknutím tlačítka…

Závěr

V dnešním článku jsme si ukázali první a základní možnost používání Bluetooth modulu ESP32. Možným využitím může být jednoduché ovládání našeho projektu pomocí smartphonu nebo určité „vzdálené“ čtení stavu modulu ESP32, či připojených čidel.

Jako jiné využití se nabízí možnost využít při startu obvodu, kdy by se pomocí Bluetooth mohl zkontrolovat na displeji smartphonu stav modulu ESP32 (podobně jako v okně klasického seriového portu), zda je vše nastaveno OK, zda jsou aktivní všechna čidla, zda nešlo k nějaké chybě při inicializaci čidel, zda došlo k úspěšnému připojení k Wi-Fi apod. Po kontrole tohoto startovního stavu by pak bylo možné Bluetooth v modulu již vypnout a nechat modul dále pracovat dle předem zvoleného projektu.


UPOZORNĚNÍ:
Nesouhlasíme s vyřazením Newtonových zákonů, Ohmova zákona a zákona zachování energie z učiva fyziky základních škol v České republice!