006.合宙ESP32-C3+蓝牙调试器通过BLE发送接收数据教程

合宙ESP32-C3+蓝牙调试器通过BLE发送接收数据教程

一、问题提出

在平衡小车制作过程中,需要对KP/KD/KSP/KSI等PID系数进行调试,而平衡小车无法通过USB等进行有线调试,而ESP32-C3自带蓝牙+WIFI,使用WIFI比较吃算力,故选择通过蓝牙进行调参,同时能够将Angle/Encoder/PWM等数据回传至手机端进行查看。
006.合宙ESP32-C3+蓝牙调试器通过BLE发送接收数据教程_第1张图片

二、合宙ESP32-C3自带蓝牙分析

前期通过查找资料,发现合宙ESP32-C3自带蓝牙不是经典蓝牙,无法使用BluetoothSerial.h进行编程,只能通过低功耗BLE使用蓝牙。
下面为需要用到的库,PIO环境自带,无需下载。

#include 
#include 
#include 
#include 

具体原理,没有理解明白,不在赘述。

三、蓝牙调试器分析

蓝牙调试器有3种模式,分别为对话模式、专业调试、按钮控制
需要特别注意的是其通信设置,也就是通信协议。
006.合宙ESP32-C3+蓝牙调试器通过BLE发送接收数据教程_第2张图片

006.合宙ESP32-C3+蓝牙调试器通过BLE发送接收数据教程_第3张图片

数据包结构为

包头 数据 校验和 包尾
1字节 bool为1字节 1字节 1字节
0xA5 0x5A

四、代码框架

/*********************头文件*********************/
#include 
#include 
#include 
#include 
#include 
/************************************************/

/********************基本设置********************/
/**/    hw_timer_t *timer=NULL;
/**/    void BClock_Init(int duty_ms);
/**/    static void IRAM_ATTR Timer0_CallBack(void);  //以上为定时器
/**/    void Short2Byte(short i,uint8_t *byte);
/**/    void Int2Byte(int i,uint8_t *byte);
/**/    void Float2Byte(float f,uint8_t *byte);       //以上为数据类型转BYTE
/************************************************/

#define Step1_BlueTooth 1

/*********************蓝牙BLE********************/    
/**/#if Step1_BlueTooth
/**/    BLEServer *pServer = NULL;
/**/    BLECharacteristic * pTxCharacteristic;
/**/    bool deviceConnected = false;
/**/    bool oldDeviceConnected = false;
/**/    uint8_t txValue = 0;
/**/    #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) 
/**/        {
/**/            deviceConnected = true;
/**/        };
/**/    
/**/        void onDisconnect(BLEServer* pServer) 
/**/        {
/**/            deviceConnected = false;
/**/        }
/**/    };
/**/    void getBlueData(uint8_t *Value);
/**/    uint8_t modes[8];
/**/    class MyCallbacks: public BLECharacteristicCallbacks 
/**/    {
/**/        void onWrite(BLECharacteristic *pCharacteristic) 
/**/        {
/**/            std::string rxValue = pCharacteristic->getValue();
/**/            if (rxValue.length() > 0) 
/**/            {
/**/                for (int i = 0; i < rxValue.length(); i++)
/**/                {
/**/                    modes[i]=rxValue[i];
/**/                }
/**/                getBlueData(modes);
/**/            }
/**/        }
/**/    };
/**/    void BLEinit()
/**/    {
/**/        BLEDevice::init("BalanceCar");
/**/        pServer = BLEDevice::createServer();
/**/        pServer->setCallbacks(new MyServerCallbacks());
/**/        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("BLE is OK.");
/**/    }
/**/#endif 
/************************************************/

void setup() 
{
    Serial.begin(115200);
    #if Step1_BlueTooth
        BLEinit();
    #endif
    BClock_Init(1000);  //定时器单位为ms,发送数据至手机的频率
}

//
以上不需要做任何修改
//
//+++++_____+++++_____+++++_____+++++_____+++++_____以上不需要做任何修改_____+++++_____+++++_____+++++_____+++++_____+++++//
//
以上不需要做任何修改
//





//
以下不需要做任何修改
//
//+++++_____+++++_____+++++_____+++++_____+++++_____以下不需要做任何修改_____+++++_____+++++_____+++++_____+++++_____+++++//
//
以下不需要做任何修改
//


static void IRAM_ATTR Timer0_CallBack(void)
{
    BLEsendflag=true;
}

void BClock_Init(int duty_ms)
{
    timer=timerBegin(0,80,true);
    timerAttachInterrupt(timer,Timer0_CallBack,true);
    timerAlarmWrite(timer,1000*duty_ms,true); // 单位us,定时模式,10ms
    timerAlarmEnable(timer); // 启动定时器
}

void Short2Byte(short i,uint8_t *byte)
{
    unsigned long longdata=0;
    longdata=*(unsigned long *)&i;
    byte[1]=(longdata&0xFF00)>>8;
    byte[0]=(longdata&0x00FF);
}

void Int2Byte(int i,uint8_t *byte)
{
    unsigned long longdata=0;
    longdata=*(unsigned long *)&i;
    byte[3]=(longdata&0xFF000000)>>24;
    byte[2]=(longdata&0x00FF0000)>>16;
    byte[1]=(longdata&0x0000FF00)>>8;
    byte[0]=(longdata&0x000000FF);
}

void Float2Byte(float f,uint8_t *byte)
{
    unsigned long longdata=0;
    longdata=*(unsigned long *)&f;
    byte[3]=(longdata&0xFF000000)>>24;
    byte[2]=(longdata&0x00FF0000)>>16;
    byte[1]=(longdata&0x0000FF00)>>8;
    byte[0]=(longdata&0x000000FF);
}

自己需要做的只是在中间加上 void loop()

五、手机——>单片机解码

手机发送5个数据 bool(MotorStatus)、int16_t(kp)、int16_t(kd)、int16_t(ksp)、int16_t(ksi)
006.合宙ESP32-C3+蓝牙调试器通过BLE发送接收数据教程_第4张图片

/*****************蓝牙发送接收数据*****************/
/**/#if Step1_BlueTooth
/**/    bool MotorStatus;//控制电机开关
/**/    int16_t kp,kd,ksp,ksi;
/**/    //以上为手机发送来的数据
/**/    bool BLEsendflag=false;//定时发送标志
/**/#endif  
/************************************************/

void loop() 
{

}

#if Step1_BlueTooth
/**/    void getBlueData(uint8_t *Value)
/**/    {
/**/        MotorStatus=Value[1];
/**/        kp=(Value[3]<<8)+Value[2];  
/**/        kp=(Value[3]<<8)+Value[2];
/**/        kd=(Value[5]<<8)+Value[4];
/**/        ksp=(Value[7]<<8)+Value[6];
/**/        ksi=(Value[9]<<8)+Value[8];
/**/        Serial.printf("MotorStatus=%d,kp=%d,kd=%d,ksp=%d,ksi=%d\n",MotorStatus,kp,kd,ksp,ksi);
/**/    }
#endif 

六、单片机——>手机编码

单片机发送3个数据 short(PwmOut)、int(Encode_L)、float(Angle)
006.合宙ESP32-C3+蓝牙调试器通过BLE发送接收数据教程_第5张图片

/*****************蓝牙发送接收数据*****************/
/**/#if Step1_BlueTooth
/**/    bool BLEsendflag=false;//定时发送标志/**/    
/**/    uint8_t BLEBUF[13];// 数据包的顺序为BOOL(1)/BYTE(1)/SHORT(2)/INT(4)/FLOAT4)
/**/    short PwmOut=-12;
/**/    int Encode_L=-34;
/**/    float Angle=5.6;
/**/#endif  
/************************************************/



void loop() 
{
    if(deviceConnected&BLEsendflag)
    {
        BLEsendflag=false;
        BLEBUF[0]=0xA5;//包头
        Short2Byte(PwmOut,&BLEBUF[1]);
        Int2Byte(PwmOut,&BLEBUF[3]);
        Float2Byte(Angle,&BLEBUF[7]);
        BLEBUF[11]=(uint8_t)((BLEBUF[1]+BLEBUF[2]+BLEBUF[3]+BLEBUF[4]+BLEBUF[5]+BLEBUF[6]+BLEBUF[7]+BLEBUF[8]+BLEBUF[9]+BLEBUF[10])&0xFF);
        BLEBUF[12]=0x5A;//包尾
        pTxCharacteristic->setValue(BLEBUF,13);
        pTxCharacteristic->notify();
    }
}

你可能感兴趣的:(ESP32-C3,蓝牙BLE,算法,c语言,c++)