#### 基于RSICV@FPGA的两轮平衡车 --- ### 一、项目简介 #### 1.开发人员: * 浙江大学研究生 **吴健** * 上海工程技术大学研究生 **张大桂** * 重庆大学研究生 **张祥** * 西交利物浦本科生 **刘振邦** #### 2.项目功能: * 两轮自平衡小车; * 自动避障功能; * 电脑遥控功能。 #### 3.总体设计: 首先,确定项目整体框架:关键器件、各个模块、电源和主板PCB;然后使用Quartus植入RSIC-V软核,设置各种外设:I2C、PWM、HC-SR04、UART、ENCODER,融合直流电机、姿态传感器信息以及超声波模块,使用卡尔曼滤波以及PID算法,调整参数,使小车能够平稳运行并实现避障,并使得小车能和手机电脑等电子设备终端通信,实现远程遥控。 ### 二、PCB模块 #### 1.项目设计流程 ##### 1.1整体方案 {{ :平衡小车框图.jpg?600 |}} ##### 1.2关键器件 - 降压芯片LM2575-N {{:lm2575-n.pdf|}} - 模数转换芯片ADC081S101{{:adc081s101.pdf|}} - 电机驱动芯片TB6612{{:tb6612_datasheet.pdf|}} - 电平转换芯片74LV8T245{{:74lvc8t245_datasheet.pdf|}} - 六轴姿态传感器mpu6050{{:mpu6050寄存器英文版本.pdf|}}{{:mpu6050原版英文手册.pdf|}} - 编码器{{:2.编码器使用教程与测速原理.pdf|}} - 超声波传感器模块HC-SR04{{:超声波测距模块_hc-sr04_用户手册.pdf|}} - 蓝牙通信HC-05{{:hc-05.pdf|}} - PWM外设{{:m10_pwm_trm.pdf|}} ##### 1.3电路设计和PCB 1.电源模块: a.原理图:{{:电源模块原理图.pdf|}} {{ :电源模块原理图.png?600 |}} b.PCB版图:{{:电源模块pcb版图1.pdf|}} {{ :电源模块pcb版图.png?600 |}} 2.主板 a.原理图:{{:project.pdf|}} {{ :平衡小车原理图.png?1200 |}} b.PCB版图:{{:主板pcb版图1.pdf|}} {{ :平衡小车主板pcb.png?1200 |}} ##### 1.4心得 #### 2.项目调试 ##### 2.1功能调试 1.电源板功能调试: a.电池接口接错了,易造成短路; b.电源板应能输出一路5V的电压和四路12V的电压, c.检查电容极性是否接反。 2.主板功能调试: a.各个模块的电源和地是否短路; b.电源板供电给各个模块是否正常。 ##### 2.2问题和解决办法 1.问题: a.在电源模块中,电池接口接错了; b.在主板中,12V的电源线画太细了,可能不足以支撑5A的电流; 2.解决办法: a.重新绘制电源模块的PCB版图,注意电池接口的极性;{{ :电池接口.png?400 |}} b.重新绘制主板的PCB版图,把电源线加粗; ##### 2.3遗留问题 ##### 2.4调试总结 在有电池接口的版图设计时,需要注意三座接口的管脚问题,注意电源与地别短路。 #### 3.项目总结 - 项目设计初期,项目框图要考虑清楚,项目需要用到哪些模块或是器件; - 在绘制原理图和PCB版图要严格按照datasheet上的信息,包括管脚分配,管脚极性等; - 调试时也需要注意一些以前没用过的器件,其管脚分配的问题。 ### 三、FPGA模块 #### 1.项目设计 {{ :项目设计.png?400 |}} #### 2.硬件连接 {{ :硬件连接2.jpg?400 |}} #### 3.工作原理 - 在Quartus里,添加了基于RSIC-V软核的各种平衡小车需要的的外设接口,比如输出PWM波,通过处理超声波测距,通过读取编码器脉冲读取速度,ADC模块以及OLED屏模块的SPI接口,读取MPU6050数据的I2C接口,以及蓝牙模块的UART接口,然后将硬件代码通过Quartus烧入FPGA中。 - 在Arduino开发环境下,开发C++程序,调用各种外设,完成小车平衡所需要的算法。然后通过make编译生成可执行文件,通过Python代码载入工具,上传编译好的程序。 #### 4.代码实现 ##### 4.1模块划分 - MPU6050读取姿态信息模块 - 编码器读取速度模块 - 蓝牙通信模块 - 电机驱动模块 - 超声波测距模块 - ADC读取电源电压以及OLED显示模块 - ESP32远程操纵模块 - PID算法模块 各个模块代码汇总如下 {{:software.zip|}} ##### 4.2关键模块实现 ###### 4.2.1 MPU6050读取姿态信息 通过编写好的I2C接口,读取MPU6050的数据。首先在MPU6050的相关寄存器写入数据,初始化MPU6050寄存器。然后按照I2C协议通过指定的寄存器读取的三轴加速度以及角 速度数据。 在C++语言里代码如下: {{:mpu6050_0.png|}} {{:mpu6050_1.png|}} {{:mpu6050_2.png|}} ###### 4.2.2 PID算法实现 PID算法分为 直立控制PD反馈,速度控制PI反馈,转向控制P反馈。使用卡尔曼滤波读取平滑且做过预测的角度,速度数据,然后进行反馈控制。 在C++语言里代码如下: {{:直立控制_1.png|}} {{:速度控制_1.png|}} {{:转向控制_1.png|}} {{:超声波.png|}} ######4.2.3 编码器转速读取模块 在电机固定转速下,编码器会输出固定的脉冲数,通过读取脉冲数来读取速度。 在Verilog里代码如下: {{:encoder.zip|}} ######4.2.4 超声波测距模块 HC-SR04模块会隔一段时间发送一个trig信号,触发超声波的发送。然后会接到一段高电平的信号,高电平的持续时间与前方障碍物的距离成正比,以此计算前方距离远近。 在Verilog里代码如下: {{:hc_sr04.zip|}} ###### 4.2.5 ADC转换以及OLED显示模块 ADC会接收到电源电压的模拟信号,然后转化为数字信号发送给FPGA,我们将转化的数据显示在OLED屏上。 在Verilog里代码如下: {{:lcd.zip|}} {{:adc081s101.zip|}} ###### 4.2.6 蓝牙通信模块 HC-05芯片通过UART接口与FPGA实现远程通信。 {{:uart_hc-05.zip|}} ###### 4.2.7 ESP32远程操控模块 {{::esp32pic.png?200|}} {{:esp32.zip|}} ##### 4.3关键知识点、难点 ###### 4.3.1RSIC-V {{:reindeer_step_cyc10nano.rar|}} {{:riscv笔记.docx|}} ###### 4.3.2卡尔曼滤波 由于小车运行期间,MPU6050芯片提供的数据夹杂有较严重的噪音,在芯片处理静止状态时数据摆动都可能超过2%。除了噪音,各项数据还会有偏移的现象,也就是说数据并不是围绕静止工作点摆动, 因此需要通过滤波算法消除噪音。对于夹杂了大量噪音的数据,卡尔曼滤波器的效果无疑是最好的。一个卡尔曼滤波器接受一个轴上的角度值、角速度值以及时间增量,估计出一个消除噪音的角度值。跟据当前的角度值和上一轮估计的角度值,以及这两轮估计的间隔时间,还可以反推出消除噪音的角速度。我们使用滤波过后的角度和角速度来作为PD控制里的角速度。(记住输入的角度值、角速度值的方向一定要匹配,否则会得到错误的滤波数据)。 ######4.3.3PID算法 所谓PID控制,就是对偏差进行比例、积分和微分的控制。PID由3个单元组成,分别是比例(P)单元、积分(I)单元、微分(D)单位。在工程实践中,一般P是必须的,所以衍生出许多组合的PID控制器,如PD、PI、PID等。 {{:pid控制.png?500|}} {{:pid.png?500|}} {{:直立车参考方案_飞思卡尔官网文件_经典_.pdf|}} ###### 4.3.4调试 #### 5.运行结果 经过实验,通过搭建在FPGA上的RSIC-V的软核处理器以及添加的各种外设,最后能让小车平稳运行,加减速,转弯,以及遥控。基本能实现预期的功能。 {{ab2b13b5b0bc8b3a0c3804311cc18d4c.mp4|用RISCV@FPGA制作的自平衡车}} ### 四、项目总结 一个多月的培训终于结束了,感觉收获很多。仔细回味,有很多做的不足和需要改进的地方。 - 前期做板子、器件选型一定要仔细认真,反复比对,最好还要进行模拟仿真,否则到后期调试的时候很容易出现某个错误,导致不得不回炉重做,大大浪费时间。 - PID调参是一个很漫长的过程,在其中会遇到很多坑,一定要注意自己的每一步操作(MPU6050以及编码器读数、读数校准、滤波、算法等等)的正确性,某一个环节出现了问题,就无法使小车平衡。记得如果长时间都不能调出正确的参数,一定要反过头来想一想每个环节是否有一些漏洞或者错误。 - 硬件问题多如牛毛,排BUG一定得有耐心,切勿钻牛角尖。