ESP32:蓝牙BLE控制M3508电机
ESP32:蓝牙BLE控制M3508电机
先给各位朋友拜个年,祝大家新春快乐,事事顺利,身体健康啊!
还是熟悉的3508,内容概述:
- ESP32主控
- 蓝牙BLE通信
- 使用实时系统(FreeRTOS)
- 使用ESP32的TWAI总线(CAN)
ESP32使用ESP-IDF v4.3开发,仓库地址放在文末。
目录
ESP32的TWAI(CAN)
概览与对比
有人说ESP32没有CAN总线控制器,其实不然,只不过它被称作TWAI,two-wire automotive interface。这也是ESP32可以用来控制大疆M3508、M2006等电机的根本原因。由于官方放出的资料很少,所以不被大家所熟知。
ESP32的CAN控制器在功能上比STM32略逊一筹,同时技术披露较少,其硬件设计参数基本都是未知的。但从另一方面说,整体配置使用比STM32更简单一些的,特别是结合实时系统提供的一些组件,不需要过多的考虑中断等问题。
最大区别在于,STM32有三组FIFO和灵活分配的filter,ESP32则采用收发buffer,控制器硬件将接受到的消息放入buffer中,软件驱动再把buffer中的报文处理过后放入queue,用户应用读取queue获取报文,发送同理。
反馈的获取
ESP32没有提供中断回调函数接口。意味着STM32上使用接收中断来更新电机反馈的方法是行不通的,为保证反馈量的实时性,有以下三种方法可以选择:
- 使用优先级合适的任务进行轮询
- 利用定时器中断回调进行轮询
- 利用TWAI控制器的alert查询阻塞读取
由于我使用的FreeRTOS的tick为10ms,而大疆C620电调的发送速率默认为1KHz,所以我使用了第一个方法来获取电机反馈数据。创建一个从queue中读取报文的任务,不断阻塞查询queue,计算更新反馈数据。
蓝牙BLE
ESP32的最大亮点就是支持WiFi、蓝牙协议栈,使用蓝牙代替串口的应用场景无需多言。其中低功耗蓝牙BLE非常合适少量文本数据的发送。下面简要介绍几个蓝牙BLE概念。
GAP
GAP定义了设备的广播行为,例如手机可以扫描到很多蓝牙BLE设备便是靠GAP。GAP把设备分成两种:中心设备(Central)、外围设备(Peripheral),外围设备对外不断广播,中心设备扫描、接收广播。发现后进而建立连接,再利用下文的GATT协议进行数据传输。
举例来说,我们的手机往往扮演中心设备的角色,而智能手环、智能家居、蓝牙耳机、电动牙刷等设备则是外围设备。
GATT
利用GAP发现并连接相应设备后,就可以开始传输数据了。蓝牙BLE的数据传输建立在GATT协议上,它定义了BLE设备之间如何传输数据。GATT把设备分为Client和Server,其中命令与请求由Client主动发起,Server被动接受。
请注意:GATT的Client、Server身份与GAP的中心、外围设备没有任何关系,它们可以任意搭配,甚至可以既是Server又是Client。
参考:Getting Started with Bluetooth Low Energy:https://www.oreilly.com/library/view/getting-started-with/9781491900550/ch04.html
在本例中,运行着GATT Server的ESP32在建立连接前主动对外广播,充当外围设备。手机作为GATT Client,可以主动发起数据传输。
下面是典型的GATT Server的数据层级结构图,服务端上可以同时提供多个Service让客户端选择,每个Service内可以有多个Characteristic,其中就保存着数据的内容和描述。客户端请求的时候就可以单独请求某个Service里的某个Characteristic包含的数据。
举例说明,某款智能手环作为GATT Server,定义了电量和运动两个Service。电量服务内有一个Characteristic保存着电池电量百分比,手机请求它即可获得手环电量。运动Service内有步数、消耗卡路里、睡眠时间等Characteristic,手机可以在需要的时候分别请求这些数据。
由于蓝牙协议内容较多,这里暂不展开,后面有机会可以进一步深入讨论。
ESP32 API
为了使用BLE,首先要把蓝牙外设驱动、硬件初始化,按照之前说的,为了建立连接我们要初始化GAP,为了传输数据要初始化GATT。具体表现为要为GAP、GATT注册处理事件的回调函数。
ret = esp_ble_gatts_register_callback(gatts_event_handler);
//错误处理
ret = esp_ble_gap_register_callback(gap_event_handler);
//错误处理
ret = esp_ble_gatts_app_register(PROFILE_A_APP_ID);
//错误处理
这些回调函数使用switch语句判断由底层驱动传递上来的事件编号,并给出处理步骤,我们对其中的读写事件处理进行修改,使其符合我们的数据传输需求。
结合前面完成的TWAI驱动、移植的PID程序,电机控制程序基本完成。
实际上手
使用微信上的BLE调试小程序或者Nordic Connect软件都可以,后者较为专业简洁,但两者功能上差别不大。
向图中的Characteristic发送速度目标值,会触发ESP_GATTS_WRITE_EVT
事件,在处理中加入解析并向发送设备返回一个notify告知写入成功:
char data[30];
memcpy(data,param->write.value,param->write.len);
data[param->write.len]=0;
moto_pid.target=atof(data);
printf("resetting target:%.2f\n",moto_pid.target);
sprintf(data,"SET TARGET:%.2f",moto_pid.target);
if (a_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY){//发送notice
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id,
gl_profile_tab[PROFILE_A_APP_ID].char_handle,
strlen(data),(unsigned char *)data, false);}
当按下左边的获取按钮时,会触发ESP_GATTS_READ_EVT
事件,使用response让Client获得图中的速度值:
char spd[20];
sprintf(spd,"speed:%hd",moto_chassis->speed_rpm);
rsp.attr_value.len = strlen(spd);
memcpy(rsp.attr_value.value,spd,rsp.attr_value.len);
esp_ble_gatts_send_response(gatts_if, param->read.conn_id,
param->read.trans_id,
ESP_GATT_OK, &rsp);
总结
临近年关,事也多,心也燥。这次本是简单的移植,文章却一直拖到正月初二才写完。涉及蓝牙协议栈的东西不敢多说,还需要多加研究。最后,祝大家新春快乐,工作顺利,身体健康!
工程仓库地址:GitHub:https://github.com/HuXioAn/ESP32-M3508-BLE
技术新人,水平有限,文中纰漏请一定指出,如有其他意见也请不吝赐教。更多嵌入式相关内容请移步公众号,来找我聊聊天吧:
欢迎转载,转载请注明作者与原文地址。
作者:胡小安
原文地址:https://www.cnblogs.com/huxiaoan/p/15861624.html
ESP32:蓝牙BLE控制M3508电机的更多相关文章
- 蓝牙BLE实用教程
蓝牙BLE实用教程 Bluetooth BLE 欢迎使用 小书匠(xiaoshujiang)编辑器,您可以通过 设置 里的修改模板来改变新建文章的内容. 1.蓝牙BLE常见问答 Q: Smart Re ...
- 蓝牙(BLE)应用框架接口设计和应用开发——以TI CC2541为例
本文从功能需求的角度分析一般蓝牙BLE单芯片的应用框架(SDK Framework)的接口设计过程,并以TI CC2541为例说明BLE的应用开发方法. 一.应用框架(Framework) 我们熟知的 ...
- 深入浅出低功耗蓝牙(BLE)协议栈
深入浅出低功耗蓝牙(BLE)协议栈 BLE协议栈为什么要分层?怎么理解蓝牙"连接"?如果蓝牙协议只有ATT没有GATT会发生什么? 协议栈框架 一般而言,我们把某个协议的实现代码称 ...
- 蓝牙BLE实用教程(转载)
欢迎使用 小书匠(xiaoshujiang)编辑器,您可以通过 设置 里的修改模板来改变新建文章的内容. 1.蓝牙BLE常见问答 Q: Smart Ready 和 Smart 以及传统蓝牙之间是什么关 ...
- 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发具体解释
转载请注明来源: http://blog.csdn.net/kjunchen/article/details/50909410 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发具体 ...
- 深入浅出讲解低功耗蓝牙(BLE)协议栈
详解BLE连接建立过程https://www.cnblogs.com/iini/p/8972635.html 详解BLE 空中包格式—兼BLE Link layer协议解析https://www.cn ...
- 蓝牙BLE: ATT协议层中属性(Attribute)
ATT(Attribute Protocol)属性层是GATT和GAP的基础,它定义了BLE协议栈上层的数据结构和组织方式. 属性(Attribute)概念是ATT层的核心,ATT层定义了属性的内容, ...
- 蓝牙BLE: 蓝牙(BLE)协议栈
蓝牙协议是通信协议的一种,一般而言,我们把某个协议的实现代码称为协议栈(protocol stack),BLE协议栈就是实现低功耗蓝牙协议的代码,理解和掌握BLE协议是实现BLE协议栈的前提.当前的蓝 ...
- 蓝牙 BLE 协议学习: 001-BLE协议栈整体架构
背景 在深入BLE协议帧之前,我们先看一下BLE协议栈整体架构. 转载自:<深入浅出低功耗蓝牙(BLE)协议栈> 架构 如上图所述,要实现一个BLE应用,首先需要一个支持BLE射频的芯片, ...
随机推荐
- 涛思数据 TDengine集群搭建
一.准备 1.设置主机名 hostnamectl set-hostname a.com hostnamectl set-hostname b.com hostnamectl set-hostname ...
- 5G的到来
通信改变未来,从古至今信息的传输和获取从来就没有缺少过,之所以谁能取得胜利就是谁掌握的资源多,其中信息资源尤为重要,只要获取到更多的信息你就能提前做出应对策略.因此未来一定是信息的未来,作为信息传输的 ...
- BP网络简单实现
目录 BP算法的简单实现 Linear 全连接层 ReLu MSELoss 交叉熵损失函数 BP算法的简单实现 """ BPnet 简易实现 约定输入数据维度为(N, i ...
- 【优雅代码】04-1行代码完成多线程,别再写runnable了
[优雅代码]04-1行代码完成多线程,别再写runnable了 欢迎关注b站账号/公众号[六边形战士夏宁],一个要把各项指标拉满的男人.该文章已在github目录收录. 屏幕前的大帅比和大漂亮如果有帮 ...
- JavaScript交互式网页设计 • 【第1章 JavaScript 基本语法】
全部章节 >>>> 本章目录 1.1 JavaScript 概述 1.1.1 JavaScript 简介 1.1.2 JavaScript 的概念和执行原理 1.1.3 J ...
- 编写Java程序,使用PreparedState实现对英雄数据的新增、删除和更新
返回本章节 返回作业目录 需求说明: 使用PreparedState实现对英雄数据的新增.删除和更新 英雄(t_hero)表结构 列名(含义) 数据类型 约束 id (序号) int 主键,自动增长 ...
- Mysql 8.0版本以上和8.0以下jar包版本 需要注意的 URL连接参数useSSL、serverTimezone 相关问题
在语法上的需要注意的: MySQL 8.0 以下版本 - JDBC 驱动名及数据库 URL static final String JDBC_DRIVER = "com.mysql.jdbc ...
- windows下的pycharm下载与安装(不包括激活)
Pycharm的下载与安装 首先兄弟们我们依旧在浏览器输入pycharm的网址链接 PyCharm: the Python IDE for Professional Developers by Jet ...
- Eclipse导入Elasticsearch源码
Eclipse导入Elasticsearch源码的步骤, 基于Elasticsearch 6.2.2的源码版本. 1.安装JDK1.9 Elasticsearch 6.2.2需要JDK1.9编译,否则 ...
- 基于GO语言的PBFT共识算法
最近采用GO语言实现了一个PBFT共识算法的demo,主要用于展示算法的核心逻辑 github地址:https://github.com/w3liu/consensus/tree/master/pbf ...