【自制无人机】“辛”路历程(三)Servo库
2020-03-084680
AI 快速预览详细
本文详细介绍了如何使用Arduino的Servo库来控制电调。首先解释了电调的控制信号,特别是PWM信号的作用和频率选择。接着提供了具体的代码示例,展示了如何通过调节PWM信号的占空比来控制电机。文章还讨论了电调的内部算法和PWM信号的转换过程,帮助读者更好地理解电调的工作原理。
|
【自制无人机】“辛”路历程(三) 【前言】 通过【自制无人机】“辛”路历程(二),电机在Leonardo主板的控制下,可以转动了,但有好多地方是不清楚的,接下来一点点解决。 【代码程序】 上贴程序void setup()中有这样一行语句: esc.writeMicroseconds(1000);// initialize the signal to 1000有网友说是:先给最低占空比才能解锁 原程序上有一段英文注释,原文如下: 英文: 0.Servo.writeMicroseconds(): Writes a value in microseconds (uS) to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft. On standard servos a parameter value of 1000 is fully counter-clockwise, 2000 is fully clockwise, and 1500 is in the middle. 1.servo.write() allows a maximum of 180 servo positions servo.writeMicroseconds() allows a maximum of 1000 servo positions 2.The "write" method simply maps the "degrees" to microseconds and calls the "writeMicroseconds" method anyway. 我用百度给翻译了一下: 0.Servo.writeMicroseconds():将以微秒(uS)为单位的值写入伺服,并相应地控制轴。在标准伺服系统上,这将设置轴的角度。在标准伺服系统中,参数值1000是完全逆时针方向的,2000是完全顺时针的,1500是在中间的。 1.servo.write()允许最多180个伺服位置 servo.writeMicroseconds()最多允许1000个伺服位置 2.“write”方法只是将“degrees”映射到微秒,并调用“write microseconds”方法。 关于电调的控制信号:电调信号是pwm信号,信号频率为50Hz,一个周期为20ms。对于电调来讲,高电平脉宽为1ms表示停转,高电平脉宽为2ms表示满油门运转;对于舵机来说1.5ms是归中,1ms和2ms分别为左右满舵。(因此下面才直接用Servo库来给实现ESC信号的输出)。 那上贴中的程序使用了舵机的库文件去控制电调,就很简单了,控制代码很少 #include<Servo.h> // Using servo library to control ESC Servo esc; //Creating a servo class with name as esc int val; //Creating a variable val void setup() { esc.attach(9); //Specify the esc signal pin,Here as D9 esc.writeMicroseconds(1000);// initialize the signal to 1000 //可以给到990微秒比较保险,是滴滴滴短的三声,然后一声长的,再然后不响了,这时候加大占空比就会转了 Serial.begin(9600); } void loop() { val=analogRead(A0); // Read input from analog pin a0 and store in val val= map(val, 0,1023,1390,1600); // mapping val to minimum and maximum(Change if needed) Serial.println(val); esc.writeMicroseconds(val);// using val as the signal to esc } 但这篇文章中Arduino控制舵机和无刷电机(ESC)说直接利用Arduino 自带的Servo函数进行控制有缺点,缺点是只能控制2路舵机,因为 Arduino 自带函数只能利用数字9、10 接口。Arduino 的驱动能力有限,所以当需要控制1 个以上的舵机时需要外接电源。 Servo函数本来是用来控制舵的,舵机的转动的角度是通过调节PWM(脉冲宽度调制)信号的占空比来实现的。但目前市场上主流的电调,PWM基本只是起到一个信号传递的作用,你也可以使用CAN或UART来传递信号。至于电机的控制,内部也会涉及到PWM的调节,但是此PWM非彼PWM,电调内部的PWM是由电调内部的算法来驱动的,电调会把输入PWM转换成对应的油门量再做控制。 所以电调接收的PWM信号主要是信号传递作用,主要关注点在脉宽的大小上,电调识别的主要是PWM的脉宽1ms-2ms,也就是1ms认为油门是最小值,2ms认为油门是最大值,(这句提到多次,很重要)2ms对应的PWM周期是500HZ,所以这里决定了PWM频率的上限不能超过500hz,超过500PWM的脉宽就达不到2ms了,留一定的裕量,400hz是比较好的选择。 一会是50HZ,一会又是500HZ是怎么回事? 最早的航模多是固定翼,是没有飞控的,PWM是由遥控器接收机的PWM通道输出的,频率大概是在50HZ左右(以前用示波器测试过乐迪遥控器的PWM频率是67.42HZ),这个频率主要由舵机的输入频率决定的,早期模拟舵机是直流伺服电机控制器芯片一般只能接收50Hz频率(周期20ms)~300Hz左右的PWM,脉宽在0.5-2.5ms之间。 后来多旋翼时代,一直沿用这个控制信号来做控制,但是对于多旋翼,要求更高的控制频率和精度,如果PWM还是50HZ,会限制电调每秒钟调节的次数最多就50次,得不到很好的控制效果,所以多旋翼飞控在输出PWM的时候会采用更高的频率,像Pixhawk采用的是400HZ。 /*2020年3月11日,注释 下面这两段代码,就能产生50HZ的PWM信号 for(int i=0;i<=1000;i++){ digitalWrite(9,HIGH); delayMicroseconds(2000);//高电平持续2000微秒(油门最高点) digitalWrite(9,LOW); delayMicroseconds(18000);} for(int i=0;i<=1000;i++){ digitalWrite(9,HIGH); delayMicroseconds(1000);//高电平持续1000微秒(油门最低点) digitalWrite(9,LOW); delayMicroseconds(19000); } 2000微秒+18000微秒=20000微秒,就是20毫秒一次高低变化,50HZ 1000微秒+19000微秒=20000微秒,也是20毫秒一次高低变化,50HZ */ 另一种控制电调的方法,Arduino的普通数字传感器接口产生占空比不同的方波,模拟产生向电调发送的PWM信号。 (四)中进行边学习过介绍。 |





Dshot协议的出现,是把电调控制信号纯数字化了,不再是脉宽,不再是占空比,只需发个值,所以刷新率,轻松上M一级。
Proshot协议的出现,可以看成是Dshot的增强,(至于为啥。。。嘿嘿)。同时也向总线化发展,以前的IIC,CAN等总线形式的协议逐步兼容到,飞控-电调系统上了。使用总线形式的好处是是可以双向,也就意味这飞控-电调系统可以实现真正的闭环控制了。