Как получить продолжительность сканирования менее 1 секунды с помощью Arduino BLE?
Я хочу непрерывно сканировать другие устройства Bluetooth с помощью моего ESP32 с использованием BLE. Метод scan принимает только целые числа больше 0, например scan->start(1, false). Однако я хочу, чтобы результаты были более «отзывчивыми». и продолжительность сканирования в 1 секунду слишком велика. Это мой пример кода:
#include <Arduino.h>
#include <BLEAdvertisedDevice.h>
#include <BLEDevice.h>
#include <BLEScan.h>
#include <string>
#include <iostream>
const int PIN = 2;
const int CUTOFF = -40;
BLEScan* scan;
#define SERVICE_UUID "f5aeb701-4395-4387-b8d4-e1f542b05151"
#define CHARACTERISTIC_UUID "b2bd617f-6f78-45e7-bfdd-3edf29a5661a"
void setup() {
pinMode(PIN, OUTPUT);
BLEDevice::init("ESP32 GrooveBrick");
Serial.begin(9600);
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // функции, которые помогают решить проблему с подключением iPhone
pAdvertising->setMinPreferred(0x12);
scan = BLEDevice::getScan();
scan->setActiveScan(true);
/*!< Scan interval. This is defined as the time interval from
when the Controller started its last LE scan until it begins the subsequent LE scan.
Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
Time = N * 0.625 msec
Time Range: 2.5 msec to 10.24 seconds*/
scan->setInterval(100); //интервал (как часто происходит сканирование)
/*!< Scan window. The duration of the LE scan. LE_Scan_Window
shall be less than or equal to LE_Scan_Interval
Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
Time = N * 0.625 msec
Time Range: 2.5 msec to 10240 msec */
scan->setWindow(99); // окно (длина сканирования) должно быть <= интервалом
BLEDevice::startAdvertising();
}
void loop() {
BLEScanResults results = scan->start(1, true);
int best = CUTOFF;
std::cout << "Scanning!" << "\n";
for (int i = 0; i < results.getCount(); i++) {
BLEAdvertisedDevice device = results.getDevice(i);
std::cout << "Found BT-device: " << device.getName() << " RSSI: " << std::to_string(device.getRSSI()) << "\n";
int rssi = device.getRSSI();
if (rssi > best) {
best = rssi;
}
}
digitalWrite(PIN, best > CUTOFF ? HIGH : LOW);
scan->clearResults(); // удаляем результаты из буфера BLEScan, чтобы освободить память
}
@Philipp, 👍0
Обсуждение2 ответа
▲ 2
вы не можете использовать обратный вызов из этой функции, но вы можете добавить свой собственный обратный вызов, который будет получать каждое новое радиособытие.
добавьте это в свой код инициализации:
BLEDevice::setCustomGapHandler(custom_handler);
и это перед этим:
static void it_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
switch (event)
{
case ESP_GAP_BLE_SCAN_RESULT_EVT:
if (param->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT)
{
// Это событие срабатывает каждый раз, когда обнаруживается новое устройство, и содержит объявленные данные.
// Нам следует избегать обработки или печати чего-либо здесь, чтобы избежать перегрузки оборудования
// log_i("ESP_GAP_BLE_SCAN_RESULT_EVT");
if (param->scan_rst.ble_adv != NULL)
{
//это гарантирует наличие данных для обработки
}
}
break;
default:
// log_i("Событие %d необработано", event);
break;
}
}
,
@Italo Soares
▲ 0
Самое простое решение такое: добавьте эту строку:
BLEDevice::getScan()->stop();
Пример:
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <Arduino.h>
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
// Получить данные сервиса с рекламируемого устройства
//std::string serviceData = advertisingDevice.getServiceData();
std::string deviceName = advertisedDevice.getName();
if (!deviceName.empty() && deviceName.find("Drone_") != std::string::npos) { // Используйте .empty() вместо !
Serial.println("Scan-Ergebnis gefunden:");
// Вывод типа устройства и уровня сигнала RSSI
Serial.print("Gerätename: ");
Serial.println(advertisedDevice.getName().c_str());
Serial.print("Signalstärke (RSSI): ");
Serial.println(advertisedDevice.getRSSI());
}
BLEDevice::getScan()->stop();
}
};
void setup() {
Serial.begin(115200);
delay(3000); // Подождать 1 секунду
Serial.println("Startet kontinuierlichen BLE-Scan...");
// Инициализация BLE
BLEDevice::init("");
// Настроить сканирование BLE
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); // Активное сканирование для более точных значений RSSI
pBLEScan->setInterval(32); // Интервал сканирования в единицах 0,625 мс
pBLEScan->setWindow(32); // Сканируем окно с шагом 0,625 мс
}
void loop() {
// Запустить сканирование без ограничения по времени и очистить результаты сразу после
BLEDevice::getScan()->start(0.1, true); // короткое сканирование для повторения результатов
//int deviceCount = BLEDevice::getScan()->getResults().getCount();
//Serial.print("Количество найденных устройств: ");
//Serial.println(deviceCount);
BLEDevice::getScan()->clearResults(); // Немедленно очистить результаты для следующего сканирования
}
,
@druckgott
Смотрите также:
- Библиотека ардуино или код для ESP32 для сканирования устройств Bluetooth?
- ESP32 запускает BLE после глубокого сна
- Антенна для ESP32-pico-d4
- Как получить имя подключенного устройства через BLE?
- WifiClient и aREST на esp32 – цикл до получения новых инструкций?
- ESP32 - BLE не подключается/не перезапускается после легкого сна
- Ошибка компиляции модуля ESP32 Wrover в виртуальной машине Linux
- Служба BLE ESP32 не видна Node-RED
Вы когда-нибудь решали эту проблему?, @NobbysNutz
Привет, IIRC, я так и не решил эту проблему.. извини., @Philipp