Как записать с клиентского узла на серверный узел в пользовательскую службу BLE?
Я пытаюсь записать данные с клиентского узла на центральный узел в пользовательскую службу BLE.
Ниже приведен код для центрального узла (клиент)
#include <bluefruit.h>
#define suuid 0x8912
#define cuuid 0x9012
//# определить suuid 0x1256
//#определить cuuid 0x1260
uint16_t gconn_handle;
long int county;
BLEClientService displays(suuid);
BLEClientCharacteristic displayc(cuuid);
void setup()
{
Serial.begin(115200);
while ( !Serial ) delay(10); // для nrf52840 с родным usb
Serial.println("Bluefruit52 Central Custom display Example");
Serial.println("--------------------------------------\n");
// Инициализируем Bluefruit с максимальным количеством соединений, как Peripheral = 0, Central = 1
// Использование SRAM, необходимое для SoftDevice, резко возрастет с увеличением количества подключений
Bluefruit.begin(0, 1);
Bluefruit.setName("Bluefruit52 Central");
// Инициализировать дисплей-клиент
displays.begin();
// Инициализировать клиентские характеристики Display.
// Примечание: клиентский символ будет добавлен к последней службе, которая была запущена методом begin().
displayc.begin();
// Увеличить скорость мигания, чтобы он отличался от режима рекламы PrPh
Bluefruit.setConnLedInterval(250);
// Обратные вызовы для Central
Bluefruit.Central.setDisconnectCallback(disconnect_callback);
Bluefruit.Central.setConnectCallback(connect_callback);
/* Start Central Scanning
- Enable auto scan if disconnected
- Interval = 100 ms, window = 80 ms
- Don't use active scan
- Filter only accept display service
- Start(timeout) with timeout = 0 will scan forever (until connected)
*/
Bluefruit.Scanner.setRxCallback(scan_callback);
Bluefruit.Scanner.restartOnDisconnect(true);
Bluefruit.Scanner.setInterval(160, 80); // в единицах 0,625 мс
Bluefruit.Scanner.filterUuid(displays.uuid);
Bluefruit.Scanner.useActiveScan(false);
Bluefruit.Scanner.start(0); // // 0 = Не останавливать сканирование через n секунд
county = 0;
}
uint8_t toggle = 0;
void loop()
{
// ничего не делать
if (Bluefruit.connected())
{
uint8_t displaydata[5] = { 0x09, 0x10, 0x11, 0x12 };
displayc.write(displaydata,5);
//переключить UUID
/*if (county > 1)
{
Bluefruit.disconnect(gconn_handle);
if (toggle == 0)
{
displays.uuid = 0x1256;
displayc.uuid = 0x1260;
toggle = 1;
Serial.println("CONNECTING 0x1256");
}
else
{
displays.uuid = 0x8912;
displayc.uuid = 0x9012;
toggle = 0;
Serial.println("CONNECTING 0x8912");
}
county = 0;
setup();
}
//округ++;
delay(1000);
*/
}
}
/**
Callback invoked when scanner pick up an advertising data
@param report Structural advertising data
*/
void scan_callback(ble_gap_evt_adv_report_t* report)
{
// Поскольку мы настраиваем сканер с помощью filterUuid()
// Обратный вызов сканирования вызывается только для устройства с объявленным сервисом отображения
// Подключиться к устройству с сервисом отображения в рекламе
Bluefruit.Central.connect(report);
}
/**
Callback invoked when an connection is established
@param conn_handle
*/
void connect_callback(uint16_t conn_handle)
{
gconn_handle = conn_handle;
Serial.println("Connected");
Serial.print("Discovering Display Service ... ");
// Если дисплей не найден, отключаемся и возвращаемся
if ( !displays.discover(conn_handle) )
{
Serial.println("Found NONE");
// отключаемся, так как не можем найти службу отображения
Bluefruit.disconnect(conn_handle);
return;
}
// Как только сервис отображения найден, мы продолжаем обнаруживать его характеристики
Serial.println("Found it");
Serial.print("Discovering IMAGE characteristic ... ");
if ( !displayc.discover() )
{
// Измерение chr обязательно, если не найдено (валидно), то отключаем
Serial.println("not found !!!");
Serial.println("Measurement characteristic is mandatory but not found");
Bluefruit.disconnect(conn_handle);
return;
}
Serial.println("Found it");
}
/**
Callback invoked when a connection is dropped
@param conn_handle
@param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
*/
void disconnect_callback(uint16_t conn_handle, uint8_t reason)
{
(void) conn_handle;
(void) reason;
Serial.print("Disconnected, reason = 0x"); Serial.println(reason, HEX);
}
Ниже код для периферийного устройства (сервер):
#include <bluefruit.h>
#define suuid 0x8912
#define cuuid 0x9012
BLEService displays = BLEService(suuid);
BLECharacteristic displayc = BLECharacteristic(cuuid);
BLEDis bledis; // Экземпляр вспомогательного класса DIS (Device Information Service)
BLEBas blebas; // Экземпляр вспомогательного класса BAS (Battery Service)
uint8_t bps = 0;
void setup()
{
Serial.begin(115200);
while ( !Serial ) delay(10); // для nrf52840 с родным usb
Serial.println("Bluefruit52 Display Example");
Serial.println("-----------------------\n");
// Инициализируем модуль Bluefruit
Serial.println("Initialise the Bluefruit nRF52 module");
Bluefruit.begin();
// Установить обработчики обратного вызова подключения/отключения
Bluefruit.Periph.setConnectCallback(connect_callback);
Bluefruit.Periph.setDisconnectCallback(disconnect_callback);
// Настройте и запустите службу информации об устройстве
Serial.println("Configuring the Device Information Service");
bledis.setManufacturer("Adafruit Industries");
bledis.setModel("Bluefruit Feather52");
bledis.begin();
// Запускаем BLE Battery Service и устанавливаем его на 100%
Serial.println("Configuring the Battery Service");
blebas.begin();
blebas.write(100);
// Настройте службу монитора сердечного ритма, используя
// Классы BLEService и BLECharacteristic
Serial.println("Configuring the Heart Rate Monitor Service");
setupDisplay();
// Настраиваем рекламный пакет(ы)
Serial.println("Setting up the advertising payload(s)");
startAdv();
Serial.println("Ready Player One!!!");
Serial.println("\nAdvertising");
}
void startAdv(void)
{
// Рекламный пакет
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
Bluefruit.Advertising.addTxPower();
// Включить UUID службы отображения
Bluefruit.Advertising.addService(displays);
// Включить имя
Bluefruit.Advertising.addName();
/* Start Advertising
- Enable auto advertising if disconnected
- Interval: fast mode = 20 ms, slow mode = 152.5 ms
- Timeout for fast mode is 30 seconds
- Start(timeout) with timeout = 0 will advertise forever (until connected)
For recommended advertising interval
https://developer.apple.com/library/content/qa/qa1931/_index.html
*/
Bluefruit.Advertising.restartOnDisconnect(true);
Bluefruit.Advertising.setInterval(32, 244); // в единицах 0,625 мс
Bluefruit.Advertising.setFastTimeout(30); // количество секунд в быстром режиме
Bluefruit.Advertising.start(0); // 0 = Не останавливать рекламу через n секунд
}
void setupDisplay(void)
{
displays.begin();
displayc.setProperties(CHR_PROPS_WRITE);
displayc.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
displayc.setFixedLen(2);
displayc.setCccdWriteCallback(cccd_callback); // Опционально захватить обновления CCCD
displayc.begin();
}
void connect_callback(uint16_t conn_handle)
{
// Получить ссылку на текущее соединение
BLEConnection* connection = Bluefruit.Connection(conn_handle);
char central_name[32] = { 0 };
connection->getPeerName(central_name, sizeof(central_name));
Serial.print("Connected to ");
Serial.println(central_name);
}
/**
Callback invoked when a connection is dropped
@param conn_handle connection where this event happens
@param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
*/
void disconnect_callback(uint16_t conn_handle, uint8_t reason)
{
(void) conn_handle;
(void) reason;
Serial.print("Disconnected, reason = 0x"); Serial.println(reason, HEX);
Serial.println("Advertising!");
}
void cccd_callback(uint16_t conn_hdl, BLECharacteristic* chr, uint16_t cccd_value)
{
// Отображаем необработанный пакет запроса
Serial.print("CCCD Updated: ");
//Serial.printBuffer(запрос->данные, запрос->длина);
Serial.print(cccd_value);
Serial.println("");
// Проверяем характеристику, с которой связано это обновление CCCD на случай, если
// этот обработчик используется для нескольких записей CCCD.
if (chr->uuid == displayc.uuid) {
if (chr->notifyEnabled(conn_hdl)) {
Serial.println("Characteristic ID Matched");
} else {
Serial.println("Characteristic ID NON-Matched");
}
}
}
void loop()
{
digitalToggle(LED_RED);
if ( Bluefruit.connected() ) {
Serial.println(displayc.read8());
}
// Отправлять обновление только раз в секунду
// задержка (1000);
}
Я пытаюсь писать из центрального узла с помощью:
if (Bluefruit.connected())
{
uint8_t displaydata[5] = { 0x09, 0x10, 0x11, 0x12 };
displayc.write(displaydata,5);
}
И чтение на периферии с помощью :
if ( Bluefruit.connected() ) {
Serial.println(displayc.read8());
}
Но на последовательном мониторе отображается 187
.
Можем ли мы писать с центрального узла (клиента) на периферийный узел (сервер)? Есть ли способ создать функцию обратного вызова RX для узла сервера и узла клиента в пользовательских службах BLE?
Модуль Adafruit Bluefruit nRF52832: здесь Источник Git: здесь Центральный узел HRM Git Источник: здесь Пользовательский узел HRM Источник Git: здесь
0
Смотрите также:
- Как отправить ключи, отличные от ASCII, через соединение BLE HID с помощью Adafruit nRF52 Feather?
- nRF52832 BLE «conn_handle» для отключения текущих подключенных устройств
- Как callback функция вызова может отозвать себя. Например, функция подключения отменяется при наличии нового подключения
- Использование SoC nRF52 в качестве РЧ-радио
- Добавление пользовательской платы в среду разработки Arduino
- Причина предупреждения «avr:build doesn't define a 'build.board' preference», когда build.board явно задан в boards.txt?
- Библиотека ардуино или код для ESP32 для сканирования устройств Bluetooth?
- Отправка/получение данных от/на Raspberry Pi к/от Arduino с помощью HM-10 (модуль Bluetooth LE)