ESP32 (33) – BLE, advertising

luca 26/03/2018 2

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:

  • 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
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):

2 Comments »

  1. Karlo Verde 02/06/2018 at 23:36 - Reply

    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!

    • luca 03/06/2018 at 20:09 - Reply

      Karlo, thanks for your comment!

Leave A Response »

Questo sito usa i cookie per poterti offrire una migliore esperienza di navigazione maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.

Chiudi