599 views|2 replies

270

Posts

4

Resources
The OP
 

[Beetle ESP32 C6 Mini Development Board] Dual machine communication and Bluetooth switch [Copy link]

 

In the previous article [Beetle ESP32 C6 Mini Development Board], the UART Service has been implemented in the initial use of the low-power Bluetooth (BLE) function. On this basis, using two Beetle ESP32 C6 mini development boards, dual-machine communication based on UART can be achieved, and on this basis, the Bluetooth switch function can be realized.

1. Dual-machine communication

In principle, two-machine communication requires one server and one client.

For the Server part, you can directly use the one in the previous article. Or refer to the DFRobot Beetle ESP32 C6 mini development board WiKi article: https://wiki.dfrobot.com.cn/_SKU_DFR1075_FireBeetle_2_Board_ESP32_C6_Advanced_Tutorial#target_2

The Client part automatically scans the surrounding BLE devices, and then checks whether there is a Service device that meets the requirements. If so, it connects and then performs subsequent processing.

The server code is as follows:

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

// 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"

uint8_t txValue = 0;
bool deviceConnected = false;
BLECharacteristic *pTxCharacteristic;


//蓝牙连接/断开处理。当有连接/断开事件发生时自动触发
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {   //当蓝牙连接时会执行该函数
      Serial.println("蓝牙已连接");
      deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {  //当蓝牙断开连接时会执行该函数
        Serial.println("蓝牙已断开");
        deviceConnected = false;
        delay(500); // give the bluetooth stack the chance to get things ready
        BLEDevice::startAdvertising(); // restart advertising
    }
};
/****************数据接收部分*************/
/****************************************/
//蓝牙接收数据处理。当收到数据时自动触发
class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();  //使用rxValue接收数据

      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);
  Serial.println("Starting BLE work!");
  bleBegin();
}

/****************数据发送部分*************/
/****************************************/
void loop() {
  if(deviceConnected){  //当有设备连接时发送数据
    pTxCharacteristic->setValue("我是从机");
    pTxCharacteristic->notify();

  }
  /****************************************/
  /****************************************/
  delay(1000);
}


void bleBegin()
{
  BLEDevice::init(/*BLE名称*/"ESP32-C6 BLE Server");
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pRxCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID_RX,
                                         BLECharacteristic::PROPERTY_WRITE 
                                       );
  pRxCharacteristic->setCallbacks(new MyCallbacks()); 

 pTxCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID_TX,
                                         BLECharacteristic::PROPERTY_NOTIFY
                                       );
 pTxCharacteristic->addDescriptor(new BLE2902());

  pService->start();
  // BLEAdvertising *pAdvertising = pServer->getAdvertising();  // this still is working for backward compatibility
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();

  }

The client code is as follows:

#include "BLEDevice.h"


#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"

static BLEUUID serviceUUID(SERVICE_UUID);
static BLEUUID    charTXUUID(CHARACTERISTIC_UUID_RX);
static BLEUUID    charRXUUID(CHARACTERISTIC_UUID_TX);


static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic* pTXRemoteCharacteristic;
static BLERemoteCharacteristic* pRXRemoteCharacteristic;
static BLEAdvertisedDevice* myDevice;


/****************数据接收部分*************/
/****************************************/
//蓝牙接收数据处理,当收到数据时自动触发
static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) {  //传入uint8_t* pData用于存放数据
    String BLEData = "";
    for(int i = 0; i < length; i++)  //
      BLEData += (char)pData[i];
    Serial.println("*********");
    Serial.print("Received Value: ");
    Serial.println(BLEData);
    Serial.println("*********");
}
/****************************************/
/****************************************/

//蓝牙连接/断开处理。当有连接/断开事件发生时自动触发
class MyClientCallback : public BLEClientCallbacks {
  void onConnect(BLEClient* pclient) {
  }

  void onDisconnect(BLEClient* pclient) {
    connected = false;
    Serial.println("onDisconnect");
  }
};


/**
 * Scan for BLE servers and find the first one that advertises the service we are looking for.
 */
 //蓝牙扫描处理事件。当开启扫描时自动触发
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
 /**
   * Called for each advertising BLE server.
   */
  void onResult(BLEAdvertisedDevice advertisedDevice) {
    //Serial.print("BLE Advertised Device found: ");
    //Serial.println(advertisedDevice.toString().c_str());

    // We have found a device, let us now see if it contains the service we are looking for.
    if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {
      BLEDevice::getScan()->stop();
      myDevice = new BLEAdvertisedDevice(advertisedDevice);
      doConnect = true;
      doScan = true;

    } // Found our server
  } // onResult
}; // MyAdvertisedDeviceCallbacks



void setup() {
  Serial.begin(115200);
  Serial.println("Starting Arduino BLE Client application...");
  bleBegin();

}

void loop() {
  // If the flag "doConnect" is true then we have scanned for and found the desired
  // BLE Server with which we wish to connect.  Now we connect to it.  Once we are 
  // connected we set the connected flag to be true.
  if (doConnect == true) {
    if (connectToServer()) {
      Serial.println("We are now connected to the BLE Server.");
    } else {
      Serial.println("We have failed to connect to the server; there is nothin more we will do.");
    }
    doConnect = false;
  }
/****************数据发送部分*************/
/****************************************/
  if (connected) {  //当连接到蓝牙从机时发送数据
    pTXRemoteCharacteristic->writeValue("我是主机");
  }
  if(!connected){  //当没有连接到蓝牙从机时重新扫描
    BLEDevice::getScan()->start(5,false);  // this is just example to start scan after disconnect, most likely there is better way to do it in arduino
  }
/****************************************/
/****************************************/
  delay(1000); 
}


void bleBegin()
{
  BLEDevice::init("");

  // Retrieve a Scanner and set the callback we want to use to be informed when we
  // have detected a new device.  Specify that we want active scanning and start the
  // scan to run for 5 seconds.
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());//扫描处理函数
  pBLEScan->setInterval(1349);//设置扫描间隔时间
  pBLEScan->setWindow(449);//主动扫描时间
  pBLEScan->setActiveScan(true);
  pBLEScan->start(5, false);//扫描时间,单位秒
  }


//蓝牙连接处理
bool connectToServer() {
    Serial.print("Forming a connection to ");
    Serial.println(myDevice->getAddress().toString().c_str());

    BLEClient*  pClient  = BLEDevice::createClient();
    Serial.println(" - Created client");

    pClient->setClientCallbacks(new MyClientCallback());

    // Connect to the remove BLE Server.
    pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
    Serial.println(" - Connected to server");
    pClient->setMTU(517); //set client to request maximum MTU from server (default is 23 otherwise)

    // Obtain a reference to the service we are after in the remote BLE server.
    BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
    if (pRemoteService == nullptr) {
      Serial.print("Failed to find our service UUID: ");
      Serial.println(serviceUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our service");


    // Obtain a reference to the characteristic in the service of the remote BLE server.
    pTXRemoteCharacteristic = pRemoteService->getCharacteristic(charTXUUID);
    if (pTXRemoteCharacteristic == nullptr) {
      Serial.print("Failed to find our characteristic UUID: ");
      Serial.println(charTXUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    pRXRemoteCharacteristic = pRemoteService->getCharacteristic(charRXUUID);
    if (pRXRemoteCharacteristic == nullptr) {
      Serial.print("Failed to find our characteristic UUID: ");
      Serial.println(charRXUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our characteristic");

    if(pRXRemoteCharacteristic->canNotify())
      pRXRemoteCharacteristic->registerForNotify(notifyCallback);

    connected = true;
    return true;
}

In connectToServer() of the Client part, connect to the BLE service set by SERVICE_UUID, and then send and receive messages through the Characteristic corresponding to RX and TX.

After burning the above code to two ESP32-C6 development boards, the following message can be received from the serial port monitoring:

2. Bluetooth switch based on dual-machine communication

On the basis of dual-machine communication, add button processing to the end that acts as the switch, and then send the information to control the LED to the controlled end. After the controlled end receives the message, it can control the LED on and off according to the specific situation of the message.

To process the keystrokes, you can use interrupts. The code involved is as follows:

#define BUTTON 9 //设置引脚9为按键的引脚


    pinMode(BUTTON, INPUT_PULLUP); //设置BUTTON引脚为外部中断引脚
    attachInterrupt(BUTTON, PinIntEvent, RISING);

void PinIntEvent()
{
    Serial.printf("PinInt Event.\r\n");
}

On the computer, there is a button D9/IO9, which can be used as BOOT, or as a user button after booting:

In the above key interrupt code, this key is used. Once the key is pressed, the set interrupt PinIntEvent() will be called. In PinIntEvent(), you can add the corresponding calling code:

void PinIntEvent()
{
    Serial.printf("PinInt Event.\r\n");
    if(millis() - lastInterrupt > 300) // we set a 10ms no-interrupts window
    {
      if(deviceConnected){  //当有设备连接时发送数据
        ledStatus = !ledStatus;
        lastInterrupt = millis();
        for (;;) {
          if (shared_var_mutex != NULL) {
            if (xSemaphoreTake(shared_var_mutex, portMAX_DELAY) == pdTRUE) {
                if(ledStatus) {
                  Serial.println("控制开灯");
                  digitalWrite(LED, HIGH);
                } else {
                  Serial.println("控制关灯");
                  digitalWrite(LED, LOW);
                }
                hasMsg = true;
                xSemaphoreGive(shared_var_mutex);
                break;
              }
            }
        }
      }
    }
}

In the main loop, add the code to send the message:

void loop() {
  if(deviceConnected){  //当有设备连接时发送数据
    if(hasMsg) {
      hasMsg = false;
      pTxCharacteristic->setValue("我是主机");
      pTxCharacteristic->notify();

      if(ledStatus) {
        pTxCharacteristic->setValue("ON");
        pTxCharacteristic->notify();
      } else {
        pTxCharacteristic->setValue("OFF");
        pTxCharacteristic->notify();
      }
    }
  }
  /****************************************/
  /****************************************/
  // delay(1000);
}

On the controlled end, after receiving the message, the LED is controlled according to the specific content of the message. The corresponding code is as follows:

//蓝牙接收数据处理,当收到数据时自动触发
static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) {  //传入uint8_t* pData用于存放数据
    String BLEData = "";
    for(int i = 0; i < length; i++)  //
      BLEData += (char)pData[i];
    Serial.println("*********");
    Serial.print("Received Value: ");
    Serial.println(BLEData);
    Serial.println("*********");

    if(BLEData == "ON"){
      Serial.println("开灯");
      digitalWrite(LED, HIGH);
      hasMsg = true;
    }  //判断接收的字符是否为"ON"

    if(BLEData == "OFF"){
      Serial.println("关灯");
      digitalWrite(LED, LOW);
      hasMsg = true;
    }  //判断接收的字符是否为"OFF"
}

After the above processing, the control end and the controlled end can send control information through the BLE UART service to control the LED.

Finally, the specific code is as follows:

Server code:

/*
    Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleServer.cpp
    Ported to Arduino ESP32 by Evandro Copercini
    updates by chegewara
*/

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

// 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"

#define LED 15 //设置引脚15为LED引脚
#define BUTTON 9 //设置引脚9为按键的引脚

uint8_t txValue = 0;
bool deviceConnected = false;
BLECharacteristic *pTxCharacteristic;

SemaphoreHandle_t shared_var_mutex = NULL;
bool ledStatus = false;
unsigned long lastInterrupt = 0;
bool hasMsg = false;

// 定义外部中断的Mode
// 0: 无中断,读取Touch值
// 1:Touch中断,执行 TouchEvent()
// 2: 外部IO的中断
#define EXT_ISR_MODE 2

void TouchEvent()
{
    Serial.printf("Touch Event.\r\n");
}
 
void PinIntEvent()
{
    Serial.printf("PinInt Event.\r\n");
    if(millis() - lastInterrupt > 300) // we set a 10ms no-interrupts window
    {
      if(deviceConnected){  //当有设备连接时发送数据
        ledStatus = !ledStatus;
        lastInterrupt = millis();
        for (;;) {
          if (shared_var_mutex != NULL) {
            if (xSemaphoreTake(shared_var_mutex, portMAX_DELAY) == pdTRUE) {
                if(ledStatus) {
                  Serial.println("控制开灯");
                  digitalWrite(LED, HIGH);
                } else {
                  Serial.println("控制关灯");
                  digitalWrite(LED, LOW);
                }
                hasMsg = true;
                xSemaphoreGive(shared_var_mutex);
                break;
              }
            }
        }
      }
    }
}

//蓝牙连接/断开处理。当有连接/断开事件发生时自动触发
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {   //当蓝牙连接时会执行该函数
      Serial.println("蓝牙已连接");
      deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {  //当蓝牙断开连接时会执行该函数
        Serial.println("蓝牙已断开");
        deviceConnected = false;
        delay(500); // give the bluetooth stack the chance to get things ready
        BLEDevice::startAdvertising(); // restart advertising
    }
};
/****************数据接收部分*************/
/****************************************/
//蓝牙接收数据处理。当收到数据时自动触发
class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      String rxValue = pCharacteristic->getValue();  //使用rxValue接收数据

      //if(rxValue == "ON"){Serial.println("开灯");}   //判断接收的字符是否为"ON"

      if (rxValue.length() > 0) {
        Serial.println("*********");
        Serial.print("Received Value: ");
        for (int i = 0; i < rxValue.length(); i++)
              Serial.print(rxValue);    //将接收的数据打印出来

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

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  bleBegin();

  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);

  shared_var_mutex = xSemaphoreCreateMutex();  // Create the mutex

#if 1 == EXT_ISR_MODE   // 触摸中断
    // Pin: T0(GPIO4), 函数指针:TouchEvent, 阈值: 40
    // touchAttachInterrupt(7, TouchEvent, 40);
 
#elif 2 == EXT_ISR_MODE   // 下降沿触发 
    pinMode(BUTTON, INPUT_PULLUP); //设置BUTTON引脚为外部中断引脚
    attachInterrupt(BUTTON, PinIntEvent, RISING);
#endif
}

/****************数据发送部分*************/
/****************************************/
void loop() {
  if(deviceConnected){  //当有设备连接时发送数据
    // pTxCharacteristic->setValue("我是从机");
    // pTxCharacteristic->notify();

    // pTxCharacteristic->setValue("Hello Sever");
    // pTxCharacteristic->notify();

    // for (;;) {
    //   if (shared_var_mutex != NULL) {
    //     if (xSemaphoreTake(shared_var_mutex, portMAX_DELAY) == pdTRUE) {

    //       pTxCharacteristic->setValue("我是从机");
    //       pTxCharacteristic->notify();

    //         xSemaphoreGive(shared_var_mutex);
    //         break;
    //       }
    //     }
    // }

    // hasMsg = true;
    if(hasMsg) {
      hasMsg = false;
      pTxCharacteristic->setValue("我是主机");
      pTxCharacteristic->notify();

      if(ledStatus) {
        pTxCharacteristic->setValue("ON");
        pTxCharacteristic->notify();
      } else {
        pTxCharacteristic->setValue("OFF");
        pTxCharacteristic->notify();
      }
    }
  }
  /****************************************/
  /****************************************/
  // delay(1000);
}


void bleBegin()
{
  BLEDevice::init(/*BLE名称*/"Long name works now");
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pRxCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID_RX,
                                         BLECharacteristic::PROPERTY_WRITE 
                                       );
  pRxCharacteristic->setCallbacks(new MyCallbacks()); 

 pTxCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID_TX,
                                         BLECharacteristic::PROPERTY_NOTIFY
                                       );
 pTxCharacteristic->addDescriptor(new BLE2902());

  pService->start();
  // BLEAdvertising *pAdvertising = pServer->getAdvertising();  // this still is working for backward compatibility
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();

  }

Client code:


/**
 * A BLE client example that is rich in capabilities.
 * There is a lot new capabilities implemented.
 * author unknown
 * updated by chegewara
 */

#include "BLEDevice.h"
//#include "BLEScan.h"

#define LED 15 //设置引脚13为LED引脚

#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"

// The remote service we wish to connect to.
static BLEUUID serviceUUID(SERVICE_UUID);
// The characteristic of the remote service we are interested in.
static BLEUUID    charTXUUID(CHARACTERISTIC_UUID_RX);

static BLEUUID    charRXUUID(CHARACTERISTIC_UUID_TX);

static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic* pTXRemoteCharacteristic;
static BLERemoteCharacteristic* pRXRemoteCharacteristic;
static BLEAdvertisedDevice* myDevice;

bool hasMsg = false;

/****************数据接收部分*************/
/****************************************/
//蓝牙接收数据处理,当收到数据时自动触发
static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) {  //传入uint8_t* pData用于存放数据
    String BLEData = "";
    for(int i = 0; i < length; i++)  //
      BLEData += (char)pData[i];
    Serial.println("*********");
    Serial.print("Received Value: ");
    Serial.println(BLEData);
    Serial.println("*********");

    if(BLEData == "ON"){
      Serial.println("开灯");
      digitalWrite(LED, HIGH);
      hasMsg = true;
    }  //判断接收的字符是否为"ON"

    if(BLEData == "OFF"){
      Serial.println("关灯");
      digitalWrite(LED, LOW);
      hasMsg = true;
    }  //判断接收的字符是否为"OFF"

    //Serial.print("Notify callback for characteristic ");
    //Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
    //Serial.print(" of data length ");
    //Serial.println(length);
}
/****************************************/
/****************************************/

//蓝牙连接/断开处理。当有连接/断开事件发生时自动触发
class MyClientCallback : public BLEClientCallbacks {
  void onConnect(BLEClient* pclient) {
  }

  void onDisconnect(BLEClient* pclient) {
    connected = false;
    Serial.println("onDisconnect");
  }
};


/**
 * Scan for BLE servers and find the first one that advertises the service we are looking for.
 */
 //蓝牙扫描处理事件。当开启扫描时自动触发
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
 /**
   * Called for each advertising BLE server.
   */
  void onResult(BLEAdvertisedDevice advertisedDevice) {
    //Serial.print("BLE Advertised Device found: ");
    //Serial.println(advertisedDevice.toString().c_str());

    // We have found a device, let us now see if it contains the service we are looking for.
    if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {
      BLEDevice::getScan()->stop();
      myDevice = new BLEAdvertisedDevice(advertisedDevice);
      doConnect = true;
      doScan = true;

    } // Found our server
  } // onResult
}; // MyAdvertisedDeviceCallbacks



void setup() {
  Serial.begin(115200);
  Serial.println("Starting Arduino BLE Client application...");
  bleBegin();

  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
}

void loop() {
  // If the flag "doConnect" is true then we have scanned for and found the desired
  // BLE Server with which we wish to connect.  Now we connect to it.  Once we are 
  // connected we set the connected flag to be true.
  if (doConnect == true) {
    if (connectToServer()) {
      Serial.println("We are now connected to the BLE Server.");
    } else {
      Serial.println("We have failed to connect to the server; there is nothin more we will do.");
    }
    doConnect = false;
  }
/****************数据发送部分*************/
/****************************************/
  if (connected) {  //当连接到蓝牙从机时发送数据
    // pTXRemoteCharacteristic->writeValue("我是从机");
    // hasMsg = true;
    if(hasMsg) {
      hasMsg = false;
      pTXRemoteCharacteristic->writeValue("我是从机");
      pTXRemoteCharacteristic->writeValue("OK");
    }
  }
  if(!connected){  //当没有连接到蓝牙从机时重新扫描
    BLEDevice::getScan()->start(5,false);  // this is just example to start scan after disconnect, most likely there is better way to do it in arduino
    delay(1000); 
  }
  delay(1000); 
/****************************************/
/****************************************/
}


void bleBegin()
{
  BLEDevice::init("");

  // Retrieve a Scanner and set the callback we want to use to be informed when we
  // have detected a new device.  Specify that we want active scanning and start the
  // scan to run for 5 seconds.
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());//扫描处理函数
  pBLEScan->setInterval(1349);//设置扫描间隔时间
  pBLEScan->setWindow(449);//主动扫描时间
  pBLEScan->setActiveScan(true);
  pBLEScan->start(5, false);//扫描时间,单位秒
  }


//蓝牙连接处理
bool connectToServer() {
    Serial.print("Forming a connection to ");
    Serial.println(myDevice->getAddress().toString().c_str());

    BLEClient*  pClient  = BLEDevice::createClient();
    Serial.println(" - Created client");

    pClient->setClientCallbacks(new MyClientCallback());

    // Connect to the remove BLE Server.
    pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
    Serial.println(" - Connected to server");
    pClient->setMTU(517); //set client to request maximum MTU from server (default is 23 otherwise)

    // Obtain a reference to the service we are after in the remote BLE server.
    BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
    if (pRemoteService == nullptr) {
      Serial.print("Failed to find our service UUID: ");
      Serial.println(serviceUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our service");


    // Obtain a reference to the characteristic in the service of the remote BLE server.
    pTXRemoteCharacteristic = pRemoteService->getCharacteristic(charTXUUID);
    if (pTXRemoteCharacteristic == nullptr) {
      Serial.print("Failed to find our characteristic UUID: ");
      Serial.println(charTXUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    pRXRemoteCharacteristic = pRemoteService->getCharacteristic(charRXUUID);
    if (pRXRemoteCharacteristic == nullptr) {
      Serial.print("Failed to find our characteristic UUID: ");
      Serial.println(charRXUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our characteristic");

    if(pRXRemoteCharacteristic->canNotify())
      pRXRemoteCharacteristic->registerForNotify(notifyCallback);

    connected = true;
    return true;
}

Burn the above code to two development boards, and view the corresponding output information through serial port monitoring:

Press the BOOT button on the Server board, and a message will be sent to the Client board to control the LED.

Latest reply

Does it automatically search for connections when powered on?   Details Published on 2024-5-20 14:33
 
 

6788

Posts

2

Resources
2
 

Does it automatically search for connections when powered on?

Comments

That's a must  Details Published on 2024-5-20 23:29
 
 
 

270

Posts

4

Resources
3
 
wangerxian posted on 2024-5-20 14:33 Does it automatically search for connections when powered on?

That is required

 
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list