项目和设计思路
最近在研究家用的小型雕刻机,我发现这一类工业应用中对电机的要求远远比一般情况要高。例如,在切削时,我们需要一定的转速来确保刀口的切削速度符合要求。但问题是,切削时刀口遇到的阻力却不是一成不变的。一般来讲,电机在工作时,随着阻力变大,电机负载变大,转速会降低,功率会变大。但在此时,我却需要无论切削阻力如何变化,稳定保持电机转速保持一致。这就需要使用编码器实时监测电机转速,然后利用PID控制器来进行控制。而工业控制器又大又贵,不太适合家庭业余DIY,因此我自己设计一个通用的PID电机控制器。
方案框图和介绍
框图的左边是硬件外设,右边是功能划分。我使用了两种控制方式,一种是直接在控制器上通过编码器直接控制,另一种是通过上位机来进行控制。输出的话我设计了三种控制方式,一种是0v-10v模拟量输出,用来控制工业上常见的三相电机驱动器;另一种是电调输出,输出1000ns-2000ns的PWM信号,可以驱动常见的航模电调;第三种是PWM占空比直接控制,可以接MOS管直接驱动有刷电机。
原理图介绍
项目电路由四大块组成,一块是MCU单片机部分。由于我直接使用了ARDUINO PRO MINI模块,因此不需要再设计外围电路;
第二块是LCD部分。这里使用了一颗onsemi的MMBT3904LT1G NPN三极管来驱动背光电路,还用了一个电位器来设置对比度。
第三块是电路输入输出部分。我在所有的引脚上都串了一个小电阻,以实现防止脉冲,保护MCU的作用。模拟量输入的地方我加了一个变阻器进行分压,这样方便不同电平范围的前置DAC设备都可以方便的进行接入。编码器作为最主要的HMI输入设备,除此外我还增加了两个滑动开关,可以用来做模式的切换。
输出部分的我增加了一个一个PWM转0-10V电压的模块,用来控制工业上常见的三相电机驱动器。目前比较好买到的这样的模组有两种,一种是电路板模组,用运放和三极管实现功能;另外一种是GP8101芯片。我把两个的封装都画在了板子上,这样在制作时可以根据自己的焊接水平自行选择使用哪个方案。
最后一部分是电源模块部分。因为工业上大多供电是12-24V,因此可以使用一个DC-DC降压模块来完成5V供电。
指定厂商元器件简单介绍
项目中我使用了onsemi的MMBT3904LT1G NPN三极管,这个三极管用来驱动LCD屏幕的背光电路。
从规格书中可以看到,onsemi的这颗MMBT3904LT1G NPN三极管在保持了常见SOT-23-3封装的基础上,性能较为优异,最大电压可以做到40V,电流可以做到200mA,是作为LCD背光驱动三极管的理想选择。
PCB设计
PCB我把MCU和芯片,模块等都放在反面,按钮,端子和LCD屏等需要交互的东西都放在了正面。焊接时注意顺序,先焊接好除LCD以外的所有东西,验证好功能无误后,再焊接LCD。否则一旦LCD焊好了,就不方便再调整焊接其他模块。
软件代码介绍
由于ARDUINO PRO MINI仅有两个中断,因此我并没有使用双中断来检测编码器,因为电机测速码盘同样也需要使用到中断。为了保证编码器读取的准确性,防止毛刺等因素干扰,我在中断函数中配置了中断功能的切换。
void encoder1() {
dmillis = millis() - previousMillis;
if (dmillis > 10) // debounce
{
if (!digitalRead(clk)) {
if (digitalRead(dt)) {
enc = 1;
bool1 = 1;
} else {
enc = 2;
bool1 = 2;
}
attachInterrupt(digitalPinToInterrupt(clk), encoder2, RISING);
backlight_on;
}
}
}
void encoder2() {
if (digitalRead(clk)) {
if (bool1 == 1) {
if (digitalRead(dt)) {
return;
}
}
if (bool1 == 2) {
if (!digitalRead(dt)) {
return;
}
}
attachInterrupt(digitalPinToInterrupt(clk), encoder1, FALLING);
previousMillis = millis();
}
}
整个板子一共实现两种功能,用两个页面来显示。第一种是开环控制,直接使用PWM输出来驱动电机,设置占空比就可以调整电机转速;第二种是闭环控制,可以直接通过编码器在屏幕上修改PID参数,并且参数会使用EEPROM进行记录。
出于一般显示器设备的节电考虑,我还增加了自动息屏功能。当一段时间没有操作后会自动把屏幕关掉。
backlight_timeout = millis() - backlight_time;
if (backlight_timeout > 60000) {
digitalWrite(backlight, LOW);
}
硬件功能展示
板子背面焊接好是这样。模块之间的连接我使用了从排针上拔下来的插针。原本设计DC-DC模块的地方,由于手边正好没有,于是焊接了一个7805.板子上的功率并不高,一个7805也足以完成供电任务。ARDUINO模块上的五个针脚是用来烧录程序使用的。
烧录好程序,就可以看到设计好的界面:
我用了一个小电机,在输出轴上固定一个码盘,再加一个小车测速模块,就完成了一个简易电机制作。
接好所有的线。具体PID的控制效果可以参考视频。视频中我会验证开环和闭环控制。至于多种输入输出方式就不一一演示,可以从代码中直接简单看到相应功能。
心得体会
一年一度的FastBond又来了。这次活动的灵活性非常大,刚好可以满足我正在设计的项目,希望未来能多一点这样灵活的活动。