BLheli电调与Dshot通讯
这里首先介绍一下基本概念
-
电调ESC:全称电子速度控制器,一个电机需要控制转动,需要电调ESC,电调负责把输入的直流电转化为三相电等输入,根据飞行控制器的输入指令(FC)调节电机的速度(和方向)。。
-
电调原理:电调是芯片加一堆mos组成的,芯片负责接收控制信号,然后控制mos的通断,把输入的直流电通过mos通断变化为不同的三相电等
-
电调固件:电调里面的芯片会烧录一个程序,这个程序就是电调固件,这个电调固件有很多开源的方案,比如BLHeli,BLHeli_S,这些是写好的,并且有很多功能比如温度控制等。
-
电调通讯协议:电调里的芯片接收控制信号也有很多,称为电调通讯协议,比如Dshot,PWM,Oneshot,其中dshot是目前最好的。有人提出这些通讯协议之后,这些BLHeli之类的固件就会兼容这些协议,比如BLHeli一般是兼容PWM,Oneshot,Dshot的。其中PWM的是需要校准最小值和最大值之后才能控制。
-
电调固件如何兼容不同协议:电调固件兼容各种电调通讯协议,具体而言,在固件里有一个分类器,输入不同协议的命令,他会先判别是什么协议然后再执行。
一个参考-无刷电调基础知识以及BLHeli固件烧录和参数调整 - 梦幻之心星 - 博客园 (cnblogs.com)
电调固件
电调固件是在每个电调上运行的软件,它确定电调的性能,支持的协议以及可以使用的配置接口。电调可以使用的固件取决于硬件。
- SimonK:最古老的两种开源电调固件之一,已经过时不再更新。内嵌了一个开环foc驱动
- BLHeli:最古老的两种开源电调固件之一,由于其广泛的功能和友好的用户界面而变得流行。
- BLHeli_S:BLHeli固件的第二代。专门为具有Busybee处理器的电调开发。
- BLHeli_32:第三代和最新一代BLHeli固件。专门为32位电调编写,不再开源。
BLheli固件
固件命名:
BLHeli_S代码除了修订版外,还用一个字母、另一个字母和两个数字命名。例如"A_L_10_REV16_0.HEX"。
第一个字母表示MCU的引脚;
第二个字母是L或H(L代表24MHz MCU,H代表48MHz MCU);
这两个数字表示FET的开关死区时间。单位为20.4ns。一些场效应晶体管驱动器具有自适应场效应晶体管死区时间控制,对于这些MOS管,则用00表示场效应晶体管开关死区时间。
可设置参数
-
**启动功率:**启动功率可设置为0.031到1.5之间的相对值。这是启动期间允许的最大功率。实际应用的功率取决于节气门输入,可以更低,但最低电平是最高电平的四分之一。启动功率也会影响双向操作,因为该参数用于限制方向反转期间应用的功率。于低转速,电机的最大功率是有限的,以便于检测低反电势电压。允许的最大功率可通过启动功率参数设置。较低的启动功率参数将为较低转速提供较低的最大功率(这从rev16.1开始实施)。
-
换向时间: 换向定时可设置为低/中低/中/中高/高,对应于00/7.50/150/22.50/300定时提前。一般来说,一个中等设置将工作良好,但如果电机口吃它可以是有益的改变时间。一些高电感的电机可以有很长的换相退磁时间。这可能会导致电机停止或口吃时,快速油门增加,特别是在运行在低转速。将定时设置为高将允许更多的时间去消磁,通常是有帮助的。
-
**消磁补偿:**消磁补偿是一种保护电机不因换相后较长的绕组退磁时间而失速的功能。典型的症状是发动机停止或快速增加油门时卡顿,特别是在低转速运行时。如上所述,设置高换向时间通常有帮助,但以效率为代价。
-
**方向:**旋转方向可设置为前进/后退/双向前进/双向后退。在双向模式下,中央油门为零,上面为前进方向旋转,下面为反向旋转。当选择双向操作时,TX编程被禁用。
-
**嘟嘟声强度:**设置正常运行时的蜂鸣音强度。
-
**信标强度:**设置蜂鸣信标蜂鸣时蜂鸣的强度。如果油门信号在给定时间内为零,电子悬架控制系统将开始发出蜂鸣声。请注意,设置高信标强度可能会导致电机或ESC过热!
-
**信标延迟:**信标延迟设置信标哔哔声开始前的延迟。
-
**最小油门、最大油门和中值油门:**这些设置设置ESC的油门范围。中央油门仅用于双向操作。为这些设置提供的值适用于正常的1000us到2000us输入信号,对于其他输入信号,这些值必须按比例缩放。
-
**热保护:**可以启用或禁用热保护。温度阈值可以在800C和1400C之间编程(可编程阈值从rev16.3开始执行)。可编程阈值主要是为了支持硬件制造商使用,因为不同的硬件可以对所使用的各种组件的最高温度有不同的公差。
-
**低转速功率保护:**可以启用或禁用低转速的功率限制。禁用它可能是必要的,以实现在低电源电压下运行的一些低kV电机的全功率。但是,禁用它会增加同步丢失的风险,并可能导致电机或电子稳定控制系统过热。
-
**停止时制动:**可以启用或禁用制动停止。启用时,油门为零时将应用制动器。对于非零油门,此设置无效。
-
**LED控制:**LED可以在支持它的ESC上控制。最多可以打开或关闭4个LED。
BLHeli蜂鸣器含义
对于BLHeli电调,上电的时候会发出一些声音,实际上每个声音都有自己的意思,如下:
- 100%上电时,电子稳定控制系统鸣叫3次。
- 当检测到油门信号时,它会发出一声低沉的哔哔声。这表示开始警戒序列。
- 然后,当或如果油门为零,它会发出一声高音哔哔声。这标志着警戒序列的结束。
- 此外,如果在启用顺序期间检测到100%油门,电子悬架控制系统将开始油门校准。
- 如果电子稳定控制系统处于待命状态,并在给定时间内看到零油门,它会发出信标哔哔声,大约每三秒发出一声哔哔声。
BLHeli的热保护:
ESC测量MCU内的温度,如果温度过高,则限制电机功率。电机功率分四步限制:
- 如果温度高于临界值,电机功率限制在75%。
- 如果温度高于阈值加上50摄氏度,电机功率限制在50%。
- 如果温度高于阈值加上100摄氏度,电机功率限制在25%。
- 如果温度高于阈值+150℃,则电机功率限制为0%。
BLheli上位机——BLheli suite
传统改变固件参数的方法是编译一个固件之后通过arduino nano烧录到电调里面来设置如上一堆值。
但是现在有了BLheli,可以通过上位机对电调进行参数修改,具体方法是用一个betaflight的飞控板连接上电调,用电调来改。
BLheli固件烧录
比较简单,但是需要arduino uno,CH340,BLheli Suite,可以搜一下教程,需要把几个焊点和arduino连接,或者直接用Betaflight的飞控板貌似也能烧录。
懒人免焊接傻瓜包会从零开始给电调刷BLHELI固件 – Elvin Play
电调协议
电调协议是飞行控制器和电调用于通信的语言,决定了信号从飞控到电调的发送速度。四轴飞行器使用的电调协议及信号宽度如下,从上而下依次高级
- 最传统PWM :1000us – 2000us
- Oneshot125模拟协议:125us – 250us
- Oneshot 42模拟协议:2us – 84us
- Multishot模拟协议:5us – 25us
- Dshot数字协议
- Dshot150 :106.8us
- Dshot300 :53.4us
- Dshot600 :26.7us
- DShot1200:13.4us
- ProShot
模拟电调和数字电调区别
模拟电调协议每隔几微秒就将电脉冲从飞控发送到电调。脉冲持续时间的长短(油门大小)决定了电机的功率。这种控制方案受到电噪声和电脉冲定时精度的限制。
使用 DShot 数字电调意味着飞控将以数字编号的形式向电调发送精确的油门值。这个数字将有一个校验值,以便从飞控发送到电调的油门值永远不会被识别错误。
与Oneshot和Multishot相比,DShot有什么优势:
- 无需进行电调行程校准
- 更精确的传输信号,更强大的抗干扰能力
- 分辨率为2048,而其他协议分辨率为1000
- 比Oneshot协议更快
- 更安全,每个信号 电调都可以检测yifan损坏的数据
- DSHOT并不是效率最高的协议
PWM
PWM ESC 通常用于固定翼车辆和地面航模,对于FPV通常使用 oneshot 或 dshot ESC,但这是最传统的电调通讯协议。PWM ESC 使用周期性脉冲进行通信,其中脉冲的宽度表示所需的功率水平。脉冲带宽通常介于 1000uS (零功率) 和 2000uS (全功率) 之间。信号的周期性帧速率取决于 ESC 的能力,通常在 50Hz 和 490 Hz 之间理论最大值为 500Hz,速率越高,ESC 越好,尤其是在需要快速响应设定值变化的情况下。对于 PWM 伺服系统,50Hz 通常就足够了,许多不支持更高的速率。
Oneshot
OneShot 125 电调通常比 PWM 电调快得多,因此响应更快,更容易调整。对于多旋翼飞行器,它们比 PWM 更受欢迎,但不如 DShot ESC,因为Dshot不需要校准,并且可以提供遥测反馈。OneShot 协议有许多变体,它们支持不同的速率,比如oneshot42,oneshot125。
OneShot 125 与 PWM 相同,但使用的脉冲宽度短 8 倍(从 125us 到 250us,从零功率到全功率)。这使得 OneShot 125 ESC 具有更短的占空比/更高的速率。对于 PWM,理论最大值接近 500 Hz,而对于 OneShot,则接近 4 kHz。实际支持的速率取决于所使用的 ESC。
Dshot
DShot(Digital Shot,是数字协议)(相对于oneshot,oneshot125,oneshot42,multishot等模拟协议)。它最初是由Felix在KISS提出的,后来被Betaflight和BLHeli_S开发团队采用。是用来和刷有BLheli固件的电调通讯的协议。
- BLHeli固件开源地址:https://github.com/bitdump/BLHeli.git
- BLHeli上位机:https://github.com/blheli-configurator/blheli-configurator.git
DShot的速度
目前常用的DShot协议有:DShot600,DShot300,DShot150 (DShot1200已经在最新的betaflight4.11固件取消了),其传输速率:
-
DShot600 – 600,000 bits/Sec
-
DShot300 – 300,000 bits/Sec
-
DShot150 – 150,000 bits/Sec
引入 DSHOT300 和 DSHOT150 是为了确保支持功能较弱的旧ESC电调,DSHOT1200是较新的协仪,有些电调可能还不支持。
例如,DShot600的频率为600,000 / 1637500hz= 37.5 KHz,这意味着将一个油门值从飞控发送到电调需要大约26.7 uS。各种电调传输协议速度对比与 Oneshot125、 Oneshot42和 Multishot 的速度相比(假设信号是100% 油门)
-
Oneshot125 – 250 uS
-
DShot150 – 106.7 uS
-
Oneshot42 – 84 uS
-
DShot300 – 53.3 uS
-
DShot600 – 26.7 uS
-
Multishot – 25 uS
快速传输速度的 DShot 理论上将允许高达33KHz的飞控运行频率。但是不要高达37.5 KHz,因为需要留有一些空间。虽然 DShot600没有 Multishot 那么快,但是只要它比飞控运行频率快就足够了。
Dshot600数据帧
一个 DShot 数据包由16位组成
- 11位表示油门值(2^10= 2048分辨率)
- 1位表示遥测请求是telemetry请求标志,tlm需要电调硬件支持
- 4位表示 CRC 校验(循环冗余校验)
- 速度600kbits/s,一帧信号的长度为26.7us。
- 对于DSHOT600,整个比特位的长度为1.67us(T0H+T0L或T1H+T1L),0的高电平时间为625ns,1的高电平时间是1250ns。
- 帧与帧之间需要一点间隔(2-3us),以区别不同的帧信号
- 11位油门值可以达到2048的分辨率,实际使用48-2047表示油门值,所以油门信号是2000的分辨率,0是上电后的默认值(锁定值),1-47表示一些命令和设置,一些值的意义如下:
- 1-5:beep(1= low freq. 5 = high freq
- esc信息请求(fw版本和通过tlm线发送的SN)
- 7:一个方向旋转
- 8:另一个方向旋转
- 9:3d模式关闭
- 10:3d模式打开
- 11:esc设置请求(saved settings over the TLM wire)
- 12:保存设置
双向dshot
Joe Lucid更进一步引入了双向 DSHOT协议。支持双向dshot的电子调速器ESC能够向飞行控制器发送遥测数据,包括:
- 温度
- 电压
- 当前
- 累积电流消耗
- 转速值
这些 DShot ESC 将有一条额外的遥测线。
要启用此功能(在支持此功能的电调上使用):将所有电调的遥测线连接在一起,然后将它们连接到未使用的飞行控制器串行端口上的一个 RX 引脚。
在通讯方式上,双向DSHOT信号使用反转电平(空闲为 1)。 FC 到 ESC 使用 DSHOT 帧,但最低 4 位是其他半字节异或后的反码(正常DSHOT的校验是不反码的)。
一套Dshot通讯参考代码1
#define ESC_BIT_0 11
#define ESC_BIT_1 22
#define ESC_CMD_BUF_LEN 18
uint16_t ESC_CMD[ESC_CMD_BUF_LEN]={0};
static uint16_t prepareDshotPacket(const uint16_t value, int8_t requestTelemetry)
{
// 油门大小为11位 所以这里先左移一位 添加上请求回传标志共12位
uint16_t packet = (value << 1) | (requestTelemetry ? 1 : 0);
// 将12位数据分为3组 每组4位, 进行异或
// compute checksum
int csum = 0;
int csum_data = packet;
for (int i = 0; i < 3; i++) {
csum ^= csum_data; // xor data by nibbles
csum_data >>= 4;
}
//取最后四位 其他的不要
csum &= 0xf;
// append checksum 将CRC添加到后四位
packet = (packet << 4) | csum;
return packet;
}
static void pwmWriteDigital(uint16_t *esc_cmd, uint16_t value)
{
value = ( (value > 2047) ? 2047 : value );
value = prepareDshotPacket(value, 0);
esc_cmd[0] = (value & 0x8000) ? ESC_BIT_1 : ESC_BIT_0;
esc_cmd[1] = (value & 0x4000) ? ESC_BIT_1 : ESC_BIT_0;
esc_cmd[2] = (value & 0x2000) ? ESC_BIT_1 : ESC_BIT_0;
esc_cmd[3] = (value & 0x1000) ? ESC_BIT_1 : ESC_BIT_0;
esc_cmd[4] = (value & 0x0800) ? ESC_BIT_1 : ESC_BIT_0;
esc_cmd[5] = (value & 0x0400) ? ESC_BIT_1 : ESC_BIT_0;
esc_cmd[6] = (value & 0x0200) ? ESC_BIT_1 : ESC_BIT_0;
esc_cmd[7] = (value & 0x0100) ? ESC_BIT_1 : ESC_BIT_0;
esc_cmd[8] = (value & 0x0080) ? ESC_BIT_1 : ESC_BIT_0;
esc_cmd[9] = (value & 0x0040) ? ESC_BIT_1 : ESC_BIT_0;
esc_cmd[10] = (value & 0x0020) ? ESC_BIT_1 : ESC_BIT_0;
esc_cmd[11] = (value & 0x0010) ? ESC_BIT_1 : ESC_BIT_0;
esc_cmd[12] = (value & 0x8) ? ESC_BIT_1 : ESC_BIT_0;
esc_cmd[13] = (value & 0x4) ? ESC_BIT_1 : ESC_BIT_0;
esc_cmd[14] = (value & 0x2) ? ESC_BIT_1 : ESC_BIT_0;
esc_cmd[15] = (value & 0x1) ? ESC_BIT_1 : ESC_BIT_0;
HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)esc_cmd,ESC_CMD_BUF_LEN);
}