banner

Ir para o Forum

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:


6 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

Tecnologia do Blogger.