合宙ESP32-C3+藍(lán)牙調(diào)試器通過BLE發(fā)送接收數(shù)據(jù)教程
一、問題提出
在平衡小車制作過程中,需要對(duì)KP/KD/KSP/KSI等PID系數(shù)進(jìn)行調(diào)試,而平衡小車無法通過USB等進(jìn)行有線調(diào)試,而ESP32-C3自帶藍(lán)牙+WIFI,使用WIFI比較吃算力,故選擇通過藍(lán)牙進(jìn)行調(diào)參,同時(shí)能夠?qū)ngle/Encoder/PWM等數(shù)據(jù)回傳至手機(jī)端進(jìn)行查看。
二、合宙ESP32-C3自帶藍(lán)牙分析
前期通過查找資料,發(fā)現(xiàn)合宙ESP32-C3自帶藍(lán)牙不是經(jīng)典藍(lán)牙,無法使用BluetoothSerial.h進(jìn)行編程,只能通過低功耗BLE使用藍(lán)牙。
下面為需要用到的庫,PIO環(huán)境自帶,無需下載。
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
具體原理,沒有理解明白,不在贅述。
三、藍(lán)牙調(diào)試器分析
藍(lán)牙調(diào)試器有3種模式,分別為對(duì)話模式、專業(yè)調(diào)試、按鈕控制
需要特別注意的是其通信設(shè)置,也就是通信協(xié)議。
數(shù)據(jù)包結(jié)構(gòu)為
包頭 | 數(shù)據(jù) | 校驗(yàn)和 | 包尾 |
---|---|---|---|
1字節(jié) | bool為1字節(jié) | 1字節(jié) | 1字節(jié) |
0xA5 | 0x5A |
四、代碼框架
/*********************頭文件*********************/
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
/************************************************/
/********************基本設(shè)置********************/
/**/ hw_timer_t *timer=NULL;
/**/ void BClock_Init(int duty_ms);
/**/ static void IRAM_ATTR Timer0_CallBack(void); //以上為定時(shí)器
/**/ void Short2Byte(short i,uint8_t *byte);
/**/ void Int2Byte(int i,uint8_t *byte);
/**/ void Float2Byte(float f,uint8_t *byte); //以上為數(shù)據(jù)類型轉(zhuǎn)BYTE
/************************************************/
#define Step1_BlueTooth 1
/*********************藍(lán)牙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); //定時(shí)器單位為ms,發(fā)送數(shù)據(jù)至手機(jī)的頻率
}
//
以上不需要做任何修改
//
//+++++_____+++++_____+++++_____+++++_____+++++_____以上不需要做任何修改_____+++++_____+++++_____+++++_____+++++_____+++++//
//
以上不需要做任何修改
//
//
以下不需要做任何修改
//
//+++++_____+++++_____+++++_____+++++_____+++++_____以下不需要做任何修改_____+++++_____+++++_____+++++_____+++++_____+++++//
//
以下不需要做任何修改
//
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,定時(shí)模式,10ms
timerAlarmEnable(timer); // 啟動(dòng)定時(shí)器
}
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()
五、手機(jī)——>單片機(jī)解碼
手機(jī)發(fā)送5個(gè)數(shù)據(jù) bool(MotorStatus)、int16_t(kp)、int16_t(kd)、int16_t(ksp)、int16_t(ksi)
文章來源:http://www.zghlxwxcb.cn/news/detail-435455.html
/*****************藍(lán)牙發(fā)送接收數(shù)據(jù)*****************/
/**/#if Step1_BlueTooth
/**/ bool MotorStatus;//控制電機(jī)開關(guān)
/**/ int16_t kp,kd,ksp,ksi;
/**/ //以上為手機(jī)發(fā)送來的數(shù)據(jù)
/**/ bool BLEsendflag=false;//定時(shí)發(fā)送標(biāo)志
/**/#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
六、單片機(jī)——>手機(jī)編碼
單片機(jī)發(fā)送3個(gè)數(shù)據(jù) short(PwmOut)、int(Encode_L)、float(Angle)
文章來源地址http://www.zghlxwxcb.cn/news/detail-435455.html
/*****************藍(lán)牙發(fā)送接收數(shù)據(jù)*****************/
/**/#if Step1_BlueTooth
/**/ bool BLEsendflag=false;//定時(shí)發(fā)送標(biāo)志/**/
/**/ uint8_t BLEBUF[13];// 數(shù)據(jù)包的順序?yàn)锽OOL(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();
}
}
到了這里,關(guān)于006.合宙ESP32-C3+藍(lán)牙調(diào)試器通過BLE發(fā)送接收數(shù)據(jù)教程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!