ESP32 (33) – BLE, advertising

by luca
3 comments

Nei precedenti articoli abbiamo visto come utilizzare il chip esp32 per ricevere ed interpretare i pacchetti di advertising trasmessi da periferiche Bluetooth Low Energy. Come esempio pratico, abbiamo sviluppato un programma per rilevare la presenza di un particolare iBeacon e attivare di conseguenza una uscita.

Nel tutorial di oggi vedremo invece come trasmettere pacchetti di advertising.

Processo di advertising

Abbiamo già scoperto che il driver Bluetooth dello stack esp-idf viene eseguito in un thread separato. Ogni volta che il driver deve inviare una notifica al nostro programma, chiama una funzione di callback indicando quale evento si è scatenato.

Il processo di advertising è molto semplice:

  • il programma configura i dati da trasmettere con il comando esp_ble_gap_config_adv_data()
  • il driver segnala di aver terminato la configurazione con l’evento ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT
  • il programma può ora avviare il processo di advertising con il comando esp_ble_gap_start_advertising()
  • il driver segnala di aver avviato il processo con l’evento ESP_GAP_BLE_ADV_START_COMPLETE_EVT

esp32-adv-001

Dati di advertising

E’ possibile indicare al driver quali dati includere nel pacchetto di advertising con il comando:

esp_err_t esp_ble_gap_config_adv_data(esp_ble_adv_data_t *adv_data);

Il comando accetta come parametro un puntatore ad una struct esp_ble_adv_data_t:

esp32-adv-002

Il significato dei vari parametri è dettagliato nel documento Supplement to the Bluetooth Core Specification.

Per prima cosa vediamo come trasmettere il nome del dispositivo. Dobbiamo utilizzare il metodo esp_ble_gap_set_device_name() per indicare al driver quale nome utilizzare e settare a true il campo include_name nella struct:

static esp_ble_adv_data_t adv_data = {
  .include_name = true,
};
[...]
ESP_ERROR_CHECK(esp_ble_gap_set_device_name("ESP32_BLE"));
ESP_ERROR_CHECK(esp_ble_gap_config_adv_data(&adv_data));

Tramite i flags possiamo indicare alcune caratteristiche del nostro dispositivo. Le costanti a disposizione sono:

esp32-adv-003

possiamo utilizzarle con l’operatore OR. Se ad esempio vogliamo indicare che il nostro dispositivo è limited discoverable (ovvero effettua la trasmissione dei pacchetti di advertising per un tempo limitato, solitamente 30 secondi) e che non supporta il Bluetooth classico (BR/EDR, Basic Rate/Enhanced Data Rate) scriveremo:

static esp_ble_adv_data_t adv_data = {
  .flag = ESP_BLE_ADV_FLAG_LIMIT_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT,
};

Parametri di advertising

Dopo aver configurato il contenuto del pacchetto di advertising, dobbiamo indicare al driver anche la modalità con cui inviare tale pacchetto.

Il comando:

esp_err_t esp_ble_gap_start_advertising(esp_ble_adv_params_t *adv_params);

accetta come parametro una struct esp_ble_adv_params_t:

esp32-adv-004

Possiamo configurare l’intervallo minimomassimo di trasmissione del pacchetto. I due parametri possono assumere un valore da 0x20 a 0x4000. Per conoscere l’intervallo in millisecondi, va moltiplicato il valore indicato per 0,625. Questo significa che il valore minimo (0x20) corrisponde ad un intervallo di 12,5ms.

Nel file esp_gap_ble_api.h sono elencate le costanti utilizzabili per gli altri parametri (esp_ble_adv_type_t, esp_ble_addr_type_t…).

Come esempio configuriamo il processo di advertising come segue:

[checklist]

  • intervallo minimo di trasmissione 0x20 e massimo 0x40
  • tipo di dispositivo non connectable (non accetta connessioni ma effettua solo invio dati in broadcast)
  • indirizzo MAC pubblico
  • trasmissione su tutti e 3 i canali dedicati ai pacchetti di advertising
  • nessun filtro sui dispositivi che possono effettuare scan o collegarsi

[/checklist]

static esp_ble_adv_params_t ble_adv_params = {
  .adv_int_min = 0x20,
  .adv_int_max = 0x40,
  .adv_type = ADV_TYPE_NONCONN_IND,
  .own_addr_type  = BLE_ADDR_TYPE_PUBLIC,
  .channel_map = ADV_CHNL_ALL,
  .adv_filter_policy  = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};
[...]
esp_ble_gap_start_advertising(&ble_adv_params);

Demo

Ho preparato un programma che raccoglie quanto spiegato sopra, il codice sorgente è disponibile nel mio repository Github.

Ecco una demo del suo funzionamento (sottotitoli in italiano disponibili):

[youtube id=”NOLYF5CutIM” width=”600″ height=”350″]

Related Posts

3 comments

Karlo Verde 2 giugno 2018 - 23:36

Hey there, Luca
thanks for all of these tutorials
they are quite useful!
I just noticed that minimum advertising interval you calculated is actually wrong.
0x20*0.625 = 32*0.625 = 20ms
Not a big deal but may lead to errors.
Thanks again!

Reply
luca 3 giugno 2018 - 20:09

Karlo, thanks for your comment!

Reply
Asish Banerjee 8 settembre 2018 - 18:48

Hello Luca,
First of all thanks to you for your great effort. Very nice and useful tutorial. I am eagerly waiting for more tutorial from you.
My best regards.
Asish

Reply

Rispondi a Asish Banerjee Cancel Reply

tre × cinque =