双ESP32蓝牙通讯-Arduino

前言

        代码最终实现功能:蓝牙从机(服务器端)通过Notify向蓝牙主机(客户端)发送数据

一、蓝牙从机(服务器端)

// 首先是蓝牙设备(Device)作为服务器使用(Server);
// 一个服务器中运行了一个或多个服务(Service),每个服务由一个UUID来标识;
// 每个服务中含有一个或多个特征(Characteristic),每个特征由一个UUID来标识;
// 每个特征中包含一个值(Value),另外还包含零个或多个描述(Descriptor),每个描述由一个UUID来标识;
// 通过notify向主机也就是客户端发送数据,因为notify是非阻塞,不会确认客户端是否收到,但默认情况智慧发送value的前20字节数据

#include <BLEDevice.h>
#include <BLE2902.h>


#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" // 自定义UUID
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" // 自定义UUID

BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;
uint32_t value = 0;

// Server回调函数声明
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      Serial.println("设备接入~");
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
      Serial.println("设备断开~");
      // 在有设备接入后Advertising广播会被停止,所以要在设备断开连接时重新开启广播
      // 不然的话只有重启ESP32后才能重新搜索到
      pServer->startAdvertising(); //该行效果同 BLEDevice::startAdvertising();
    }
};

// 特征回调函数声明
class MyCharacteristicCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
        std::string value = pCharacteristic->getValue(); // 读取特征的新值
        Serial.print("特征值已更新,新值为: ");
        Serial.println(value.c_str());
    }
};

void setup() {
  Serial.begin(115200);
  Serial.println();

  BLEDevice::init("ESP32-BLE");
  BLEServer *pServer = BLEDevice::createServer(); // 创建服务器
  BLEService *pService = pServer->createService(SERVICE_UUID); // 创建服务
  // pCharacteristic = pService->createCharacteristic( // 创建特征
  //                                                 CHARACTERISTIC_UUID,
  //                                                 BLECharacteristic::PROPERTY_NOTIFY | // 启用通知
  //                                                 BLECharacteristic::PROPERTY_INDICATE // 启用通知
  //                                                 );
  pCharacteristic = pService->createCharacteristic(
                                                  CHARACTERISTIC_UUID,
       
ESP32-S3 是一款功能强大的 Wi-Fi 和蓝牙模微控制器,支持使用 Arduino 开发环境进行编程。在 ESP32-S3 上实现串口通信时,可以通过使用内置的 `HardwareSerial` 类来进行高效的串行数据传输。 ### 初始化串口通信 ESP32-S3 提供了多个硬件串口接口(Serial1、Serial2),允许同时与其他设备进行通信。基本的初始化方法如下: ```cpp void setup() { // 设置串口波特率,通常使用 115200 Serial.begin(115200); // 初始化 Serial1(可以选择 UART 号,例如 GPIO 会根据实际需求设置) Serial1.begin(9600, SERIAL_8N1, 4, 5); // 9600 波特率,8位数据位,无校验位,1停止位,RX 引脚为 4,TX 引脚为 5 } ``` ### 发送和接收数据 通过调用 `Serial.print()` 或 `Serial.write()` 函数可以发送数据,而通过 `Serial.available()` 和 `Serial.read()` 可以接收数据。 #### 示例代码:发送与接收数据 ```cpp void setup() { // 启动默认串口用于调试输出 Serial.begin(115200); // 初始化 Serial1 并指定 RX/TX 引脚 Serial1.begin(9600, SERIAL_8N1, 4, 5); // 使用自定义 RX=4, TX=5 } void loop() { // 检查是否有来自 Serial1 的数据 if (Serial1.available()) { char incomingByte = Serial1.read(); // 读取一个字节的数据 Serial.print("Received: "); Serial.println(incomingByte); } // 发送数据到 Serial1 Serial1.println("Hello from ESP32-S3!"); delay(1000); // 延迟 1 秒 } ``` ### 使用多串口通信 ESP32-S3 支持多个硬件串口,可以在同一时间处理不同外设的数据交互。例如,除了 Serial1 外,还可以使用 Serial2: ```cpp void setup() { Serial.begin(115200); Serial1.begin(9600, SERIAL_8N1, 4, 5); // Serial1 使用引脚 4(RX) 和 5(TX) Serial2.begin(19200, SERIAL_8N1, 16, 17); // Serial2 使用引脚 16(RX) 和 17(TX) } void loop() { if (Serial1.available()) { String data = Serial1.readStringUntil('\n'); // 读取直到换行符 Serial2.println(data); // 将数据转发到 Serial2 } } ``` ### 配置串口参数 ESP32-S3 允许配置串口的格式,包括数据位、校验位和停止位。以下是示例: ```cpp // 配置为 8 数据位,偶校验,1 停止位 Serial1.begin(9600, SERIAL_8E1, 4, 5); ``` 其中: - `SERIAL_8N1` 表示 8 位数据,无校验,1 位停止。 - `SERIAL_8E1` 表示 8 位数据,偶校验,1 位停止。 - `SERIAL_8O1` 表示 8 位数据,奇校验,1 位停止。 ### 中断方式处理串口数据 为了提高效率,可以使用中断来实时处理串口接收到的数据。以下是一个基于中断的简单示例: ```cpp volatile int receivedData = 0; void IRAM_ATTR onReceive(int dataSize) { while (Serial1.available()) { receivedData = Serial1.read(); Serial.print("Interrupt received: "); Serial.println(receivedData); } } void setup() { Serial.begin(115200); Serial1.begin(9600, SERIAL_8N1, 4, 5); // 注册串口接收中断回调函数 attachInterrupt(digitalPinToInterrupt(4), onReceive, RISING); } ``` ### 注意事项 - **GPIO 引脚选择**:确保选择的 RX 和 TX 引脚不与其他功能冲突,并参考 ESP32-S3 的引脚映射文档确认可用性。 - **波特率匹配**:确保连接设备之间的波特率一致,否则可能导致通信失败。 - **缓冲区大小**:ESP32 的串口缓冲区有限,大量数据传输时建议适当增加缓冲区大小或使用流控制。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mao十七

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值