Desenvolvendo um Beacon BLE com ESP32 9

O Bluetooth, apesar dos seus mais de 20 anos de uso comercial, continua relevante até os dias de hoje. Usado desde a transferência de arquivos entre smartphones até para conexão de periféricos sem fio do dia-a-dia (teclado, mouse, etc.), o Bluetooth tornou-se praticamente um padrão no quesito conectar dispositivos localmente de forma sem fio. Uma das aplicações mais novas e interessantes do Bluetooth (no caso, de sua versão Low Energy, BLE) são os beacons. Não sabe o que é um beacon? Deseja construir o seu próprio beacon usando um ESP32? Este post vai te ensinar!

Material necessário

Para criar seu próprio beacon com ESP32, você vai precisar de:

Afinal, o que são beacons?

Para explicar o que é um beacon, de início farei uma analogia: um beacon é um dispositivo Bluetooth que pode ser comparado a um farol marítimo (ver figura 1). Os faróis marítimos servem para que embarcações se localizem / saibam onde tem terra firme de forma rápida e simples.

Farol marítimo - Imagem 1
Figura 1 – farol marítimo

Um beacon funciona de forma similar, usando Bluetooth ao invés de luz visível. O que um beacon faz, na prática, é enviar constantemente, via Bluetooth Low Energy, alguns dados curtos relativos à sua identificação. Dessa forma, dispositivos Bluetooth (computadores, smartphones, etc.) que estiverem nas proximidades conseguirão “enxergar” o beacon. É como se ele fosse um farol para computadores, smartphones, etc. Cada beacon possui uma identificação única, logo um computador ou smartphone que o “veja” pode, portanto, associar sua presença nas proximidades a uma ação específica, como gatilho / trigger de uma ação.

Um uso muito comum para beacons é para interação com clientes no varejo: se o cliente tiver o app de uma loja instalado e este detectar (com beacon) que você está numa das lojas físicas pertencentes à marca, pode disparar promoções exclusivas baseadas no perfil de compra do cliente, alimentar uma base de dados sobre sua visitação às lojas (incluindo o setor visitado e tempo de permanência em cada setor) ou até mesmo te dar informações sobre um produto específico que você esteja fisicamente próximo (no caso de haver vários beacons estrategicamente colocados na loja).

Outro uso comum (nesse caso, comum fora do Brasil) é em museus e galerias de arte, onde o visitante em posse do app do local / galeria pode receber informações adicionais das obras de arte que estiver próximo, transformando seu smartphone em um guia de arte inteligente, personalizado e de bolso.

Portanto, vimos que um beacon, em conjunto com um aplicativo específico, é capaz de fazer coisas muito relevantes e que podem se converter em mais lucro para os estabelecimentos. Além disso, conforme podemos concluir, o beacon sozinho não faz nada! É preciso que um aplicativo procure por ele e, na sua presença, dispare uma determinada ação no smartphone do cliente.

Uma das maiores vantagens técnicas dos beacons é que estes não exigem conexão para compartilhar a identificação. Dessa forma, um simples scan consegue capturar estes dados, tornando o processo muito mais rápido e simples (em comparação a um cenário onde a conexão Bluetooth seria necessária).

Aproveito para deixar abaixo links de dois vídeos mostrando o uso dos beacons:

Origem dos beacons e exemplos deles no mercado

Os beacons foram originalmente inseridos no mercado pela Apple (daí o nome iBeacon), porém hoje já existem múltiplos fabricantes e tipos de beacons disponíveis no mercado. Se tiver curiosidade, veja o starting guide do iBeacon feito pela Apple clicando aqui.

Fisicamente, o beacon é um dispositivo bem pequeno (em alguns casos, de dimensões similares a uma tampa de garrafa PET), alimentado por bateria e com autonomia de meses ou até mesmo anos. Eles são vendidos nos mais variados formatos e cores, conforme pode ser visto na figura 2.

Beacon disponíveis no mercado - Imagem 2
Figura 2 – alguns dos formatos e cores de beacons existentes

Atualmente, dois tipos de beacons são os mais populares:

  • iBeacon: pioneiros dentre os beacons, ainda são muito usados no mercado. Sua popularidade se deve tanto pelo pioneirismo (o que o tornou uma referência) quanto pela facilidade de uso, uma vez que sua especificação é simples.
  • Eddystone Beacon: criado pela Google, é um concorrente direto aos iBeacons. Possui como diferenciais ser de muito fácil integração com o Android e permitir que mais algumas (poucas) informações sejam enviadas junto com sua identificação, como temperatura, por exemplo.

Por razões didáticas, o projeto deste post implementará um beacon do tipo iBeacon.

Identificação de um iBeacon

Um iBeacon possui 3 tipos de informações compondo sua identificação:

  1. UUID: um ID único de 128-bits. Pode ser gerado neste site: https://www.uuidgenerator.net
  2. Major: um número inteiro (indo de 0 a 65535). Na prática, age como um identificador de grupo de dispositivos.
  3. Minor: um número inteiro (indo de 0 a 65535) . Na prática, age como um identificador de dispositivo específico num determinado grupo.

O UUID, Major e Minor, na prática, são usados de forma a permitir a segmentação de iBeacons.
Por exemplo: imagine que você possui 3 lojas em 3 cidades diferentes (São Paulo, Rio de Janeiro e Belo Horizonte) e que cada loja vende só três tipos de produtos: sapatos, meias e cintos. Ainda, você irá colocar um iBeacon por setor (setor de sapatos, setor de meias e setor de cintos) em cada loja. Uma forma de utilizar o UUID, Major e Minor para segmentar suas três lojas e permitir que um app único para toda sua rede de lojas identifique em que loja e setor que você está localizado poderia ser:

Cidade – São Paulo:

  • UUID: único para a loja de São Paulo
  • Major (referente à loja): 1
  • Minor (setor de sapatos): 1
  • Minor (setor de meias): 2
  • Minor (setor de cintos): 3

Cidade – Rio de Janeiro:

  • UUID: único para a loja do Rio de Janeiro
  • Major (referente à loja): 2
  • Minor (setor de sapatos): 1
  • Minor (setor de meias): 2
  • Minor (setor de cintos): 3

Cidade – Belo Horizonte:

  • UUID: único para a loja de Belo Horizonte
  • Major (referente à loja): 3
  • Minor (setor de sapatos): 1
  • Minor (setor de meias): 2
  • Minor (setor de cintos): 3

Dessa forma, um único app (que conheça os UUIDs de todos os seus iBeacons) conseguiria detectar em que loja e setor está, podendo oferecer ofertas exclusivas de acordo com seu perfil de compra e também estatísticas variadas: setores mais visitados, tempo de permanência por setor e muito mais.

Beacon com ESP32

O ESP32 oferece conectividade Bluetooth, tanto clássico quanto BLE (Bluetooth Low Energy). Dessa forma, um ESP32 pode ser usado diretamente (sem sensores e módulos externos adicionais) para se desenvolver um iBeacon.

Ainda, se você desejar, pode usar o ESP32 como iBeacon e como outra coisa simultaneamente, trabalhando com wi-fi e Bluetooth ao mesmo tempo, por exemplo. Portanto, é possível transformar o ESP32 em um iBeacon com esteróides!

Pontos importantes

Os beacons, além de enviarem dados referentes a sua identificação, enviam qual é seu fabricante. Este é um dado obrigatório. Para fins de teste, o iBeacon desenvolvido neste post irá considerar a Apple como fabricante (até por razões de maior compatibilidade, uma vez que os iBeacons são especificados originalmente pela Apple).

Porém, se você deseja fazer seu próprio iBeacon (ou outro tipo de beacon) proprietário / comercial você deve, obrigatoriamente,  registrar sua empresa como fabricante no Bluetooth SIG (Special Interest Group). Caso você usar indevidamente o identificador de um outro fabricante, poderá ter consequências legais.

Programando um Beacon com ESP32 com a Arduino IDE

Para o projeto deste post, o ESP32 será programado utilizando a Arduino IDE. Caso você não saiba como programar o ESP32 na Arduino IDE, eu recomendo a leitura deste artigo.

Código-fonte do projeto

O código-fonte do projeto pode ser visto abaixo.
Importante: leia atentamente os comentários para total compreensão do mesmo.

#include "BLEDevice.h"
#include "BLEUtils.h"
#include "BLEServer.h"
#include "BLEBeacon.h"

/* GPIO onde está o LED a ser piscado para indicar funcionamento
(breathing light) */
#define GPIO_BREATHING_LIGHT 2 /* 2 é o GPIO que está ligado o LED já contido na placa */

/* Para gerar uma UUID, uma sugestão é utilizar o site a seguir:
https://www.uuidgenerator.net/
*/

/* UUID do Beacon BLE (128 bits) */
/*
* Importante: o UUID tem seu endian invertido quando lido em um app qualquer para scan BLE.
* Logo, esse UUID será lido como: 0ffcd8742d3d-75a3-7f40-e78a-7035c02f
*/

#define BEACON_UUID "2fc03570-8ae7-407f-a375-3d2d74d8fc0f"

/* IMPORTANTE: o código/ID do fabricante é um identificador único, registrado no
Bluetooth SIG (Special Interest Group). Logo, trata-se de um identificador
globalmente conhecido. Para fins de teste utilize um ID qualquer mas,
em caso de fazer um produto comercial, NUNCA UTILIZE UM ID DE UMA EMPRESA
OU FABRICANTE QUE NÃO SEJA A SUA. Isso poderá levar a problemas legais.
Aqui, neste exemplo, a finalidade é de aprendizado somente.
*/
/* Lista com fabricantes registrados na SIG:
Company Identifiers
Importante: o código deve ser usado nesse programa com endian diferente do oferecido na lista Por exemplo, se na lista o fabricante está como 0x1234, deve ser usado aqui como 0x3412. */ #define ID_FABRICANTE_BEACON 0x4C00 /* Major e Minor do Beacon (assumindo 1 grupo (major) com 1 beacon somente (minor) */ #define MAJOR_BEACON 1 #define MINOR_BEACON 1 /* Dados do beacon (tipo, fabricante, uuid, major, minor e tx power) */ #define BEACON_DATA "" #define BEACON_DATA_SIZE 26 #define BEACON_DATA_TYPE 0xFF /* Ver: https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile/ */ /* Objeto global para gerar o advertising do BLE */ BLEAdvertising *pAdvertising; // BLE Advertisement type /* Protótipos */ void configura_beacon(void); /* Função: configura o Beacon BLUE Parâmetros: nenhum Retorno: nenhum */ void configura_beacon(void) { /* Cria um objeto para gerenciar o Beacon */ BLEBeacon ble_beacon = BLEBeacon(); /* Código/ID do fabricante */ /* IMPORTANTE: o código/ID do fabricante é um identificador único, registrado no Bluetooth SIG (Special Interest Group). Logo, trata-se de um identificador globalmente conhecido. Para fins de teste utilize um ID qualquer mas, em caso de fazer um produto comercial, NUNCA UTILIZE UM ID DE UMA EMPRESA OU FABRICANTE QUE NÃO SEJA A SUA. Isso poderá levar a problemas legais. Aqui, neste exemplo, a finalidade é de aprendizado somente. */ ble_beacon.setManufacturerId(ID_FABRICANTE_BEACON); /* Configura proximityu, major e minor do Beacon */ ble_beacon.setProximityUUID(BLEUUID(BEACON_UUID)); ble_beacon.setMajor(MAJOR_BEACON); ble_beacon.setMinor(MINOR_BEACON); /* Configura advertiser BLE */ BLEAdvertisementData advertisement_data = BLEAdvertisementData(); BLEAdvertisementData scan_response_data = BLEAdvertisementData();   /* Indica que Bluetooth clássico não deve ser suportado */ advertisement_data.setFlags(0x04);   /* Informando os dados do beacon */ std::string strServiceData = ""; strServiceData += (char)BEACON_DATA_SIZE; strServiceData += (char)BEACON_DATA_TYPE; strServiceData += ble_beacon.getData(); advertisement_data.addData(strServiceData); /* configura informações dos dados a serem enviados pelo beacon e informações de scan no advertiser */ pAdvertising->setAdvertisementData(advertisement_data); pAdvertising->setScanResponseData(scan_response_data); } void setup() { Serial.begin(115200); Serial.println("Fazendo inicializacao do beacon..."); /* Configura breathing light */ pinMode(GPIO_BREATHING_LIGHT, OUTPUT); digitalWrite(GPIO_BREATHING_LIGHT, LOW); /* Cria e configura um device e server BLE */ BLEDevice::init("ESP32 - Beacon BLE"); BLEServer *pServer = BLEDevice::createServer();   /* Inicializa e configura advertising */ pAdvertising = BLEDevice::getAdvertising(); BLEDevice::startAdvertising();   configura_beacon(); /* Começa a funcionar como beacon (advertiser entra em ação) */ pAdvertising->start(); Serial.println("O beacon foi inicializado e ja esta operando."); } /* Loop principal: apenas pisca LED ligado ao GPIO definido em GPIO_BREATHING_LIGHT para indicar que ESP32 está ligado */ void loop() { digitalWrite(GPIO_BREATHING_LIGHT, LOW); delay(500); digitalWrite(GPIO_BREATHING_LIGHT, HIGH); delay(500); }

Teste do Beacon com ESP32

Para testar o projeto, basta alimentar o ESP32 e utilizar um aplicativo scanner BLE (ou um especificamente scanner de Beacons) para encontrar o iBeacon desenvolvido e comprovar seu funcionamento. Enquanto estiver em funcionamento, o ESP32 pisca o LED built-in (funcionando como um breathing light do projeto).

Eu utilizo smartphone com sistema operacional Android e, para trabalhar com dispositivos BLE, eu gosto muito do aplicativo nRF Connect for Mobile. Antes de utilizar qualquer aplicativo para fazer scan de Beacons é fundamental ligar o Bluetooth e a localização de seu smartphone.

Com o ESP32 funcionando, abra o app e faça o scan clicando sobre o botão “Scan” no canto superior direito. Aguarde poucos segundos e você verá o iBeacon do projeto (de nome “ESP32 – Beacon BLE”) na lista de dispositivos encontrados.  Clique sobre ele e veja todas suas informações, incluindo a sua identificação (UUID, Major e Minor) e fabricante (nesse caso, para fins de teste somente, finge ser um iBeacon Apple). Observe a figura 3.

Beacon com ESP32 - Imagem 3
Figura 3 – iBeacon feito com ESP32 aparecendo no scan BLE

Gostou deste post sobre como desenvolver seu próprio beacon com ESP32? Deixe seu comentário logo abaixo.

Faça seu comentário

Acesse sua conta e participe

9 Comentários

  1. Pedro, bom dia, gostaria de saber como faço para capiturar em outro dispositivo informações de dados de beacon com um outro esp32, ou mandar, uma informação para ele, se isso é possível?

  2. Pedro, boa tarde. Gostaria muito de saber se existe a possibilidade de detectar a distância e/ou localização do beacon por meio dessa mesma aplicação.

  3. Excelente texto.
    Acabei ficando com uma dúvida. É possível enviar dados com o iBeacon Ble? Num cenário de múltiplos Beacons e Servidores BLE esse seria um bom cenário?

    Desde já, agradeço!

    1. Markus, boa noite.

      Primeiramente, obrigado pelos elogios.
      No caso, um beacon do tipo iBeacon (como o deste post) não permite esse tipo de envio.
      Existem outros tipos de beacon (como, por exemplo, o Eddystone) que permitem enviar alguns dados.

      Atenciosamente,
      Pedro Bertoleti

  4. Excelente post. Muito esclarecedor.
    É possível fazer o processo inverso para usar um esp32 para reconhecer beacons próximos?

    1. Markus, boa noite.

      Primeiramente, obrigado pelos elogios.
      No caso, um beacon do tipo iBeacon (como o deste post) não permite esse tipo de envio.
      Existem outros tipos de beacon (como, por exemplo, o Eddystone) que permitem enviar alguns dados.

      Atenciosamente,
      Pedro Bertoleti

    2. Markus, desculpa, respondi a dúvida do Paulo aqui, fiz confusão.

      Primeiramente, obrigado pelos elogios.
      Sim, é possível fazer o ESP32 reconhecer outros beacons. Para isso, basta utilizar um BLE scanner (tem nos próprios exemplos das bibliotecas do ESP32).

      Atenciosamente,
      Pedro Bertoleti

  5. Olá comprei a ESP32 aqui do site Flip-Flop
    Segue exemplo de programa com comunicação Wifi
    https://www.youtube.com/watch?v=nz70smAvpW8
    Att
    Jonatas Ferreira