Recents in Beach


Receba o meu conteúdo GRATUITAMENTE


Sensor de Presença com iTag Bluetooth BLE




Hoje vamos falar sobre o iTag, que é um chaveiro com tecnologia parecida com o iBeacon, de Bluetooth BLE, que serve como um detector de presença. Uma maravilha da automação residencial. Vamos utilizar um ESP32 programando com Arduino IDE.


Essa montagem tem milhares de utilidades: o portão da garagem pode perceber sua aproximação e abrir sozinho, as luzes acenderem conforme a detecção de sua presença, entre outras inúmeras. Sem contar que, cada morador da casa, por exemplo, pode ter seu chaveiro próprio e fazer suas próprias escolhas em relação a execução de comandos em um determinado ambiente.
Quero ressaltar que a nossa montagem com o ESP32 permite que o radio Bluetooth detecte a presença por um raio determinado, isso através do sinal dbm, possibilitando, por exemplo, a localização ou rastreamento de pessoas dentro de um local, identificação de indivíduo específico para o produto que você deve ofertar, entre outros.
No nosso projeto, ao invés de ligar um relé, nós acendemos um Led que já está dentro do ESP32. Mas, no seu código fonte, se você for automatizar alguma coisa, você vai mandar o ESP32 ligar um pino que liga o relé.


Demonstração

Na demonstração temos o ESP32 com um Led azul representando um relé ativado. Como o chaveiro está próximo do ESP32, em uma distância entre 6 e 10 metros, ele ativa esse pino. Ambos são Bluetooth BLE, ou seja de baixo consumo de energia.




iTag.ino

Incluímos a biblioteca BLEDevice e definimos os parâmetros. Apontamos também a variável que irá guardar o scan, entre outros detalhes.

#include <BLEDevice.h>

#define ADDRESS "ff:ff:c2:07:ab:16" //Endereço do iTag, conseguido pelo próprio scan
#define RELAY_PIN 2 //Pino do Relê
#define SCAN_INTERVAL 1000 //intervalo entre cada scan
#define TARGET_RSSI -100 //RSSI limite para ligar o relê.
#define MAX_MISSING_TIME 5000 //Tempo para desligar o relê desde o momento que o iTag não for encontrado

BLEScan* pBLEScan; //Variável que irá guardar o scan
uint32_t lastScanTime = 0; //Quando ocorreu o último scan
boolean found = false; //Se encontrou o iTag no último scan
uint32_t lastFoundTime = 0; //Tempo em que encontrou o iTag pela última vez
int rssi = 0;


onResult

Aqui temos o Callback das chamadas ao scan e a função que nos mostra quando um dispositivo é identificado e se este é o que esperávamos. Em caso positivo, ele guarda o rssi deste dispositivo.

//Callback das chamadas ao scan
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks
{
    void onResult(BLEAdvertisedDevice advertisedDevice)
    {
        //Sempre que um dispositivo for encontrado ele é mostrado aqui
        Serial.print("Device found: ");      
        Serial.println(advertisedDevice.toString().c_str());

        //Se for o dispositivo que esperamos
        if(advertisedDevice.getAddress().toString() == ADDRESS)
        {
            //Marcamos como encontrado, paramos o scan e guardamos o rssi
            found = true;
            advertisedDevice.getScan()->stop();
            rssi = advertisedDevice.getRSSI();
            Serial.println("RSSI: " + rssi);
        }
    }
};


setup

No setup, configuramos o pino do relê como saída e coloca com low. Ainda, guardamos a referência e configuramos o objeto scan.

void setup()
{
    Serial.begin(115200);
    //Configura o pino do relê como saída e coloca com low
    pinMode(RELAY_PIN, OUTPUT);
    digitalWrite(RELAY_PIN, LOW);

    //Guardamos a referência e configuramos o objeto scan
    BLEDevice::init(""); 
    pBLEScan = BLEDevice::getScan();
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true);
}


loop

Definimos o tempo em milissegundos desde o boot e trabalhamos com as possibilidades de localização ou não de um iTag.

void loop()
{   
    uint32_t now = millis(); //Tempo em milissegundos desde o boot

    if(found){ //Se econtrou o iTag no último scan
        lastFoundTime = millis(); //Tempo em milissegundos de quando encontrou
        found = false;
        
        if(rssi > TARGET_RSSI){ //Se está dentro do limite, ligamos o relê
            digitalWrite(RELAY_PIN, HIGH);
        }
        else{ //senão desligamos
            digitalWrite(RELAY_PIN, LOW);
        }
    }
    //Se não encontrou e o tempo desde a última vez que econtrou for maior que o tempo máximo de desaparecido
    else if(now - lastFoundTime > MAX_MISSING_TIME){
        digitalWrite(RELAY_PIN, LOW);  //Desligamos o relê
    }
    
    if(now - lastScanTime > SCAN_INTERVAL){ //Se está no tempo de fazer scan
        //Marca quando ocorreu o último scan e começa o scan
        lastScanTime = now;
        pBLEScan->start(1);
    }
}



Faça o download dos arquivos:


Postar um comentário

16 Comentários

  1. Não é possível fazer o download do arquivo .ino.

    ResponderExcluir
  2. Fernando, parabéns mais uma vez por pela matéria. O que vc recomenda um sistema de votacao remota até 500 devices? Abs

    ResponderExcluir
  3. professor Fernando, corrige esse link . Não está correto o link para o fonte. Já postei lá no youtube também.

    ResponderExcluir
  4. Excelente conteúdo, parabéns!
    Só um observação: montei esse exemplo e notei que a serial não imprimia o RSSI. Para funcionar comigo, substituí a linha 31 por
    Serial.print("RSSI: ");
    Serial.println(rssi);

    Abs!

    ResponderExcluir
  5. Muito bacana o video, só faltou explicar melhor a forma de pegar o endereço hexadecimal. Eu nao entendi como que o programa irá fazer o scan e capturar esse endereço. Tem como explicar melhor? No caso do outro exemplo que vc deu usando o hotspot do celular, o nome da rede do celular deveria ser cadastrado no codigo para que o ESP32, reconhecesse fizesse uma compração e ativasse o relé, nesse eu nao entendi como é feito o primeiro scanner para conseguir o endereço hexadecimal.

    ResponderExcluir
  6. Dear Professor, I am trying to modify the program so that the relay will activate if I find 2 ITAG By defining 2 ADRESS and including it in the if comparison with &&, the conditional never gives me true.
    Could you help me

    Professor, Estou tentando modificar o programa para que o relé seja ativado se eu encontrar 2 ITAG específicos. Ao definir 2 ADRESS e incluí-lo na comparação if com &&, o condicional nunca me dá a verdade.
    Poderia ajudar-me

    Estimado profesor, estoy intentando modificar el programa para que el relay se active si encontro 2 itag determinados. Al definir 2 ADRESS e incluirla la comparación en el if con &&, el condicional nunca me da true.
    Podría ayudarme


    ResponderExcluir
  7. Fernando, excelente vídeo. Só uma dúvida a respeito de segurança: é possível clonar o endereço do iTag? Por que como o chaveiro iTag fica ligado por um tempo e se tiver um BLE scanner posso obter o endereço do iTag e clonar em outro chaveiro, semelhante ao que acontece com RFID?

    ResponderExcluir
  8. Tenho um projeto no esp32 porem uma parte do projeto ja ocupa grande parte da memoria interna do esp32. Gostaria de saber se tem como expandir essa memoria interna para eu colocar esse codigo do BLE e se não tiver como faço para expandir de outra forma? Desde ja agradeço.

    ResponderExcluir
  9. Fiz todos os passos mas esta dando esse erro no final...
    pode me dizer oque é ??



    Arduino: 1.8.13 (Windows 10), Placa:"DOIT ESP32 DEVKIT V1, 80MHz, 921600, None"

    iTag_Multi:11:33: error: expected class-name before '{' token

    class ITag : public BLENotifier {

    ^

    D:\SETUPs\Arduino esp32\Codigos\iTag_Multi\iTag_Multi.ino: In member function 'void ITag::connect()':

    iTag_Multi:37:53: error: no matching function for call to 'BLEDevice::createClient(uint16_t)'

    client = BLEDevice::createClient(appId++);

    ^

    In file included from D:\SETUPs\Arduino esp32\Codigos\iTag_Multi\iTag_Multi.ino:1:0:

    C:\Users\DN_Ni\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\BLE\src/BLEDevice.h:34:21: note: candidate: static BLEClient* BLEDevice::createClient()

    static BLEClient* createClient(); // Create a new BLE client.

    ^

    C:\Users\DN_Ni\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\BLE\src/BLEDevice.h:34:21: note: candidate expects 0 arguments, 1 provided

    iTag_Multi:48:61: error: no matching function for call to 'BLERemoteCharacteristic::registerForNotify(ITag*)'

    remoteCharacteristic->registerForNotify(this);

    ^

    In file included from C:\Users\DN_Ni\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\BLE\src/BLERemoteService.h:16:0,

    from C:\Users\DN_Ni\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\BLE\src/BLEClient.h:19,

    from C:\Users\DN_Ni\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\BLE\src/BLEDevice.h:19,

    from D:\SETUPs\Arduino esp32\Codigos\iTag_Multi\iTag_Multi.ino:1:

    C:\Users\DN_Ni\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\BLE\src/BLERemoteCharacteristic.h:50:14: note: candidate: void BLERemoteCharacteristic::registerForNotify(notify_callback, bool, bool)

    void registerForNotify(notify_callback _callback, bool notifications = true, bool descriptorRequiresRegistration = true);

    ^

    C:\Users\DN_Ni\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\BLE\src/BLERemoteCharacteristic.h:50:14: note: no known conversion for argument 1 from 'ITag*' to 'notify_callback {aka std::function}'

    exit status 1

    expected class-name before '{' token



    Este relatório teria mais informações com
    "Mostrar a saida detalhada durante a compilação"
    opção pode ser ativada em "Arquivo -> Preferências"

    ResponderExcluir
  10. eu comprei um itag no mercado livre, mas estou com um problema que ele desliga automaticamente após 10 minutos. Existe alguma configuração para fazer no itag?

    ResponderExcluir
    Respostas
    1. estou exatamente com o mesmo problema. conseguiu resolver?
      os meus 6 chaveiros desligam após 15 minutos. TODOS JUNTOS.
      Achei estranho, pois o Fernando K disse que usa esse chaveiro. Se usa mesmo como ele fez para manter o chaveiro ligado?
      Paulo, conseguiu alguma informação?

      Excluir
    2. Barini, o silencio do Fernando K foi o mesmo.... eu acabei comprando diretemente do Ali Express uns chaveiros nfc , mas tambem não fiquei muito satisfeito, pois a bateria não durou mais do que 30 dias, resolvi então fazer um emulador no celular, este esta funcionando perfeitamente.

      Excluir
  11. Fernando K, muito bom este projeto. Funcionou muito bem. Só que eu me deparei com um problema, por favor me digam se só comigo... o chaveiro iTag só fica ligado por 15 minutos (no cronometro). Comprei 6 unidades.... todas elas com as mesmas características... se não está 'pareado', ele desliga em 15 minutos.
    Se eu saio de casa... ligo o chaveiro, em 15 minutos ele desliga... daí chego em casa ele está desligado!!!!
    Como vc faz para manter o seu chaveiro ligado? vc disse no vídeo que usa este chaveiro. Como vc faz para mante-lo ligado?

    ResponderExcluir
  12. Barini, vc pode me falar quantos iTag posso ligar no esp32, no maxino

    ResponderExcluir