• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Посылка BLE биконов.

jenya7

Member
Инициализация
C++:
BLEAdvertising *pAdvertising;
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();

char beacon_data[25];
uint16_t beconUUID = 0xFEAA;

void BLE_SetBeacon(uint16_t min_interval, uint16_t max_interval)
{
    BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
    BLEAdvertisementData oScanResponseData = BLEAdvertisementData();

    oScanResponseData.setFlags(0x06); //GENERAL_DISC_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04
    oScanResponseData.setCompleteServices(BLEUUID(beconUUID));

    beacon_data[0] = 0x20;                
    beacon_data[1] = 0x00;                
    beacon_data[2] = 0xAA;
    beacon_data[3] = 0xBB;
    beacon_data[4] = 0xCC;
    beacon_data[5] = 0xDD;
    beacon_data[6] = 0x01;
    beacon_data[7] = 0x02;
    beacon_data[8] = 0x03;
    beacon_data[9] = 0x04;
    beacon_data[10] = 0x05;
    beacon_data[11] = 0x06;
    beacon_data[12] = 0x07;
    beacon_data[13] = 0x08;

    oScanResponseData.setServiceData(BLEUUID(beconUUID), std::string(beacon_data, 14));
    oAdvertisementData.setName("BLE_Test");
    pAdvertising->setAdvertisementData(oAdvertisementData);
    pAdvertising->setScanResponseData(oScanResponseData);
    pAdvertising->setMaxInterval(max_interval);
    pAdvertising->setMinInterval(min_interval);
}

void BLE_Init()
{
    // Create the BLE Device
    BLEDevice::init("BLE_Test");  //AgroSens
    //BLEDevice::setPower(ESP_PWR_LVL_N12);
   
    pAdvertising = BLEDevice::getAdvertising();

    BLE_SetBeacon(100, 10000);

     // Start advertising
     pAdvertising->start();
     Serial.println("Advertizing started...");
     delay(100);
     pAdvertising->stop();
}
По таймеру (раз в секунду) посылаю

C++:
void BLE_Send()
{
    count++;
    //first - update data
    beacon_data[2] = (count >> 8);          
    beacon_data[3] = (count & 0xFF);        
   
    pAdvertising->setAdvertisementData(oAdvertisementData);
    pAdvertising->start();
    delay(100);
    pAdvertising->stop();
}
Но BLE beacon scanner на телефоне не видит этих биконов. Другие видит а эти нет.
В чём может быть проблема?
 

jenya7

Member
Не верный формат AdvData.
а как создать свой бикон?
В нативном коде я делал так
C++:
void ble_ibeacon_init(void)
{
    esp_err_t status;

    esp_bluedroid_init();
    esp_bluedroid_enable();

    ESP_LOGI(DEMO_TAG, "register callback");

    if ((status = esp_ble_gap_register_callback(esp_gap_cb)) != ESP_OK)
    {
        ESP_LOGE(DEMO_TAG, "gap register error: %s", esp_err_to_name(status));
    }

    ble_adv_data[0] = 0x02; //length of this data
    ble_adv_data[1] = 0x01; //AD type
    ble_adv_data[2] = 0x06; //discover mode

    ble_adv_data[3] = 0x06;  //length of this data
    ble_adv_data[4] = 0x09;  //shortened type name
    ble_adv_data[5] = 0x4E;  //N
    ble_adv_data[6] = 0x42;  //B
    ble_adv_data[7] = 0x4C;  //L
    ble_adv_data[8] = 0x45;  //E
    ble_adv_data[9] = 0x57;  //W

    ble_adv_data[10] = 0x0F; //length of this data
    ble_adv_data[11] = 0xFF; //Manufacturer-specific data
    ble_adv_data[12] = 0x09; //Frame ID

    ble_adv_data[13] = 0xAB;
    ble_adv_data[14] = 0xBA;
    ble_adv_data[15] = 0x03;
    ble_adv_data[16] = 0x04;

    ble_adv_data[17] = 0x01;

    ble_adv_data[18] = 0x01;
    ble_adv_data[19] = 0x07;
    ble_adv_data[20] = 0x08;
    ble_adv_data[21] = 0x09;
    ble_adv_data[22] = 0x0A;
    ble_adv_data[23] = 0x0B;
    ble_adv_data[24] = 0x0C;
    ble_adv_data[25] = 0x0D;
    ble_adv_data[26] = 0x0A;
    ble_adv_data[27] = 0x0D;
    ble_adv_data[28] = 0x0A;
    ble_adv_data[29] = 0x04;

   esp_ble_gap_config_adv_data_raw((uint8_t*)&ble_adv_data,  26);

   esp_ble_gap_start_advertising(&ble_adv_params);
}
В Ардуино я не понимаю как это работает.
 

pvvx

Активный участник сообщества
так для моего бикона это не подойдёт?
Я не знаю, но все программы для работы с BLE имеют свои глюки...
Попробуйте nRF Connect в режиме сканирования. Но он тоже не воспринимает все рекламные пакеты даже если всё корректно согласно спецификации BLE - тупо не видит устройство.
 

jenya7

Member
ок. он нашёл мой бикон как Eddystone.
WhatsApp Image 2021-11-16 at 17.17.59.jpegWhatsApp Image 2021-11-16 at 17.17.58.jpeg
вопрос как мне изменить бикон чтоб использовать максимальное количество байт в payload, их 20 если я не ошибаюсь. В Raw Data -
LEN TYPE
17 0x16 0xAAFE2000AABBCCDD0102030405060708 - это максимальный размер моих данных?
9 0x09 0x4167726F53656E73 - я могу загрузить вместо имя мои данные?
 

pvvx

Активный участник сообщества
17 0x16 0xAAFE2000AABBCCDD0102030405060708 - это максимальный размер моих данных?
Максимум составляет 31 байт на рекламные данные и еще 31 байт для ответа на сканирование.

1637295813932.png
Структуры данных BLE Advertising Data в примере имеют:
1. В начале AD структуру в 3 байта c ADTYPE_FLAGS_MODES (её можно выкинуть :) ):
[02 01 06], где 06 - Flags:
bit0: LE Limited Discoverable Mode
bit1: LE General Discoverable Mode
bit2: BR/EDR Not Supported
bit3: Simultaneous LE and BR/EDR to Same Device Capable (Controller)
bit4: Simultaneous LE and BR/EDR to Same Device Capable (Host)
bit5..7: Reserved
2. Далее AD структуру 'Complete List of 16-bit Service Class UUIDs' в 4 байта:
[03 03 AAFE] (её можно выкинуть :) )
3. Далее структуру Eddystone в 18 байт.

Итого: 18+4+3 = 25 байт (из возможных 31)

9 0x09 0x4167726F53656E73 - я могу загрузить вместо имя мои данные?
Нет. Это ответ на сканирование, а не реклама. Его запрашивает активный сканер спец.посылкой посылаемой сразу, в строго ограниченное время по стандарту BLE, после приема рекламного пакета.
Иногда имя вставляют в Advertising Data, чтобы не принимать запросы на сканирование... Но тупые адаптеры в активном режиме сканирования всё равно запрашивают имя :eek:
Если вставлено в Advertising Data, то оно не лезет у вас: 25 + 10 = 35 байт.
 

pvvx

Активный участник сообщества
Если выкинуть AD структуру в 3 байта c ADTYPE_FLAGS_MODES, то windows и андроид не покажет в системном списке BT ваше устройство, но программы соединяться с ним будут, т.к. есть понятие этого флага 'по умолчанию'.
Структура полного списка сервисов никому не нужна, кроме наверно каких-то кривых программ сканеров маяков писанных ардуинщиками для андроида и ...
Если вы хотите что-то добавить в рекламу, то необходимо это делать согласно стандартам формирования AD структур.
 

pvvx

Активный участник сообщества
Для этого обычно используют id структуры = 0x16 - Service Data - 16-bit UUID
Т.е.
  1. первый байт = размеру данных + 3 (id + uuid)
  2. второй байт = id (GAP_ADTYPE) = 0x16
  3. следующие 2 байта равны 16-bit UUID, которые необходимо купить или зарегистрировать в bluetooth.com
  4. далее данные.
К примеру, устройства Xiaomi имеют uuid 0xfe95, а далее у них идут данные в формате mijia...
Список других:
16-bit UUIDsThe 16-bit UUID Numbers Document contains the following value types: GATT Service, GATT Unit, GATT Declaration, GATT Descriptor, GATT Characteristic and Object Type, 16-bit UUID for members, Protocol Identifier, SDO GATT Service, Service Class and Profile.
 

pvvx

Активный участник сообщества
На сегодня, альтернативные прошивки DIY и т.д., для датчиков температуры и влажности, используют в рекламе UUID16 равную 0x181A, GATT Service 0x181A Environmental Sensing.
Их уже обрабатывают многие "Вумные дома".
По этой причине не стоит менять их форматы, не согласовав с писателями "Вумных домов" и остальными аборигенами в open source :)
Для своих поделок я использую UUID16 0x1F11, рассчитывая, что диапазон 0x1f10...0x1f1f пока не занят, т.е. его никто пока не выкупил и использовал официально...
На сегодня, cообщество ESP32 и их производитель не выделило и не зарегистрировало никаких UUID.
 

pvvx

Активный участник сообщества
Кроме того, программное обеспечение ESP32 для BLE самое ужасное - находится на последнем месте - имеет массу недочетов.
Т.е. реализация чего-то на ESP32 в тематике BLE - это самый кошмарный случай. Там даже танцы с бубном не помогают.
 

jenya7

Member
Кроме того, программное обеспечение ESP32 для BLE самое ужасное - находится на последнем месте - имеет массу недочетов.
Т.е. реализация чего-то на ESP32 в тематике BLE - это самый кошмарный случай. Там даже танцы с бубном не помогают.
А какая альтернатива? Какой камень с BLE и WIFI за 2$ существует ещё на рынке?
 

pvvx

Активный участник сообщества
А какая альтернатива? Какой камень с BLE и WIFI за 2$ существует ещё на рынке?
Несколько вариантов RTL872x и за $1 (в пачке) - BL60x (Bouffalo, RISC-V).
В принципе, если у вас ещё старая инфраструктура - нет WiFi6, и работаете только с UDP, то даже связка BLE чипа типа TLSR826x/TLSR825x с ESP8266 будет работать гораздо качественнее (исключая зависоны ESP в WiFi).
И, говорят, есть варианты ESP32 с RISC-V, и народ надеется, что там будет лучше написан драйвер BLE. Но пока это только надежды...
 

pvvx

Активный участник сообщества
У ESP32 проблемы с приемом в BLE чисто программные. Видимо не умеют быстро переключать приемник или это связано с тормозами выполнения слишком объемного кода - не лезет раздутый код библиотек уже давно в "кэш" XIP. По этому, из-за низкой скорости выборки кода из SPI-Flash, совокупная скорость выполнения обоих ядер снижается ниже уровня 12 МГц одноядерного древнего Cortex-M3. Но при этом ESP32 жрет на полную катушку...
 
Сверху Снизу