Example on setting up esp32 as BLE server?

Hi @ashald

Your work is a very welcome oasis in a google search desert :grinning:

I have tried to implement this to simulate a BLE temperature sensor to be received by a Viltron controller, the code works up to this line.

          // Force esp_ble to use new data
          id(ble).get_advertising()->start();

This causes a core panic. No Idea why and I don’t know how to decode a backtrace from esphome ,

If I rem the above line it boots normally, but obviously doesn’t transmit any ble signal

Logs are here:

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13132
load:0x40080400,len:3036
entry 0x400805e4
[I][logger:262]: Log initialized
[C][ota:469]: There have been 0 suspected unsuccessful boot attempts.
[D][esp32.preferences:114]: Saving 1 preferences to flash...
[D][esp32.preferences:143]: Saving 1 preferences to flash: 0 cached, 1 written, 0 failed
[I][app:029]: Running through setup()...
[C][dht:011]: Setting up DHT...
[C][esp32_ble:027]: Setting up BLE...
[D][esp32_ble:043]: BLE setup complete
[C][wifi:038]: Setting up WiFi...
[C][wifi:039]:   Local MAC: 30:AE:A4:8B:A8:4C
[D][wifi:387]: Starting scan...
[D][advertisement:068]: Refreshing advertisement
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.

Core  1 register dump:
PC      : 0x400d86ca  PS      : 0x00060b30  A0      : 0x800dfb00  A1      : 0x3ffcd410  
A2      : 0x00000000  A3      : 0x00000000  A4      : 0x3ffc3c44  A5      : 0x00000000  
A6      : 0x00000000  A7      : 0x003fffff  A8      : 0x00000000  A9      : 0x00000001  
A10     : 0x3ffcd480  A11     : 0x00000000  A12     : 0x0000000c  A13     : 0x3ffcd48c  
A14     : 0x3ffc0230  A15     : 0x00000000  SAR     : 0x0000001d  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x0000007c  LBEG    : 0x400913cc  LEND    : 0x400913d7  LCOUNT  : 0xffffffff  


Backtrace:0x400d86c7:0x3ffcd4100x400dfafd:0x3ffcd470 0x400dfa4d:0x3ffcd4b0 0x401f3f47:0x3ffcd4d0 0x401f3f77:0x3ffcd4f0 0x401f3de1:0x3ffcd510 0x400df993:0x3ffcd530 0x400de7c2:0x3ffcd580 0x400e061e:0x3ffcd5b0 0x400e646e:0x3ffcd6c0 




ELF file SHA256: 0000000000000000

Rebooting...

YAML is here

esphome:
  name: ble-server
  includes:
  - ble-server-structs.h

esp32_ble:
    id: ble

esp32:
  board: esp32dev
  framework:
    type: arduino

time:
  - platform: sntp
    id: ntp

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "REDACTED"

ota:
  password: "REDACTED"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "ble-server Fallback Hotspot"
    password: "REDACTED"

captive_portal:
    


sensor:
  - platform: dht
    pin: GPIO16
    temperature:
      id: ble_server_temperature
      name: "Ble Server Temperature"
      filters:
      - or:
        - throttle: 10s
        - delta: 0.2
      device_class: temperature
      state_class: measurement
      unit_of_measurement: °C
    humidity:
      id: ble_server_humidity
      name: "Ble Server Humidity"
      filters:
      - delta: 2
      device_class: humidity
      state_class: measurement
      unit_of_measurement: "%"
    update_interval: 10s



interval:
  - interval: 10seconds
    then:
      - lambda: |-
          ESP_LOGD("advertisement", "Refreshing advertisement");

          // We allocate single instance in memory and refresh it in place
          static manufacturer_data_t* advertisement = new manufacturer_data_t;

          // Assuming there is a time component configured with identifier ntp
          advertisement->data.timestamp = id(ntp).now().timestamp;

          // Assuming there is a sensor component configured with identifier ble_server_temperature
          advertisement->data.ble_server_temperature = (uint16_t) id(ble_server_temperature).state;

          if (advertisement->company_id == 0) { // Execute once after boot for initial setup
              ESP_LOGD("advertisement", "Initializing advertisement");

              advertisement->company_id = 0xFFFF; // 0xFFFF reserved for local testing and non-commercial use
              id(ble).get_advertising()->set_manufacturer_data((uint8_t*) advertisement, sizeof(manufacturer_data_t));

              ESP_LOGD("main", "Advertisement initialized");
          }

          // Force esp_ble to use new data
          id(ble).get_advertising()->start();

          ESP_LOGD("advertisement", "Advertisement refreshed");


ble-server-structs.h

typedef struct payload {

  time_t   timestamp;
  uint16_t ble_server_temperature;

} __attribute__((packed)) payload_t;


typedef struct manufacturer_data {

  uint16_t   company_id;
  payload_t  data;

} manufacturer_data_t;

Any idea what I am doing wrong?