ESP32S蓝牙04

ESP32S蓝牙04

我们先了解一下蓝牙的另一种状态BLE(低功耗蓝牙),BLE需要在Android API18版本以上,也就是安卓4.3版本以上才有的。

BLE之所以被称为低功耗蓝牙,就是需要通讯的时候才握手,数据传输完成后,就断开连接。而在这个通讯传输的过程中,主动方是客户端,都是由客户端发起连接请求、收发数据、断开连接等控制;相反,服务器端是被动的一方,服务器方随时做好了被连接的准备,并对连接请求作出响应,仅此而已。

先看一个简单的实用例子吧,手机用蓝牙连接小车,并发送控制指令,控制着小车的行驶状态。所以,在手机端需要的是一个控制小车行走的客户端APP,小车上面的接收端是ESP32,是服务器端,在接收到指令后,控制小车车轮电机的转动和转向,从而实现小车的运动。

  • 手机APP制作

我们还是使用APPInventor 2在线编辑的模式制作手机APP,需要注意的是,我们这里使用的蓝牙组件是“低功耗蓝牙”。低功耗蓝牙只有一个,他既可以设置成服务器,也可以设置成客户端,具体就看后面的逻辑程序设计了。

制作完界面的组件设计后,可以制作逻辑程序。这里我们准备设置成客户端,主要的任务就是搜索蓝牙服务器信号,发送握手连接的请求,收发数据。我们需要一个定时器,帮助我们不断地尝试发送控制指令。这个部分没有写,只写了手动发送按钮的功能。

  • ESP32S接收控制

ESP32S的接收的服务器端也要做成BLE,而BLE低功耗蓝牙的程序,在米思琪中是没有支持的,所以要改用的是Arduino IDE来编辑程序,代码也比较简单。

ESP32S通电后,直接初始化一个蓝牙服务器,并设置成可供别的蓝牙设备搜索、连接的状态。当手机控制端(客户端)发送连接请求、并连接成功后,当接收到从手机APP传来的控制指令后:直接把这个指令返回到手机APP(这样手机APP就可以知道自己之前发送的那条消息已经发送成功,以及ESP32S接收到指令后改变了小车的状态),这样手机APP就能知道小车的当前行驶状态了;同时把接收到的指令做进一步处理,通过串口发送到电脑显示(或者你也可以让指令显示在液晶屏,根据指令改变小车行驶状态)。

// 包含所必需的库

#include <BLEDevice.h>

#include <BLEServer.h>

#include <BLEUtils.h>

#include <BLE2902.h>

BLEServer *pServer = NULL;

BLECharacteristic *pTxCharacteristic;

bool deviceConnected = false;

bool oldDeviceConnected = false;

char BLEbuf[32] = {0};

String data = "";

// 定义收发服务的UUID(唯一标识)

#define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"

// RX串口标识

#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"

// TX串口标识

#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]);

            }

        Serial.println();

        data =rxValue.c_str();

        //Serial.println(data);

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

        Serial.println();

      }

    }

};

// setup()在复位或上电后运行一次:

void setup() {

  Serial.begin(115200);

  Serial.println("1- Download and install an BLE scanner app in your phone");

  Serial.println("2- Scan for BLE devices in the app");

  Serial.println("3- Connect to MyESP32");

  Serial.println("4- Go to CUSTOM CHARACTERISTIC in CUSTOM SERVICE and write something");

  Serial.println("5- See the magic =)");

  // 初始化蓝牙设备

  BLEDevice::init("MyESP32");

  // 为蓝牙设备创建服务器

  pServer = BLEDevice::createServer();

  pServer->setCallbacks(new MyServerCallbacks());

  // 基于SERVICE_UUID来创建一个服务

  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 a client connection to notify...");

  Serial.println();

}

// loop()一直循环执行:

void loop() {

    if (deviceConnected==1&data.length()>0) {

        memset(BLEbuf, 0, 32);

        memcpy(BLEbuf, data.c_str(), 32);//数据赋值

        Serial.println(BLEbuf);

        pTxCharacteristic->setValue(BLEbuf);   //收到数据后返回数据

        pTxCharacteristic->notify();

        data = "";  //返回数据后进行清空,否则一直发送data

    }

    // 没有新连接时

    if (!deviceConnected && oldDeviceConnected) {

        // 给蓝牙堆栈准备数据的时间

        delay(500);

        pServer->startAdvertising();

        // 重新开始广播

        Serial.println("start advertising");

        oldDeviceConnected = deviceConnected;

    }

    // 正在连接时

    if (deviceConnected && !oldDeviceConnected) {

        // 正在连接时进行的操作

        oldDeviceConnected = deviceConnected;

    }

}

关键代码解读:

// 定义收发服务的UUID(唯一标识)

#define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"

// RX串口标识

#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"

// TX串口标识

#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

BLE低功耗蓝牙需要设置独特的标识UUID,ESP32S开发板通电后,向外不停地广播一个服务器及服务器的UUID,然后手机客户端就可以通过搜索并选择这个服务器的UUID,选择和这块开发板握手连接。

我们可以注意到,在开发板驱动程序这里设置的一些UUID标志,在手机控制APP的逻辑代码中也要一一对应的,否则就无法握手、无法通讯了。

  • 真机测试

我们把这个手机控制的APP下载到手机并安装。

给ESP32S连接到电脑(接通电源),并在Arduino IDE中打开串口监视器,注意选择波特率为115200。

打开手机,取消手机中原来已配对的蓝牙设备,重新搜索,发现这个开发板的蓝牙信号。特别特别地注意了,不要配对(因为这时候的ESP32S广播的是BLE低功耗蓝牙的服务,而手机默认的配对是传统的BT蓝牙服务。所以即使你选择配对的话,手机也会告诉你需要专用的软件才能配对的)

在手机中打开控制APP,然后选择扫描——蓝牙列表——连接,会发现连接成功。然后你就可以按动手机中的方向按钮,开发板也能收到响应的控制指令,并把指令传递到串口监视器中显示出来。

有了这个,只要稍加修改,手机控制的ESP32S蓝牙小车就要成功了。

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

tongyue

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

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

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

打赏作者

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

抵扣说明:

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

余额充值