使用Arduino开发ESP32(十八):BLE_uart,BLE的异步通信及安卓app测试

基础介绍:

1、UART
universal asynchronous receiver and transmitter通用异步收发器

2、USART
universal synchronous asynchronous receiver and transmitter通用同步异步收发器

区别
1.“异步通信”是一种很常用的通信方式(效率较低)异步通信在发送字符时,发送端可以在任意时刻开始发送字符,因此必须在每一个字符的开始和结束的地方加上标志,即加上开始位和停止位,以便使接收端能够正确地将每一个字符接收下来。所传送的数据以字节为单位。每个字节前加上一位起始位,每个字节的后面加上停止位。好处:异步通信的好处是通信设备简单、便宜,但传输效率较低。
2.“同步通信”的通信双方必须先建立同步,即双方的时钟要调整到同一个频率。收发双方不停地发送和接收连续的同步比特流。一种是使用全网同步,用一个非常精确的主时钟对全网所有结点上的时钟进行同步。一种是使用准同步,各结点的时钟之间允许有微小的误差,然后采用其他措施实现同步传输。同步通信是把所传送的数据以多个字节(100字节以上)为单位,在其前后添加标志。

相关函数:

/**

  • @简介 Set the value of the characteristic.
  • @参数 data The data to set for the characteristic.
  • @参数 length The length of the data in bytes.
    */
void BLECharacteristic::setValue(uint8_t* data, size_t length) 

例程:

代码

/*
    Video: https://www.youtube.com/watch?v=oCMOYS71NIU
    Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
    Ported to Arduino ESP32 by Evandro Copercini

   Create a BLE server that, once we receive a connection, will send periodic notifications.
   创建一个BLE服务器,一旦我们收到连接,将会周期性发送通知
   
   The service advertises itself as: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
   Has a characteristic of: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E - used for receiving data with "WRITE" 
   Has a characteristic of: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E - used to send data with  "NOTIFY"

   T使用步骤:
   1. 创建一个 BLE Server
   2. 创建一个 BLE Service
   3. 创建一个 BLE Characteristic
   4. 创建一个 BLE Descriptor
   5. 开始服务
   6. 开始广播

   In this example rxValue is the data received (only accessible inside that function).
   And txValue is the data to be sent, in this example just a byte incremented every second. 
   在本例中,rxvalue是接收到的数据(仅在该函数内可访问)。
   txValue是要发送的数据,在这个例子中每秒递增一个字节
*/
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

BLEServer *pServer = NULL;                 //BLEServer指针 pServer
BLECharacteristic * pTxCharacteristic;    //BLECharacteristic指针 pTxCharacteristic
bool deviceConnected = false;        //本次连接状态
bool oldDeviceConnected = false;    //上次连接状态
uint8_t txValue = 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 {     //创建MyServerCallbacks类,其继承自BLEServerCallbacks
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};

class MyCallbacks: public BLECharacteristicCallbacks {   //创建MyCallbacks类,其继承自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]);

        Serial.println();
        Serial.println("*********");
      }
    }
};


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

  // 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());    //设置回调函数


  pService->start();                             // 开始服务


  pServer->getAdvertising()->start();                   // 开始广播
  
  Serial.println("等待一个客户端连接,且发送通知...");
}

void loop() {

    if (deviceConnected) {
        pTxCharacteristic->setValue(&txValue, 1);     //设置要发送的值为1
        pTxCharacteristic->notify();               //广播
        txValue++;                               //指针地址自加1
		delay(10); // bluetooth stack will go into congestion, if too many packets are sent   如果有太多包要发送,蓝牙会堵塞
	}

    // disconnecting  断连
    if (!deviceConnected && oldDeviceConnected) {
        delay(500); // 留时间给蓝牙缓冲
        pServer->startAdvertising(); // 重新广播
        Serial.println("开始广播");
        oldDeviceConnected = deviceConnected;
    }
    
    // connecting  正在连接
    if (deviceConnected && !oldDeviceConnected) {
		// do stuff here on connecting
        oldDeviceConnected = deviceConnected;
    }
}

结果
本次测试基于安卓平台的app:nRF connect,可在谷歌商店安装

找到我们的esp32设备并连接 (此处名叫UART Service)
在这里插入图片描述
连接之后,会自动跳转到该栏
在这我们可以看到各种信息
在TX Characteristic栏点击右侧箭头,可以看到value在不断变化(地址自加1)
在RX Characteristic栏点击右侧箭头,输入我们要发送的值,发送即可
在这里插入图片描述

上位机,串口收到了信息
在这里插入图片描述

后言:

到今天算是有了小突破
虽然例程仍有部分看不懂(c++还在学习中),但大致流程算是明白了
加油~

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值