In the previous post, you learned how to send BLE advertising packets with the esp32 chip.
To define the content of the packet, you used a struct, of the esp_ble_adv_data_t type:
The struct’s definition is included in the esp_gap_ble_api.h file:
Although there are many fields available, sometimes it is necessary to be able to define the content of the advertising packet arbitrarily. For this reason, the esp-idf framework provides a raw mode.
Instead of defining a struct, you create a byte array and fill it with the entire contents of the packet’s payload:
static uint8_t adv_raw_data[10] = {0x09,0x09,0x4c,0x75,0x6b,0x45,0x53,0x50,0x33,0x32}; |
then you can use the esp_ble_gap_config_scan_rsp_data_raw() function to pass the array to the driver. You have to specify both the array and its size as parameters:
esp_ble_gap_config_scan_rsp_data_raw(scan_rsp_raw_data, 8); |
When using this new function, it also changes the event that the driver passes to your callback function when the configuration is complete. The new event is ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT. As in the previous example, when this event is triggered you can start the advertising process:
case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: esp_ble_gap_start_advertising(&ble_adv_params); break; |
Raw data
For the advertising process to work, the data contained in the array must correspond to a valid payload.
In the blog post about the iBeacons, I’ve already shown you its structure. Let’s briefly review it:
The payload contains one or more AD (advertising data) structures. Each structure is made by 3 fields:
[checklist]
- an initial byte that represents the length (in bytes) of the structure, excluding itself
- a byte that represents the type of the data contained in the structure
- a variable number of bytes which are the actual data
[/checklist]
The codes that can be used to define the type of data can be found in the Bluetooth specifications. Depending on the type of data, it is then necessary to apply a particular format to the data that follows. The necessary information is found in the Core Specification Supplement document (available on the Bluetooth.com website).
Let’s see a simple example: the ADType 0x09 represents the complete local name, which is the name of the device. This name must be specified in AD data with simply a sequence of the ASCII codes that correspond to the different letters.
You can use a website to do the conversion:
The payload to transmit this name is therefore:
adv_raw_data[7] = {0x06,0x09,0x4d,0x79,0x42,0x4c,0x45}; |
The first byte has value 0x06 that is the sum of the name length (5 bytes) and 1 byte for the data type (0x09).
Demo
In the following video you can see how I use the raw advertising feature to simulate the advertising packet of my iBeacon and therefore I’m able to activate the relay as in the previous example.
The source code of the program is available in my Github repository.
Hey there Luca, thanks for this tutorial as well as all your series. I have a little issue implementing this one though. when I start advertising, a message shows in serial monitor that reads: E (498) BT: bta_gattc_co_cache_addr_init, Line = 333, nvs flash get blob data fail, err_code = 1102. There is no problem with the advertising and data y properly shown on any device. I implemented this tutorial in another project and same thing happens. I used an ESP-WROOM-32 as well as an ESP32-WROVER with same output. Advertising is fine and I can propery advertise data, only problem is this message appearing.
Hi Leonardo, I can’t get the same error message… are you using the latest version of the esp-idf?
Hi. I have both ubuntu and Windows. In Ubuntu, I had the latest toolchain and IDF version as of January, there I have no problems. On Windows, I made a fresh install last week due to the announcement of ESP-MDF. If you may, take a look at these pictures. https://drive.google.com/open?id=1hpr_7uNdJklE-eyygD7xQmbgm8sfZDtI. in (1), I flashed the project on Ubuntu and seems fine. (2) I did the same on windows and you can see the problem. So I restarted to Ubuntu and “monitor” there and problem persist(3). Finally, I copied the project from ubuntu to windows, flash without changing anything, and there’s the problem (4). So I believe is something introduced in the latest IDF.
someone found the solution. There’s a new option in bluedroid settings which causes this message.
https://esp32.com/viewtopic.php?t=5549&sid=c7c61eee6f0c23482a674e99183e43ba#p24069
Not clear on a couple of things. Maybe someone can help?
– Can a custom scan response message be sent to each different device? I need to send a different message to each remote device without connecting. If possible, how do I do it?
– I have multiple iOS software for BLE but I have not been able to find one that displays both the Advertisement data and the scan response data dynamically as it changes at the same time
Hi Philip, I cannot help on iOS apps because I use Android. BLE advertising is sent in broadcast, each device can respond with its own response message. If you need to send messages to specific devices, you have to implement something at application level, for example include an “address” in the adv_data.
can anyone help me i want to broad cast string in order for example i want to broad cast no.1 then after pressing push button it should start advertising np.2 all the time then after again pressing push button it should advertise no.3 all the time