云天 发表于 2022-6-2 14:25:50

【Beetle ESP32-C3试用(一)】测试蓝牙Bluetooth 5传输距离

本帖最后由 云天 于 2022-6-2 14:29 编辑


Beetle ESP32-C3是一款基于ESP32-C3 RISC-V 32位单核处理器芯片的主控板,专为物联网 (IoT) 设备而设计。
本贴将测试Beetle ESP32-C3的蓝牙Bluetooth 5传输距离实际传输距离。
【蓝牙服务】
根据例程,找到蓝牙的服务UUID,和特征UUID(发送和接收)
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"

【APP inventor2】

编写手机APP
1、界面设计

2、获取蓝牙地址

3、连接蓝牙并监听数据



4、接收数据



5、发送指令,控制ESP32 C3板载灯



【ESP32 C3编程】
使用Arduino IDE编写程序,配置过程参考官方教程。
以下程序,通过修改例程。每隔一秒向APP发送递增数字。

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

BLEServer *pServer = NULL;
BLECharacteristic * pTxCharacteristic;
bool deviceConnected = false;

int led = 10;
// 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 {
    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
      pServer->startAdvertising(); // restart advertising

    }
};

/****************数据接收部分*************/
/****************************************/
//蓝牙接收数据处理。当收到数据时自动触发
class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();//接收数据,并赋给rxValue

      if(rxValue == "ON\r"){digitalWrite(led,HIGH);Serial.println("开灯");}   //判断接收的字符是否为"ON"
      if(rxValue == "OFF\r"){digitalWrite(led,LOW);Serial.println("关灯");}   //判断接收的字符是否为"OFFN"

      if (rxValue.length() ==3) {
      digitalWrite(led,HIGH);Serial.println("开灯");
      }
      if (rxValue.length() ==4) {
      digitalWrite(led,LOW);Serial.println("关灯");
      }
    }      
};
/***************************************/
/****************************************/

uint16_t txValue = 0;
void setup() {
Serial.begin(115200);
BLEBegin();//初始化蓝牙

pinMode(led,OUTPUT);
}

void loop() {
/****************数据发送部分*************/
/****************************************/
if (deviceConnected) {//如果有蓝牙连接,就发送数据
   
    pTxCharacteristic->setValue(txValue);//发送字符串
    pTxCharacteristic->notify();
    delay(1000); // bluetooth stack will go into congestion, if too many packets are sent
    txValue++;

   
}
/****************************************/
/****************************************/
}


void BLEBegin(){
// Create the BLE Device
BLEDevice::init(/*BLE名称*/"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());

// Start the service
pService->start();

// Start advertising
pServer->getAdvertising()->start();
Serial.println("Waiting a client connection to notify...");
}
查看在“\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.3\libraries\BLE\src”,“BLECharacteristic.h“文件。setValue()函数所接收的数据类型。确定上面发送的数据类型。

class BLECharacteristic {
public:
      BLECharacteristic(const char* uuid, uint32_t properties = 0);
      BLECharacteristic(BLEUUID uuid, uint32_t properties = 0);
      virtual ~BLECharacteristic();

      void         addDescriptor(BLEDescriptor* pDescriptor);
      BLEDescriptor* getDescriptorByUUID(const char* descriptorUUID);
      BLEDescriptor* getDescriptorByUUID(BLEUUID descriptorUUID);
      BLEUUID      getUUID();
      std::string    getValue();
      uint8_t*       getData();
      size_t         getLength();

      void indicate();
      void notify(bool is_notification = true);
      void setBroadcastProperty(bool value);
      void setCallbacks(BLECharacteristicCallbacks* pCallbacks);
      void setIndicateProperty(bool value);
      void setNotifyProperty(bool value);
      void setReadProperty(bool value);
<font color="#ff0000">      void setValue(uint8_t* data, size_t size);
      void setValue(std::string value);
      void setValue(uint16_t& data16);
      void setValue(uint32_t& data32);
      void setValue(int& data32);
      void setValue(float& data32);
      void setValue(double& data64); </font>
      void setWriteProperty(bool value);
      void setWriteNoResponseProperty(bool value);
      std::string toString();
      uint16_t getHandle();【实际测试】
通过接收信息数据的稳定性来,判断传输距离。因地面一块瓷砖为60CM,在74块砖前较为稳定,之后会出现跳跃。确定传输距离为44.4米。



【测试视频】


https://www.bilibili.com/video/BV1yL4y1K7Yk?share_source=copy_web

【扩展知识】
1、远距离传输
蓝牙5可以做远距离传输,远距离传输将会无人机,遥控赛车,竞技手柄,工业自动化需要200-500范围内的数据传输提供强有力的技术支持,目前可以支持蓝牙5远距离的芯片有Nordic 52840,TI CC2640R2F, Silconlab EFR32 Blue Gecko,但是可惜的是目前没有一部手机支持远距离。

2、数据类型为什么喜欢叫它 int8_t, uint8_t;int16_t, uint16_t;int32_t, uint32_t?
1,数据类型中都带有_t, _t 表示这些数据类型是通过typedef定义的,而不是新的数据类型。也就是说,它们其实是我们已知的类型的别名。
2,8,16,32又是什么意思?
这些数字都是位数,即,使用多少位来存储数据,一个字节8位,其中因为数字有正负之粉,对应有符号(signed,最高位为0,表示正数)和无符号(unsigned,最高位为1,表示负数),所以表示的范围不一样,但是因为位数一致,故表示的个数是一样的。
比如使用16位,也就是两个字节来存储
可以是 typedef signed short int int16_t;//给有符号短整型short int,取别名int16_t
也可以是 typedef unsigned short int uint16_t;//给无符号短整型short int,取别名为uint16_t
int16_t 表示数据范围则是0 ~65535。
uint16_t 表示数据范围为-32768~32767
表示的个数是一样的:65536=2的16次方


整型的每一种都有无符号(unsigned)和有符号(signed)两种类型(float和double总是带符号的),在默认情况下声明的整型变量都是有符号的类型(char有点特别),如果需声明无符号类型的话就需要在类型前加上unsigned。无符号版本和有符号版本的区别就是无符号类型能保存2倍于有符号类型的正整数数据,比如16位系统中一个int能存储的数据的范围为-32768~32767,而unsigned能存储的数据范围则是0 ~65535。由于在计算机中,整数是以补码形式存放的。根据最高位的不同,如果是1,有符号数的话就是负数;如果是无符号数,则都解释为正数。同时在相同位数的情况下,所能表达的整数范围变大。

挖一下这句话
在默认情况下声明的整型变量都是有符号的类型(char有点特别),有什么特别呢

如何确认char到底是signed char还是unsigned char

ANSI C 提供了3种字符类型,分别是char、signed char、unsigned char 、char相当于signed char或者unsigned char,但是这取决于编译器!
这三种字符类型都是按照1个字节存储的,可以保存256个不同的值。
signed char取值范围是 -128 到 127
unsigned char 取值范围是 0 到 255

有符号和无符号有默认的,可以省略不写,默认情况下声明的整型变量都是有符号的类型









小明同学 发表于 2022-6-6 22:54:01

请问app inventor 2的网址是多少?
我找到官方的但进不去
页: [1]
查看完整版本: 【Beetle ESP32-C3试用(一)】测试蓝牙Bluetooth 5传输距离