https://m.toutiao.com/is/BFWx4Pc/
自制了一个非常简单易学的小四轴,只用到了两个芯片和700行代码。
这原本是一个用于大四轴的飞控项目,由荷兰开发者Joop Brokking公布。我为了学习和调试更加安全,才改为了小四轴。小四轴上引出了引脚,也可以当作大四轴飞控使用,只需对飞控软件代码稍作修改。
如果你会购买飞控板、电调、电机等零件,且能自己组装无人机。那这个项目可以帮你更进一步,学习到飞控的核心技术。
如果你喜欢研究软件无线电,这个小四轴也可以作为你研究无线电通信信号的基础。
原理分5个板块讲解,包含:STM32、MPU6050、驱动电路、供电、其他4个部分的电路。
1.STM32部分
这是主控芯片STM32的原理图,它与电路的其它部分都有联系。
STM32由LDO供电,通过IIC接收MPU6050的姿态信息,接收PA0口上的遥控PPM信号,输出控制4个电机的PWM信号。除此之外,它也用模拟引脚实现了电池电压检测功能,可以控制LED灯来显示状态,可以通过串口与电脑相连。
J1接口是下载固件时用的,下载模式时J1需要短接,正常模式下J1需要开路。
2.MPU6050部分
这是MPU6050的原理图,它通过IIC接口与STM32相连,提供姿态信息。
3.驱动电路部分
这是其中一个电动机的驱动电路,PWM4_LF_CW表示这是第四个电机信号,它可以直接输出给外部的电调模块用来控制大四轴的无刷电机,也可以送到下图中的MOSFET上,用来控制接在LF这个2pin口上的有刷电机。
控制两种不同的电机,需要对代码做一些修改。
4.供电部分
这个供电部分是最重要的!参考下图,从左到右依次是电池接口、开关、线性稳压芯片。
在画PCB过程中,电池口的正极先连接到了开关正极上,网络名称是VBAT,它与4个电动机对应的MOSFET相连,这几条连线必须要足够粗,否则电流不够。
电池负极一般都与铺铜区相连,也就是说电路上的所有部分都有一根很粗的导线连到了负极,所以负极不会是问题,主要是正极要足够粗。
如果正极不够粗,可能会导致STM32的供电电压不够,程序跑飞。当你看到蓝色LED灯开始闪烁,代表飞控重启了,很有可能就是这个原因。
我提供的资料里线宽是足够的,但是如果你要二次开发,要注意这个问题。
5.其他部分
这是一个3pin的接口,用来把航模遥控器的PPM信号输送给主控,你也可以用软件无线电来自己实现遥控。
这是一个4pin接口,可以用它往主控里烧写固件,也可以在正常使用过程中向电脑发送调试数据。
这是一个分压电路,可以获得与电池电压成正比的信号,然后给到主控的模拟输入口上,检测电池剩余电量。
这是两个LED状态指示灯,可以由主控的两个引脚控制。飞机在飞行过程中,用LED来显示状态非常方便。
对于飞控来说,其实主要难点还是在软件代码上,代码我做了很多减法,删除了原项目的多余部分。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////These functions handle the red and green LEDs. The LEDs on the flip 32 are inverted. That is why a Flip32 test is needed.///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void red_led(int8_t level) {if (flip32)digitalWrite(PB4, !level); //If a Flip32 is used invert the output.else digitalWrite(PB4, level); //When using the BluePill the output should not be inverted.}void green_led(int8_t level) {if (flip32)digitalWrite(PB3, !level); //If a Flip32 is used invert the output.else digitalWrite(PB3, level); //When using the BluePill the output should not be inverted.}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////In this part the error LED signal is generated.///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void error_signal(void) {if (error >= 100) red_led(HIGH); //When the error is 100 the LED is always on.else if (error_timer < millis()) { //If the error_timer value is smaller that the millis() function.error_timer = millis() + 250; //Set the next error_timer interval at 250ms.if (error > 0 && error_counter > error + 3) error_counter = 0; //If there is an error to report and the error_counter > error +3 reset the error.if (error_counter < error && error_led == 0 && error > 0) { //If the error flash sequence isn't finisched (error_counter < error) and the LED is off.red_led(HIGH); //Turn the LED on.error_led = 1; //Set the LED flag to indicate that the LED is on.}else { //If the error flash sequence isn't finisched (error_counter < error) and the LED is on.red_led(LOW); //Turn the LED off.error_counter++; //Increment the error_counter variable by 1 to keep trach of the flashe
由于文件格式原因,代码仅展示部分,需要的伙伴可以在评论区滴滴,无偿分享~
联系客服