【Beetle ESP32 C6迷你开发板】双机通讯并实现蓝牙开关
<div class='showpostmsg'><p>在之前的文章 <a href="https://bbs.eeworld.com.cn/thread-1282254-1-1.html">【Beetle ESP32 C6迷你开发板】低功耗蓝牙(BLE)功能初步使用 </a>中,已经实现了UART Service服务,在此基础上,使用两块Beetle ESP32 C6迷你开发板,就可以实现基于UART的双机通讯,并在此基础上,实现蓝牙开关的功能。</p><p> </p>
<p><strong>一、双机通讯</strong></p>
<p>双机通讯,原则上,需要一个Server,一个Client。</p>
<p>其中,Server部分,直接使用之前文章中的即可。或者参考DFRobot Beetle ESP32 C6迷你开发板的WiKi文章:<a href="https://wiki.dfrobot.com.cn/_SKU_DFR1075_FireBeetle_2_Board_ESP32_C6_Advanced_Tutorial#target_2" target="_blank">https://wiki.dfrobot.com.cn/_SKU_DFR1075_FireBeetle_2_Board_ESP32_C6_Advanced_Tutorial#target_2</a></p>
<p>Client部分,自动扫描周边的BLE设备,然后检查是否有符合要求的Service设备,如果有,则进行连接,然后进行后续的处理。</p>
<p> </p>
<p>Server部分的代码如下:</p>
<pre>
<code class="language-cpp">#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); //将接收的数据打印出来
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();
}</code></pre>
<p> </p>
<p>Client部分的代码如下:</p>
<pre>
<code class="language-cpp">#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;
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;
}
</code></pre>
<p>在Client部分的connectToServer()中,连接到 SERVICE_UUID 设定的BLE服务上,然后在通过RX、TX对应的Characteristic,来收发消息。</p>
<p> </p>
<p>将上述代码,分别烧录到两个ESP32-C6开发板以后,从串口监听可以收到如下的消息:</p>
<p> </p>
<p>二、基于双机通讯的蓝牙开关</p>
<p>在双机通讯的基础上,在要做为开关的一端,添加按键的处理,然后发送控制LED的信息到受控的一端,而受控一端收到消息后,根据消息的具体情况来控制LED的亮灭即可。</p>
<p> </p>
<p>处理按键部分,可以使用中断来实现,涉及到的代码如下:</p>
<pre>
<code class="language-cpp">#define BUTTON 9 //设置引脚9为按键的引脚
pinMode(BUTTON, INPUT_PULLUP); //设置BUTTON引脚为外部中断引脚
attachInterrupt(BUTTON, PinIntEvent, RISING);
void PinIntEvent()
{
Serial.printf("PinInt Event.\r\n");
}</code></pre>
<p>在上,有一个按键D9/IO9,可以用作BOOT,也可以在启动后,做为用户按键:</p>
<p> </p>
<p>在上面的按键中断代码中,就使用了这个按键,一旦按键后,就会调用设置好的中断PinIntEvent(),在PinIntEvent()中,可以添加对应的调用代码:</p>
<pre>
<code class="language-cpp">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;
}
}
}
}
}
}</code></pre>
<p>在主循环,添加发送消息的代码即可:</p>
<pre>
<code class="language-cpp">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);
}</code></pre>
<p> </p>
<p>在受控端,收到消息后,根据消息的具体内容,控制LED,对应代码如下:</p>
<pre>
<code class="language-cpp">//蓝牙接收数据处理,当收到数据时自动触发
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;
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"
}</code></pre>
<p> </p>
<p>通过以上的处理后,控制端和受控端,就能够通过BLE UART服务来发送控制信息,控制LED了。</p>
<p> </p>
<p>最终,具体的代码如下:</p>
<p>Server代码:</p>
<pre>
<code class="language-cpp">/*
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();
}</code></pre>
<p> </p>
<p>Client代码:</p>
<pre>
<code class="language-cpp">
/**
* 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;
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;
}</code></pre>
<p>将上述代码烧录到两块开发板,通过串口监听,可以查看对应的输出信息:</p>
<p> 在Server板上按BOOT按键 ,就会发送消息到Client板,进行LED的控制了。</p>
<p> </p>
<p> </p>
<p> </p>
</div><script> var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;" style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
if(parseInt(discuz_uid)==0){
(function($){
var postHeight = getTextHeight(400);
$(".showpostmsg").html($(".showpostmsg").html());
$(".showpostmsg").after(loginstr);
$(".showpostmsg").css({height:postHeight,overflow:"hidden"});
})(jQuery);
} </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script> <p>上电自动搜索连接的吗?</p>
wangerxian 发表于 2024-5-20 14:33
上电自动搜索连接的吗?
<p>那必须的</p>
页:
[1]