uPesy ESP32C3 Mini Arduino 开启蓝牙服务 测试服务可用

一 可运行代码

#include <BLEDevice.h>

#include <BLEUtils.h>

#include <BLEServer.h>

#include <BLE2902.h>

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"

#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

BLEServer *pServer = NULL;

BLECharacteristic *pCharacteristic = NULL;

bool deviceConnected = false;

bool oldDeviceConnected = false;

unsigned long lastAdvertisingRestart = 0;

class MyServerCallbacks: public BLEServerCallbacks {

    void onConnect(BLEServer* pServer) {

      deviceConnected = true;

      Serial.println("Device connected");

    };

    void onDisconnect(BLEServer* pServer) {

      deviceConnected = false;

      Serial.println("Device disconnected");

    }

};

class MyCallbacks: public BLECharacteristicCallbacks {

    void onWrite(BLECharacteristic *pCharacteristic) {

      String arduinoString = pCharacteristic->getValue();

      if (arduinoString.length() > 0) {

        Serial.println("Received Value: ");

        Serial.println(arduinoString);

        // Create simple response

        String response = "{\"status\":\"OK\",\"message\":\"Data received: " + arduinoString + "\"}";

        // Set the characteristic's value to the response string

        pCharacteristic->setValue(response.c_str());

        pCharacteristic->notify();

        Serial.println("Response sent");

      }

    }

    void onRead(BLECharacteristic *pCharacteristic) {

      Serial.println("Characteristic read");

    }

    void onNotify(BLECharacteristic *pCharacteristic) {

      Serial.println("Characteristic notified");

    }

};

void setup() {

  Serial.begin(115200);

  while (!Serial) {

    ; // wait for serial port to connect. Needed for native USB port only

  }

  Serial.println("Serial communication started");

  // Create the BLE Device

  BLEDevice::init("ESP32-C3");

  if (!BLEDevice::getInitialized()) {

    Serial.println("Failed to initialize BLE Device!");

    while (1) {

#include <BLEDevice.h> #include <BLEServer.h> #include <BLEUtils.h> #include <BLE2902.h> #include <Arduino.h> BLEServer *pServer = NULL; BLECharacteristic *pTxCharacteristic; bool deviceConnected = false; bool oldDeviceConnected = false; bool deviceswitch = false; uint8_t txValue = 0; uint8_t runtime = 0; // See the following for generating UUIDs: // https://www.uuidgenerator.net/ #define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID #define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" #define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" class MyServerCallbacks : public BLEServerCallbacks { void onConnect(BLEServer *pServer) { deviceConnected = true; }; void onDisconnect(BLEServer *pServer) { deviceConnected = false; } }; class MyCallbacks : public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { std::string rxValue = pCharacteristic->getValue(); if (rxValue.length() > 0) { Serial.println("*********"); Serial.print("Received Value: "); for (int i = 0; i < rxValue.length(); i++) Serial.print(rxValue[i]); if (rxValue[0] == &#39;a&#39;) { digitalWrite(2, HIGH); // open switch deviceswitch = true; runtime = millis() / 1000; } if (rxValue[0] == &#39;b&#39;) { digitalWrite(2, LOW); // open switch deviceswitch = false; } Serial.println(); Serial.println("*********"); } } }; void setup() { Serial.begin(9600); pinMode(2, OUTPUT); // 设置输出2脚 digitalWrite(2, LOW); // 默认低电平 // Create the BLE Device BLEDevice::init("UART Service"); // Create the BLE Server pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); // Create the BLE Service BLEService *pService = pServer->createService(SERVICE_UUID); // Create a BLE Characteristic pTxCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY); pTxCharacteristic->addDescriptor(new BLE2902()); BLECharacteristic *pRxCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE); pRxCharacteristic->setCallbacks(new MyCallbacks()); // Start the service pService->start(); // Start advertising pServer->getAdvertising()->start(); Serial.println("Waiting a client connection to notify..."); } void loop() { if (deviceConnected) { pTxCharacteristic->setValue(&txValue, 1); pTxCharacteristic->notify(); txValue++; delay(10); // bluetooth stack will go into congestion, if too many packets are sent } // disconnecting if (!deviceConnected && oldDeviceConnected) { delay(500); // give the bluetooth stack the chance to get things ready pServer->startAdvertising(); // restart advertising Serial.println("start advertising"); oldDeviceConnected = deviceConnected; } // connecting if (deviceConnected && !oldDeviceConnected) { // do stuff here on connecting oldDeviceConnected = deviceConnected; } if (deviceswitch == true) { Serial.println("start advertising"); } } 帮我解释一下这段代码
03-15
<think>嗯,用户给了一段Arduino的代码,是关于BLE的,需要帮忙解释。首先,我得仔细看一下代码的结构和各个部分的功能。用户可能是个刚开始接触物联网或者蓝牙开发的开发者,想了解这段代码是如何工作的。 首先,注意到代码里用了BLEDevice、BLEServer、BLEUtils等库,这些都是ESP32的BLE库。代码的大致结构是setup和loop函数,里面初始化了BLE服务,设置了特征值,还有处理连接和数据的回调类。 用户可能想知道每个部分的作用,比如服务UUID、特征值的设置,以及数据如何接收和发送。另外,代码里还有控制GPIO的部分,可能涉及到通过蓝牙指令控制硬件开关。需要解释MyServerCallbacks和MyCallbacks这两个回调类的作用,特别是当设备连接或断开时,以及收到数据时的处理逻辑。 然后,loop函数里的逻辑,比如设备连接时的通知发送,断开后的重新广播,这些也是关键点。还有,用户可能对变量如deviceConnected、oldDeviceConnected的作用有疑问,需要说明它们在连接状态管理中的用途。 另外,代码中的deviceswitch和runtime变量,可能用于跟踪开关状态和运行时间,这部分在接收到特定字符(&#39;a&#39;或&#39;b&#39;)时触发,需要解释清楚。 用户可能还想知道这段代码的实际应用场景,比如通过手机APP发送指令控制GPIO引脚,实现远程开关的功能。同时,代码里的一些细节,比如UUID的生成、BLE2902描述符的作用,是否需要进一步说明? 最后,要确保解释清晰,分步骤说明各个部分,帮助用户理解整个BLE通信流程,从初始化到数据处理,再到连接管理。可能还需要指出潜在的问题,比如延迟设置、数据发送频率,以及GPIO控制的安全考虑。</think>这段代码是基于ESP32的BLE(蓝牙低功耗)通信示例,主要用于实现通过蓝牙接收指令控制GPIO引脚的功能。以下是代码的分步解析: --- ### **1. 头文件引入** ```cpp #include <BLEDevice.h> // BLE核心库 #include <BLEServer.h> // BLE服务器功能 #include <BLEUtils.h> // BLE工具函数 #include <BLE2902.h> // 描述符定义 #include <Arduino.h> // Arduino核心库 ``` - 引入ESP32的BLE相关库和Arduino基础库。 --- ### **2. 全局变量定义** ```cpp BLEServer *pServer = NULL; BLECharacteristic *pTxCharacteristic; // 发送特征 bool deviceConnected = false; // 当前连接状态 bool oldDeviceConnected = false; // 上一次连接状态 bool deviceswitch = false; // 自定义开关状态 uint8_t txValue = 0; // 发送计数器 uint8_t runtime = 0; // 运行时间记录 ``` - 定义BLE服务器、特征值和状态变量。 --- ### **3. UUID定义** ```cpp #define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // 服务UUID #define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" // 接收特征 #define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" // 发送特征 ``` - 使用标准Nordic UART Service (NUS) UUID,兼容多数蓝牙串口应用。 --- ### **4. 回调类实现** #### **4.1 服务器连接回调** ```cpp class MyServerCallbacks : public BLEServerCallbacks { void onConnect(BLEServer *pServer) { deviceConnected = true; } void onDisconnect(BLEServer *pServer) { deviceConnected = false; } }; ``` - 设备连接/断开时更新`deviceConnected`状态。 #### **4.2 特征值写入回调** ```cpp class MyCallbacks : public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { std::string rxValue = pCharacteristic->getValue(); if (rxValue[0] == &#39;a&#39;) { // 收到&#39;a&#39;指令 digitalWrite(2, HIGH); // 开启GPIO2 deviceswitch = true; runtime = millis() / 1000; // 记录时间 } if (rxValue[0] == &#39;b&#39;) { // 收到&#39;b&#39;指令 digitalWrite(2, LOW); // 关闭GPIO2 deviceswitch = false; } } }; ``` - 解析接收到的数据,通过字符指令控制GPIO2电平。 --- ### **5. Setup函数** ```cpp void setup() { Serial.begin(9600); pinMode(2, OUTPUT); // 初始化GPIO2为输出 digitalWrite(2, LOW); // 初始低电平 BLEDevice::init("UART Service"); // 初始化BLE设备 pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); BLEService *pService = pServer->createService(SERVICE_UUID); // 创建服务 // 配置发送特征(带通知功能) pTxCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY ); pTxCharacteristic->addDescriptor(new BLE2902()); // 添加描述符 // 配置接收特征(带写入功能) BLECharacteristic *pRxCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE ); pRxCharacteristic->setCallbacks(new MyCallbacks()); pService->start(); // 启动服务 pServer->getAdvertising()->start(); // 开始广播 Serial.println("Waiting for connection..."); } ``` --- ### **6. Loop函数** ```cpp void loop() { // 发送数据(每10ms发送递增的txValue) if (deviceConnected) { pTxCharacteristic->setValue(&txValue, 1); pTxCharacteristic->notify(); txValue++; delay(10); // 避免蓝牙栈拥堵 } // 处理连接状态变化 if (!deviceConnected && oldDeviceConnected) { delay(500); pServer->startAdvertising(); // 断开后重新广播 oldDeviceConnected = deviceConnected; } if (deviceConnected && !oldDeviceConnected) { oldDeviceConnected = deviceConnected; } } ``` --- ### **主要功能总结** 1. **蓝牙通信**:实现基于NUS协议的蓝牙串口通信。 2. **GPIO控制**: - 收到字符`a` → GPIO2输出高电平(开) - 收到字符`b` → GPIO2输出低电平(关) 3. **状态通知**:持续发送递增的`txValue`到客户端。 4. **自动重连**:设备断开后自动重新广播。 --- ### **典型应用场景** - 通过手机APP(如`nRF Connect`)发送指令控制LED/继电器 - 物联网设备的状态监控与控制 - 需要低功耗蓝牙通信的嵌入式项目 建议搭配蓝牙调试工具实际测试数据收发效果,并注意GPIO2在ESP32开发板上的具体位置(可能连接板载LED)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值