[Tuto] ESP32 comme ibeacon

Posté sur: oct. 30, 2022

Catégories: Arduino

Auteur: Fabien

Tags: ibeacon , esp32 , wemos , oled

ESP32 comme ibeacon

Nous allons aujourd'hui réalisé une balise ibeacon avec une carte ESP32 Wemos avec écran OLED. L'objectif est d'afficher sur l'écran, les informations de la balise ibeacon pour pouvoir faire des essais applicatifs.

Comme base de réflexion, il y a ce tutoriel pour sa gestion de l'écran et 

Coté paramétrage de l'IDE, si ce n'est pas déjà fait il vous faudra ajouter le package ESP32 à votre IDE et sélectionner "WEMOS LOLIN32".

Step 1: Tester l'écran

Pour tester l'écran, nous allons utiliser la librairie SSD1306 pour gérer cet écran et afficher simplement un Test.

  
#include "SSD1306.h"
SSD1306 display(0x3c, 5, 4);

void setup() {
// Paramétrage écran
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_24);
}

void loop() {
display.clear();
display.setColor(WHITE);
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(64, 15, "Test");
display.setFont(ArialMT_Plain_24);
display.display();
delay(10);
}

Step 2: Créer un ibeacon

Maintenant nous allons faire un code pour générer un point ibeacon, nous utilisons pour cela l'exemple BLE_iBeacon qui est inclue en installant le package de carte ESP32. Il se trouve dans Fichier / Exemples / ESP32 BLE Arduino / BLE_iBeacon

  /*     Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp     Ported to Arduino ESP32 by pcbreflux  */       /*     Create a BLE server that will send periodic iBeacon frames.     The design of creating the BLE server is:     1. Create a BLE Server     2. Create advertising data     3. Start advertising.     4. wait     5. Stop advertising.     6. deep sleep       */  
#include "sys/time.h"
#include "BLEDevice.h"
#include "BLEUtils.h"
#include "BLEBeacon.h"
#include "esp_sleep.h"

#define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up
RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory
RTC_DATA_ATTR static uint32_t bootcount; // remember number of boots in RTC Memory
#ifdef __cplusplus
extern "C" {
#endif
uint8_t temprature_sens_read();
//uint8_t g_phyFuns;
#ifdef __cplusplus
}
#endif
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
BLEAdvertising *pAdvertising;
struct timeval now;
#define BEACON_UUID "8ec76ea3-6668-48da-9866-75be8bc86f4d" // UUID 1 128-Bit (may use linux tool uuidgen or random numbers via https://www.uuidgenerator.net/)

void setBeacon() {
BLEBeacon oBeacon = BLEBeacon();
oBeacon.setManufacturerId(0x4C00); // fake Apple 0x004C LSB (ENDIAN_CHANGE_U16!)
oBeacon.setProximityUUID(BLEUUID(BEACON_UUID));
oBeacon.setMajor((bootcount & 0xFFFF0000) >> 16);
oBeacon.setMinor(bootcount&0xFFFF);
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
BLEAdvertisementData oScanResponseData = BLEAdvertisementData();
oAdvertisementData.setFlags(0x04); // BR_EDR_NOT_SUPPORTED 0x04
std::string strServiceData = "";
strServiceData += (char)26; // Len
strServiceData += (char)0xFF; // Type
strServiceData += oBeacon.getData();
oAdvertisementData.addData(strServiceData);
pAdvertising->setAdvertisementData(oAdvertisementData);
pAdvertising->setScanResponseData(oScanResponseData);
pAdvertising->setAdvertisementType(ADV_TYPE_NONCONN_IND);
}

void setup() {
Serial.begin(115200);
gettimeofday(&now, NULL);
Serial.printf("start ESP32 %dn",bootcount++);
Serial.printf("deep sleep (%lds since last reset, %lds since last boot)n",now.tv_sec,now.tv_sec-last);
last = now.tv_sec;
// Create the BLE Device
BLEDevice::init("ESP32 as iBeacon");
// Create the BLE Server
// BLEServer *pServer = BLEDevice::createServer(); // <-- no longer required to instantiate
BLEServer, less flash and ram usage
pAdvertising = BLEDevice::getAdvertising();
setBeacon();
// Start advertising
pAdvertising->start();
Serial.println("Advertizing started...");
delay(100);
pAdvertising->stop();
Serial.printf("enter deep sleepn");
esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION);
Serial.printf("in deep sleepn");
}

void loop() {
}

Vous devriez voir passer les lignes suivantes dans le port série:

Moniteur série

Sur votre téléphone, avec une application, vous devriez voir:

Step 3: Afficher les datas du beacon sur l'écran

Désormais, nous allons passer en define les paramètres de notre ibeacon et les imprimer sur l'écran.

  
// Type de carte: WEMOS LOLIN32
#include "SSD1306.h"
#include "sys/time.h"
#include "BLEDevice.h"
#include "BLEUtils.h"
#include "BLEServer.h"
#include "BLEBeacon.h"
#include "esp_sleep.h"
SSD1306 display(0x3c, 5, 4);
#define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
BLEAdvertising *pAdvertising; // BLE Advertisement type
struct timeval now;
#define BEACON_UUID "87b99b2c-90fd-11e9-bc42-526af7764f64" // UUID 1 128-Bit (may use linux tool uuidgen or random numbers via https://www.uuidgenerator.net/)
#define MAJOR 12345678
#define MINOR 87654321

void setBeacon() {
BLEBeacon oBeacon = BLEBeacon();
oBeacon.setManufacturerId(0x4C00); // fake Apple 0x004C LSB (ENDIAN_CHANGE_U16!)
oBeacon.setProximityUUID(BLEUUID(BEACON_UUID));
oBeacon.setMajor(MAJOR);
oBeacon.setMinor(MINOR);
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
BLEAdvertisementData oScanResponseData = BLEAdvertisementData();
oAdvertisementData.setFlags(0x04); // BR_EDR_NOT_SUPPORTED 0x04
std::string strServiceData = "";
strServiceData += (char)26; // Len
strServiceData += (char)0xFF; // Type
strServiceData += oBeacon.getData();
oAdvertisementData.addData(strServiceData);
pAdvertising->setAdvertisementData(oAdvertisementData);
pAdvertising->setScanResponseData(oScanResponseData);
}

void setup() {
Serial.begin(115200);
// Create the BLE Device
BLEDevice::init("ESP32 as iBeacon");
// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer(); // <-- no longer required to instantiate
BLEServer, less flash and ram usage
pAdvertising = BLEDevice::getAdvertising();
BLEDevice::startAdvertising();
setBeacon();
// Start advertising
pAdvertising->start();
Serial.println("Advertizing started...");
delay(100);
pAdvertising->stop();
// Paramétrage écran
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_24);
}

void loop() {
display.clear();
display.setColor(WHITE);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(0, 0, "BEACON_UUID:");
display.drawString(0, 12, String(BEACON_UUID));
display.drawString(0, 24, "Minor:"+String(MINOR));
display.drawString(0, 36, "Major:"+String(MAJOR));
display.setFont(ArialMT_Plain_10);
display.display();
delay(10);
}

Ce qui donne sur l'écran:

L'écran de l'ibeacon

laissez un commentaire

Se connecter