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

2023-11-07 18:59

本文主要是介绍006.合宙ESP32-C3+蓝牙调试器通过BLE发送接收数据教程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

一、问题提出

在平衡小车制作过程中,需要对KP/KD/KSP/KSI等PID系数进行调试,而平衡小车无法通过USB等进行有线调试,而ESP32-C3自带蓝牙+WIFI,使用WIFI比较吃算力,故选择通过蓝牙进行调参,同时能够将Angle/Encoder/PWM等数据回传至手机端进行查看。
在这里插入图片描述

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

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

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

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

三、蓝牙调试器分析

蓝牙调试器有3种模式,分别为对话模式、专业调试、按钮控制
需要特别注意的是其通信设置,也就是通信协议。
在这里插入图片描述

在这里插入图片描述

数据包结构为

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

四、代码框架

/*********************头文件*********************/
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
/************************************************//********************基本设置********************/
/**/    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_BlueToothBLEinit();#endifBClock_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,定时模式,10mstimerAlarmEnable(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)
在这里插入图片描述

/*****************蓝牙发送接收数据*****************/
/**/#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)
在这里插入图片描述

/*****************蓝牙发送接收数据*****************/
/**/#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();}
}

这篇关于006.合宙ESP32-C3+蓝牙调试器通过BLE发送接收数据教程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/365646

相关文章

Django开发时如何避免频繁发送短信验证码(python图文代码)

《Django开发时如何避免频繁发送短信验证码(python图文代码)》Django开发时,为防止频繁发送验证码,后端需用Redis限制请求频率,结合管道技术提升效率,通过生产者消费者模式解耦业务逻辑... 目录避免频繁发送 验证码1. www.chinasem.cn避免频繁发送 验证码逻辑分析2. 避免频繁

Python pandas库自学超详细教程

《Pythonpandas库自学超详细教程》文章介绍了Pandas库的基本功能、安装方法及核心操作,涵盖数据导入(CSV/Excel等)、数据结构(Series、DataFrame)、数据清洗、转换... 目录一、什么是Pandas库(1)、Pandas 应用(2)、Pandas 功能(3)、数据结构二、安

python运用requests模拟浏览器发送请求过程

《python运用requests模拟浏览器发送请求过程》模拟浏览器请求可选用requests处理静态内容,selenium应对动态页面,playwright支持高级自动化,设置代理和超时参数,根据需... 目录使用requests库模拟浏览器请求使用selenium自动化浏览器操作使用playwright

2025版mysql8.0.41 winx64 手动安装详细教程

《2025版mysql8.0.41winx64手动安装详细教程》本文指导Windows系统下MySQL安装配置,包含解压、设置环境变量、my.ini配置、初始化密码获取、服务安装与手动启动等步骤,... 目录一、下载安装包二、配置环境变量三、安装配置四、启动 mysql 服务,修改密码一、下载安装包安装地

电脑提示d3dx11_43.dll缺失怎么办? DLL文件丢失的多种修复教程

《电脑提示d3dx11_43.dll缺失怎么办?DLL文件丢失的多种修复教程》在使用电脑玩游戏或运行某些图形处理软件时,有时会遇到系统提示“d3dx11_43.dll缺失”的错误,下面我们就来分享超... 在计算机使用过程中,我们可能会遇到一些错误提示,其中之一就是缺失某个dll文件。其中,d3dx11_4

Linux下在线安装启动VNC教程

《Linux下在线安装启动VNC教程》本文指导在CentOS7上在线安装VNC,包含安装、配置密码、启动/停止、清理重启步骤及注意事项,强调需安装VNC桌面以避免黑屏,并解决端口冲突和目录权限问题... 目录描述安装VNC安装 VNC 桌面可能遇到的问题总结描js述linux中的VNC就类似于Window

Go语言编译环境设置教程

《Go语言编译环境设置教程》Go语言支持高并发(goroutine)、自动垃圾回收,编译为跨平台二进制文件,云原生兼容且社区活跃,开发便捷,内置测试与vet工具辅助检测错误,依赖模块化管理,提升开发效... 目录Go语言优势下载 Go  配置编译环境配置 GOPROXYIDE 设置(VS Code)一些基本

Windows环境下解决Matplotlib中文字体显示问题的详细教程

《Windows环境下解决Matplotlib中文字体显示问题的详细教程》本文详细介绍了在Windows下解决Matplotlib中文显示问题的方法,包括安装字体、更新缓存、配置文件设置及编码調整,并... 目录引言问题分析解决方案详解1. 检查系统已安装字体2. 手动添加中文字体(以SimHei为例)步骤

Java JDK1.8 安装和环境配置教程详解

《JavaJDK1.8安装和环境配置教程详解》文章简要介绍了JDK1.8的安装流程,包括官网下载对应系统版本、安装时选择非系统盘路径、配置JAVA_HOME、CLASSPATH和Path环境变量,... 目录1.下载JDK2.安装JDK3.配置环境变量4.检验JDK官网下载地址:Java Downloads

Python办公自动化实战之打造智能邮件发送工具

《Python办公自动化实战之打造智能邮件发送工具》在数字化办公场景中,邮件自动化是提升工作效率的关键技能,本文将演示如何使用Python的smtplib和email库构建一个支持图文混排,多附件,多... 目录前言一、基础配置:搭建邮件发送框架1.1 邮箱服务准备1.2 核心库导入1.3 基础发送函数二、