ESP32 arduino 6个BLE例程

44 ESP32之低功耗蓝牙(BLE)服务端编程 - 基于Arduino

例1 服务器最简编程

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

#define SERVICE_UUID        "b0afd88d-5807-4533-b27b-a48cc3a32e30"   //服务UUID
#define CHARACTERISTIC_UUID "7057310c-1e37-4a0a-9ae1-6ed8ccb995b1"   //特征UUID

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  delay(500);
  BLEDevice::init("Fish Fish");                    //初始化蓝牙设备
  auto local_address = BLEDevice::getAddress();    //获取本机地址
  Serial.println(local_address.toString().c_str());
  BLEServer *pServer = BLEDevice::createServer();  //创建一个服务器

  BLEService *pService = pServer->createService(SERVICE_UUID);   //创建一个服务
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(    //在服务里创建一个特征
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE                                         
                                       );
  pCharacteristic->setValue("Hello World.");        //给特征赋值


  pService->start();    //Service开始提供服务
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();      //获取广播器
  pAdvertising->addServiceUUID(SERVICE_UUID);                      //将Service加入广播
  pAdvertising->setScanResponse(true);                             //允许扫描回复
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();                                   //开始广播

  Serial.println("Characteristic defined! Now you can read it in your phone!");

}

void loop() {
}

例2 添加自动再次广播

同时只能处理一个或多个客户端

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

#define SERVICE_UUID        "b0afd88d-5807-4533-b27b-a48cc3a32e30"   //服务UUID
#define CHARACTERISTIC_UUID "7057310c-1e37-4a0a-9ae1-6ed8ccb995b1"   //特征UUID

bool isAdvertising = true;  //是否在广播
int clientCount = 0;    //目前已有客户端数量

//服务器连接与断开连接回调类
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      Serial.println("client connected...");
      clientCount++;
      isAdvertising = false;  //因为只要有客户端连上来,就会关闭广播
    };

    void onDisconnect(BLEServer* pServer) {
      Serial.println("client disconnected...");
      clientCount--;
    }
};

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  delay(500);
  BLEDevice::init("Fish Fish");                    //初始化蓝牙设备
  auto local_address = BLEDevice::getAddress();    //获取本机地址
  Serial.println(local_address.toString().c_str());
  BLEServer *pServer = BLEDevice::createServer();  //创建一个服务器
  pServer->setCallbacks(new MyServerCallbacks());

  BLEService *pService = pServer->createService(SERVICE_UUID);   //创建一个服务
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(    //在服务里创建一个特征
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE                                         
                                       );
  pCharacteristic->setValue("Hello World.");        //给特征赋值


  pService->start();    //Service开始提供服务
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();      //获取广播器
  pAdvertising->addServiceUUID(SERVICE_UUID);                      //将Service加入广播
  pAdvertising->setScanResponse(true);                             //允许扫描回复
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();                                   //开始广播

  Serial.println("Characteristic defined! Now you can read it in your phone!");

}

void loop() {
  if(BLEDevice::getInitialized() && !isAdvertising && clientCount<1)
  {
    delay(500);  //让蓝牙设备留一段处理的时间
    BLEDevice::startAdvertising();  //重新开始广播
    isAdvertising = true;
    Serial.println("start advertising");
  }

  delay(50);
}

例3 添加配对认证(静态密码)

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

#define SERVICE_UUID        "b0afd88d-5807-4533-b27b-a48cc3a32e30"   //服务UUID
#define CHARACTERISTIC_UUID "7057310c-1e37-4a0a-9ae1-6ed8ccb995b1"   //特征UUID

bool isAdvertising = true;  //是否在广播
int clientCount = 0;    //目前已有客户端数量

class MySecurity : public BLESecurityCallbacks {
  uint32_t onPassKeyRequest(){
    Serial.println("PassKeyRequest!");
    return 334455;
  }

  //显示本机要求的静态码
  void onPassKeyNotify(uint32_t pass_key){
    Serial.printf("On passkey Notify number:%d", pass_key);
  }

  bool onSecurityRequest(){
    Serial.println("On Security Request!");
    return true;
  }

  //认证结果
  void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl){
    if(cmpl.success){
      Serial.println("onAuthenticationComplete!");
    } else {
      Serial.println("onAuthentication not Complete!");
    }
  }

  //显示动态码并确定是否同意配对
  bool onConfirmPIN(uint32_t pin){
    Serial.printf("onConfirmPIN %d !", pin);
    //return false;
    return true;  //返回true同意配对,返回false拒绝配对
  }
};

//服务器连接与断开连接回调类
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      Serial.println("client connected...");
      clientCount++;
      isAdvertising = false;  //因为只要有客户端连上来,就会关闭广播
    };

    void onDisconnect(BLEServer* pServer) {
      Serial.println("client disconnected...");
      clientCount--;
    }
};

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  delay(500);
  BLEDevice::init("Fish Fish");                    //初始化蓝牙设备
  BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT_MITM);
  BLEDevice::setSecurityCallbacks(new MySecurity());

  BLESecurity *pSecurity = new BLESecurity();
  pSecurity->setStaticPIN(112233);  //这个是设置静态密码
  
  auto local_address = BLEDevice::getAddress();    //获取本机地址
  Serial.println(local_address.toString().c_str());
  BLEServer *pServer = BLEDevice::createServer();  //创建一个服务器
  pServer->setCallbacks(new MyServerCallbacks());

  BLEService *pService = pServer->createService(SERVICE_UUID);   //创建一个服务
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(    //在服务里创建一个特征
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE                                         
                                       );
  pCharacteristic->setValue("Hello World.");        //给特征赋值


  pService->start();    //Service开始提供服务
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();      //获取广播器
  pAdvertising->addServiceUUID(SERVICE_UUID);                      //将Service加入广播
  pAdvertising->setScanResponse(true);                             //允许扫描回复
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();                                   //开始广播

  Serial.println("Characteristic defined! Now you can read it in your phone!");

}

void loop() {
  if(BLEDevice::getInitialized() && !isAdvertising && clientCount<1)
  {
    delay(500);  //让蓝牙设备留一段处理的时间
    BLEDevice::startAdvertising();  //重新开始广播
    isAdvertising = true;
    Serial.println("start advertising");
  }

  delay(50);
}

例4 添加配对认证(交互认证)

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

#define SERVICE_UUID        "b0afd88d-5807-4533-b27b-a48cc3a32e30"   //服务UUID
#define CHARACTERISTIC_UUID "7057310c-1e37-4a0a-9ae1-6ed8ccb995b1"   //特征UUID

bool isAdvertising = true;  //是否在广播
int clientCount = 0;    //目前已有客户端数量

class MySecurity : public BLESecurityCallbacks {
  uint32_t onPassKeyRequest(){
    Serial.println("PassKeyRequest!");
    return 334455;
  }

  //显示本机要求的静态码
  void onPassKeyNotify(uint32_t pass_key){
    Serial.printf("On passkey Notify number:%d", pass_key);
  }

  bool onSecurityRequest(){
    Serial.println("On Security Request!");
    return true;
  }

  //认证结果
  void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl){
    if(cmpl.success){
      Serial.println("onAuthenticationComplete!");
    } else {
      Serial.println("onAuthentication not Complete!");
    }
  }

  //显示动态码并确定是否同意配对
  bool onConfirmPIN(uint32_t pin){
    Serial.printf("onConfirmPIN %d !", pin);
    //return false;
    return true;  //返回true同意配对,返回false拒绝配对
  }
};

//服务器连接与断开连接回调类
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      Serial.println("client connected...");
      clientCount++;
      isAdvertising = false;  //因为只要有客户端连上来,就会关闭广播
    };

    void onDisconnect(BLEServer* pServer) {
      Serial.println("client disconnected...");
      clientCount--;
    }
};

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  delay(500);
  BLEDevice::init("Fish Fish");                    //初始化蓝牙设备
  BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT_MITM);
  BLEDevice::setSecurityCallbacks(new MySecurity());

  BLESecurity *pSecurity = new BLESecurity();
  pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_MITM_BOND);
  pSecurity->setCapability(ESP_IO_CAP_IO);  //显示yes,no
  //pSecurity->setCapability(ESP_IO_CAP_NONE);  //没有IO设备
  pSecurity->setInitEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);
  
  auto local_address = BLEDevice::getAddress();    //获取本机地址
  Serial.println(local_address.toString().c_str());
  BLEServer *pServer = BLEDevice::createServer();  //创建一个服务器
  pServer->setCallbacks(new MyServerCallbacks());

  BLEService *pService = pServer->createService(SERVICE_UUID);   //创建一个服务
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(    //在服务里创建一个特征
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE                                         
                                       );
  pCharacteristic->setValue("Hello World.");        //给特征赋值


  pService->start();    //Service开始提供服务
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();      //获取广播器
  pAdvertising->addServiceUUID(SERVICE_UUID);                      //将Service加入广播
  pAdvertising->setScanResponse(true);                             //允许扫描回复
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();                                   //开始广播

  Serial.println("Characteristic defined! Now you can read it in your phone!");

}

void loop() {
  if(BLEDevice::getInitialized() && !isAdvertising && clientCount<1)
  {
    delay(500);  //让蓝牙设备留一段处理的时间
    BLEDevice::startAdvertising();  //重新开始广播
    isAdvertising = true;
    Serial.println("start advertising");
  }

  delay(50);
}

例5 多特征,加密及notify

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <AsyncTimer.h>
#include <BLE2902.h>
#include <BLEUUID.h>

#define SERVICE_UUID        "b0afd88d-5807-4533-b27b-a48cc3a32e30"   //服务UUID
#define CHARACTERISTIC_UUID "7057310c-1e37-4a0a-9ae1-6ed8ccb995b1"   //特征UUID
#define COUNT_CHARACTERISTIC_UUID "37582929-48c3-4dd0-8e4f-0b29c5640489" //计数器特征

uint32_t value = 0;
BLECharacteristic *countCharacteristic = NULL;
AsyncTimer t;

bool isAdvertising = true;  //是否在广播
int clientCount = 0;    //目前已有客户端数量

class MySecurity : public BLESecurityCallbacks {
  uint32_t onPassKeyRequest(){
    Serial.println("PassKeyRequest!");
    return 334455;
  }

  //显示本机要求的静态码
  void onPassKeyNotify(uint32_t pass_key){
    Serial.printf("On passkey Notify number:%d", pass_key);
  }

  bool onSecurityRequest(){
    Serial.println("On Security Request!");
    return true;
  }

  //认证结果
  void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl){
    if(cmpl.success){
      Serial.println("onAuthenticationComplete!");
    } else {
      Serial.println("onAuthentication not Complete!");
    }
  }

  //显示动态码并确定是否同意配对
  bool onConfirmPIN(uint32_t pin){
    Serial.printf("onConfirmPIN %d !", pin);
    //return false;
    return true;  //返回true同意配对,返回false拒绝配对
  }
};

//服务器连接与断开连接回调类
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      Serial.println("client connected...");
      clientCount++;
      isAdvertising = false;  //因为只要有客户端连上来,就会关闭广播
    };

    void onDisconnect(BLEServer* pServer) {
      Serial.println("client disconnected...");
      clientCount--;
    }
};

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  delay(500);
  BLEDevice::init("Fish Fish");                    //初始化蓝牙设备
  BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT_MITM);
  BLEDevice::setSecurityCallbacks(new MySecurity());

  BLESecurity *pSecurity = new BLESecurity();
  pSecurity->setStaticPIN(112233);  //这个是设置静态密码
  
  auto local_address = BLEDevice::getAddress();    //获取本机地址
  Serial.println(local_address.toString().c_str());
  BLEServer *pServer = BLEDevice::createServer();  //创建一个服务器
  pServer->setCallbacks(new MyServerCallbacks());

  BLEService *pService = pServer->createService(SERVICE_UUID);   //创建一个服务
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(    //在服务里创建一个特征
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE                                         
                                       );
  pCharacteristic->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED);
  pCharacteristic->setValue("Hello World.");        //给特征赋值

  countCharacteristic = pService->createCharacteristic(
                                         COUNT_CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_NOTIFY |
                                         BLECharacteristic::PROPERTY_INDICATE
                                       );
  countCharacteristic->setValue(value);
  countCharacteristic->addDescriptor(new BLE2902());  //要启用notify和indicate的都要添加这个描述符

  BLEDescriptor *pCountName = new BLEDescriptor(BLEUUID((uint16_t)0x2901));
  pCountName->setValue("My Counter");
  countCharacteristic->addDescriptor(pCountName);

  pService->start();    //Service开始提供服务
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();      //获取广播器
  pAdvertising->addServiceUUID(SERVICE_UUID);                      //将Service加入广播
  pAdvertising->setScanResponse(true);                             //允许扫描回复
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();                                   //开始广播

  Serial.println("Characteristic defined! Now you can read it in your phone!");

  //每3秒计数器加1,并发通知
  t.setInterval([]{
    Serial.println("plus...");
    value++;
    if(countCharacteristic && clientCount>0)
    {
      countCharacteristic->setValue(value);
      countCharacteristic->notify();  //发通知
      //countCharacteristic->indicate();
      Serial.println("notify");
    }
  }, 3000);

  //处理自动广播问题
  t.setInterval([]{
    if(BLEDevice::getInitialized() && !isAdvertising && clientCount<1)
    {
      delay(500);  //让蓝牙设备留一段处理的时间
      BLEDevice::startAdvertising();  //重新开始广播
      isAdvertising = true;
      Serial.println("start advertising");
    }
  }, 50);
}

void loop() {
  t.handle();
}

例6 特征读写回调

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <AsyncTimer.h>
#include <BLE2902.h>
#include <BLEUUID.h>

#define SERVICE_UUID        "b0afd88d-5807-4533-b27b-a48cc3a32e30"   //服务UUID
#define CHARACTERISTIC_UUID "7057310c-1e37-4a0a-9ae1-6ed8ccb995b1"   //特征UUID
#define COUNT_CHARACTERISTIC_UUID "37582929-48c3-4dd0-8e4f-0b29c5640489" //计数器特征

uint32_t value = 0;
BLECharacteristic *countCharacteristic = NULL;
AsyncTimer t;

bool isAdvertising = true;  //是否在广播
int clientCount = 0;    //目前已有客户端数量

class MyCharacteristicCallbacks: public BLECharacteristicCallbacks{

	virtual void onRead(BLECharacteristic* pCharacteristic, esp_ble_gatts_cb_param_t* param)
  {
    auto p = param->read;
    auto conn_id = p.conn_id;
    BLEAddress address(p.bda);
    Serial.printf("Read.. %d, %s\r\n", conn_id, address.toString().c_str());
  }

	virtual void onWrite(BLECharacteristic* pCharacteristic, esp_ble_gatts_cb_param_t* param)
  {
    auto p = param->read;
    auto conn_id = p.conn_id;
    BLEAddress address(p.bda);
    Serial.printf("Write.. %d, %s\r\n", conn_id, address.toString().c_str());
  }

	virtual void onNotify(BLECharacteristic* pCharacteristic)
  {
    Serial.println("notify...");
  }
};

class MySecurity : public BLESecurityCallbacks {
  uint32_t onPassKeyRequest(){
    Serial.println("PassKeyRequest!");
    return 334455;
  }

  //显示本机要求的静态码
  void onPassKeyNotify(uint32_t pass_key){
    Serial.printf("On passkey Notify number:%d", pass_key);
  }

  bool onSecurityRequest(){
    Serial.println("On Security Request!");
    return true;
  }

  //认证结果
  void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl){
    if(cmpl.success){
      Serial.println("onAuthenticationComplete!");
    } else {
      Serial.println("onAuthentication not Complete!");
    }
  }

  //显示动态码并确定是否同意配对
  bool onConfirmPIN(uint32_t pin){
    Serial.printf("onConfirmPIN %d !", pin);
    //return false;
    return true;  //返回true同意配对,返回false拒绝配对
  }
};

//服务器连接与断开连接回调类
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      Serial.println("client connected...");
      clientCount++;
      isAdvertising = false;  //因为只要有客户端连上来,就会关闭广播
    };

    void onDisconnect(BLEServer* pServer) {
      Serial.println("client disconnected...");
      clientCount--;
    }
};

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  delay(500);
  BLEDevice::init("Fish Fish");                    //初始化蓝牙设备
  BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT_MITM);
  BLEDevice::setSecurityCallbacks(new MySecurity());

  BLESecurity *pSecurity = new BLESecurity();
  pSecurity->setStaticPIN(112233);  //这个是设置静态密码
  
  auto local_address = BLEDevice::getAddress();    //获取本机地址
  Serial.println(local_address.toString().c_str());
  BLEServer *pServer = BLEDevice::createServer();  //创建一个服务器
  pServer->setCallbacks(new MyServerCallbacks());

  BLEService *pService = pServer->createService(SERVICE_UUID);   //创建一个服务
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(    //在服务里创建一个特征
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE                                         
                                       );
  pCharacteristic->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED);
  pCharacteristic->setValue("Hello World.");        //给特征赋值
  pCharacteristic->setCallbacks(new MyCharacteristicCallbacks());

  countCharacteristic = pService->createCharacteristic(
                                         COUNT_CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_NOTIFY |
                                         BLECharacteristic::PROPERTY_INDICATE
                                       );
  countCharacteristic->setValue(value);
  countCharacteristic->addDescriptor(new BLE2902());  //要启用notify和indicate的都要添加这个描述符

  BLEDescriptor *pCountName = new BLEDescriptor(BLEUUID((uint16_t)0x2901));
  pCountName->setValue("My Counter");
  countCharacteristic->addDescriptor(pCountName);
  countCharacteristic->setCallbacks(new MyCharacteristicCallbacks());

  pService->start();    //Service开始提供服务
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();      //获取广播器
  pAdvertising->addServiceUUID(SERVICE_UUID);                      //将Service加入广播
  pAdvertising->setScanResponse(true);                             //允许扫描回复
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();                                   //开始广播

  Serial.println("Characteristic defined! Now you can read it in your phone!");

  //每3秒计数器加1,并发通知
  t.setInterval([]{
    value++;
    if(countCharacteristic && clientCount>0)
    {
      countCharacteristic->setValue(value);
      countCharacteristic->notify();  //发通知
      //countCharacteristic->indicate();
    }
  }, 3000);

  //处理自动广播问题
  t.setInterval([]{
    if(BLEDevice::getInitialized() && !isAdvertising && clientCount<1)
    {
      delay(500);  //让蓝牙设备留一段处理的时间
      BLEDevice::startAdvertising();  //重新开始广播
      isAdvertising = true;
      Serial.println("start advertising");
    }
  }, 50);
}

void loop() {
  t.handle();
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值