一板网电子技术论坛

风筝
发表于: 2018-9-3 22:47:10 | 显示全部楼层

在受到Segway的RYNO Motors电动独轮摩托车和其他自平衡滑板车的启发后,我一直想要制作一个类似的东西。基于这一点,我决定使用Arduino开发板制作一个自平衡机器人。通过这种方式,我将能够掌握所有这些踏板车背后的基本概念,并了解PID算法的工作原理。


在开始制作后,我意识到这个机器人制作起来有点挑战。有很多可供选择的选项,因而,从选择电机到调整PID值,充满着疑惑。还有许多事情需要考虑,如电池类型、电池位置、车轮把手、电机驱动器类型、维持CoG(重心)等等。


但是,一旦完成后,你会觉得它并不像听起来那么难。让我们开始面对吧,在本篇文章中,我们将主要学习制作自平衡机器人的知识。你可能是一个刚刚开始的纯初学者,或者可能在长时间没有让你的机器人工作的挫折之后来到这里。这个地方旨在成为您的最终目的地。让我们开始吧......


使用的零件

●     Arduino UNO开发板

●     齿轮直流电机(黄色) - 2Nos

●     L298N电机驱动器模块

●     MPU6050

●     一对轮子

●     7.4V锂离子电池

●     连接导线

●     3D打印的车体


控制器:我在这里使用的控制器是Arduino UNO,为什么?因为它简单易用。您也可以使用Arduino Nano或Arduino mini,但我建议您坚持使用UNO,因为我们可以直接编程而无需任何外部硬件。

电机:毫无疑问,您可以使用自平衡机器人的最佳电机选择是步进电机。但为了简单起见,我使用了直流减速电机。是的,没有强制要求步进器;机器人也可以使用这些廉价的黄色直流减速电机。

电机驱动器:如果您选择了像我这样的直流减速电机,那么您可以使用像我这样的L298N驱动模块,甚至L293D应该可以正常工作。

轮子:不要低谷这些家伙;我很难搞清楚问题出在车轮上。因此,请确保您的车轮在您正在使用的地板上有良好的抓地力。仔细观察,你的抓地力永远不应该让你的车轮在地板上滑行。

加速度计和陀螺仪:机器人的加速度计和陀螺仪的最佳选择是MPU6050。因此,不要尝试使用像ADXL345这样的普通加速度计来制作,它不会起作用。在本文的最后你会知道为什么。

电池:我们需要一个尽可能轻的电池,工作电压应大于5V,这样我们就可以直接为Arduino供电而无需升压模块。因此理想的选择是7.4V锂聚合物电池。在这里,由于我有一个7.4V锂离子电池,我已经使用过它了。但请记住,Li-po比Li-ion更有优势。

车体:另一个你不应该忽视的地方是你的机器人车体。您可以使用纸板、木材、塑料制作您喜欢的任何东西。但是,只要确保车体坚固,并且在机器人试图平衡时不应该摆动。我在Solidworks上基于其他机器人设计了自己的车体,并打印出3D。如果您有打印机,那么您也可以打印设计,设计文件将附在下一个标题中。


3D打印和装配机器人

如果您决定使用3D打印我用于构建机器人的相同机箱,则可以从thingiverse下载STL文件。我还添加了设计文件,因此您也可以根据人员偏好进行修改。


这些部件没有悬垂结构,因此您可以在没有任何支撑的情况下轻松打印它们,并且25%的填充物可以正常工作。设计很简单,任何基本打印机都应该能够轻松处理。我使用Cura软件切割模型并使用我的Tevo Tarantula进行打印,设置如下所示。

Manual-Setting-in-Cura-for-Self-Balancing-Robot.png


您需要打印车身部件以及四个电机安装部件。组装非常简单;使用3mm螺母和螺栓将电机和电路板固定到位。组装后,它应该如下图所示。

Assembled-DIY-Self-Balancing-Robot-using-Arduino.jpg


实际设计计划L298N驱动模块在Arduino的底部机架中,以及电池在Arduino的顶部,如上图所示。如果您遵循相同的顺序,您可以通过提供的孔直接拧板,并使用锂电池的电线。这种排列也应该有效,除了我后来不得不改变的超级平轮。


在我的机器人中,我已经更换了电池和Arduino UNO板的位置以便于编程,并且还必须引入一个用于完成连接的穿孔板。所以我的机器人看起来不像我在初期阶段的计划。在完成布线编程测试和一切之后,我的机器人终于看起来像这样了

Circuit-Hardware-for-DIY-Self-Balancing-Robot-using-Arduino.jpg


电路原理图

为这个基于Arduino的自平衡机器人设计连接非常简单。我们只需将MPU6050与Arduino连接,然后通过电机驱动模块连接电机。整个装置由7.4V锂离子电池供电。其电路图如下所示。

Circuit-Diagram-for-DIY-Self-Balancing-Robot-using-Arduino.png


Arduino和L298N电机驱动器模块分别通过Vin引脚和12V端子直接供电。 Arduino板上的板载稳压器将输入7.4V转换为5V,ATmega IC和MPU6050将由它供电。直流电机可以从5V到12V的电压运行。但我们将7.4V正极线从电池连接到电机驱动模块的12V输入端子。这将使电机以7.4V运行。下表列出了MPU6050和L298N电机驱动器模块如何与Arduino连接。

元件引脚
Arduino引脚
MPU6050

VCC
+ 5V
Ground
GND
SCL
A5
SDA
A4
INT
D2
L298N

IN1
D6
IN2
D9
IN3
D10
IN4
D11

MPU6050通过I2C接口与Arduino通信,因此我们使用Arduino的SPI引脚A4和A5。 DC电机分别连接到PWM引脚D6、D9、D10和D11。我们需要将它们连接到PWM引脚,因为我们将通过改变PWM信号的占空比来控制直流电机的速度。

跳转到指定楼层
风筝
发表于: 2018-9-3 23:17:47 | 显示全部楼层

编程自平衡机器人

现在我们需要对Arduino UNO开发板进行编程以平衡机器人。这就是所有神奇魔法发生的地方;它背后的概念很简单。我们需要通过使用MPU6050来检查机器人是否向前倾斜或向后倾斜,然后如果它向前倾斜我们必须向前旋转车轮,如果它向后倾斜我们必须在相反的方向旋转车轮。


同时我们还必须控制车轮旋转的速度,如果机器人从中心位置略微迷失方向,车轮会缓慢旋转,并且当车辆离中心位置越来越远时速度会增加。为了实现这个逻辑,我们使用PID算法,其中心位置为设定点,迷失方向的强度为输出。


要知道机器人的当前位置,我们使用MPU6050,它是一个6轴加速度计和陀螺仪传感器相结合。为了从传感器获得可靠的位置值,我们需要使用加速度计和陀螺仪的值,因为加速度计的值存在噪声问题,陀螺仪的值会随时间漂移。因此,我们必须结合两者并获得我们的机器人的偏航俯仰和滚动的值,其中我们将仅使用偏航的值。


听起来有点头晕吗?但是不用担心,在Arduino社区,我们有现成的库,可以执行PID计算,也可以从MPU6050获得偏航值。该库分别由br3ttbjrowberg开发。在从以下链接下载这些库之前,先将它们添加到您的Arduino lib目录中。

https://github.com/br3ttb/Arduino-PID-Library/blob/master/PID_v1.h

https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050


现在,我们已将库添加到Arduino IDE中。让我们开始为自平衡机器人编程。我们在本页末尾处给出了项目的完整代码,这里我们只是解释代码中最重要的代码片段。在介绍这些代码之前,我们先声明,代码是建立在MPU6050示例代码之上的,我们只是为了目的优化代码,并为我们的自平衡机器人添加PID和控制技术。


首先,我们包括此程序工作所需的库。包括内置I2C库、我们刚刚下载的PID库和MPU6050库。

  1. #include "I2Cdev.h"
  2. #include <PID_v1.h> //From https://github.com/br3ttb/Arduino-PID-Library/blob/master/PID_v1.h
  3. #include "MPU6050_6Axis_MotionApps20.h" //https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050
复制代码

然后我们声明从MPU6050传感器获取数据所需的变量。 我们读取了重力矢量和四元数值,然后计算机器人的偏航俯仰和滚转值。 浮点数组ypr [3]将保存最终结果。

  1. // MPU control/status vars
  2. bool dmpReady = false;  // set true if DMP init was successful
  3. uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
  4. uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
  5. uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
  6. uint16_t fifoCount;     // count of all bytes currently in FIFO
  7. uint8_t fifoBuffer[64]; // FIFO storage buffer

  8. // orientation/motion vars
  9. Quaternion q;           // [w, x, y, z]         quaternion container
  10. VectorFloat gravity;    // [x, y, z]            gravity vector
  11. float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector
复制代码

接下来是代码中非常重要的部分,这是您在调整正确的值集时花费很长时间的地方。 如果您的机器人具有非常好的重心并且组件对称排列(在大多数情况下不是),那么您的设定点的值将为180。否则将您的机器人连接到Arduino串行监视器并将其倾斜直到你找到了一个很好的平衡位置,读取串行监视器上显示的值,这是你的设定值。 Kp、Kd和Ki的值必须根据您的机器人进行调整。 没有两个相同的机器人将具有相同的Kp、Kd和Ki值,因此没有方法避免。

  1. /*********Tune these 4 values for your BOT*********/
  2. double setpoint= 176; //set the value when the bot is perpendicular to ground using serial monitor.
  3. //Read the project documentation on circuitdigest.com to learn how to set these values
  4. double Kp = 21; //Set this first
  5. double Kd = 0.8; //Set this secound
  6. double Ki = 140; //Finally set this
  7. /******End of values setting*********/
复制代码

在接下来的代码中,我们通过传递输入变量输入、输出、设定点、Kp、Ki和Kd来初始化PID算法。 其中我们已经在上面的代码片段中设置了设定点Kp、Ki和Kd的值。 输入值将是从MPU6050传感器读取的偏航的当前值,输出值将是PID算法计算的值。 因此,基本上PID算法将为我们提供一个输出值,该输出值应该用于将输入值校正为接近设定点。

  1. PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);
复制代码

void setup()函数中,我们通过配置DMP(数字运动处理器)初始化MPU6050。 这将有助于我们将加速度计数据与陀螺仪数据相结合,并提供可靠的偏航、俯仰和滚转值。 我们不会深入研究这一点,因为它远远超出了主题。 无论如何,您必须在setup函数中查找的一段代码是陀螺仪偏移值。 每个MPU6050传感器都有自己的偏移值,您可以使用此Arduino草图计算传感器的偏移值,并在程序中相应更新以下行。

  1.     // supply your own gyro offsets here, scaled for min sensitivity
  2.     mpu.setXGyroOffset(220);
  3.     mpu.setYGyroOffset(76);
  4.     mpu.setZGyroOffset(-85);
  5.     mpu.setZAccelOffset(1688);
复制代码

我们还必须初始化我们用来连接电机的数字PWM引脚。 在我们的例子中,使用的是D6、D9、D10和D11。 因此我们初始化这些引脚为输出引脚,默认为低电平。

  1. //Initialise the Motor outpu pins
  2.     pinMode (6, OUTPUT);
  3.     pinMode (9, OUTPUT);
  4.     pinMode (10, OUTPUT);
  5.     pinMode (11, OUTPUT);

  6. //By default turn off both the motors
  7.     analogWrite(6,LOW);
  8.     analogWrite(9,LOW);
  9.     analogWrite(10,LOW);
  10.     analogWrite(11,LOW);
复制代码

loop函数内部,我们检查MPU6050的数据是否可以读取。 如果是,则我们使用它来计算PID值,然后在串行监视器上显示PID的输入和输出值,以检查PID的响应方式。 然后根据输出值我们决定机器人是向前还是向后移动还是静止不动。


因为我们假设当机器人直立时MPU6050将返回180。 当机器人向前倾斜时,我们将获得正值校正值,如果机器人向后倾斜,我们将得到负值。 所以我们检查这个条件并调用相应的函数来移动机器人前进或后退。

  1.     while (!mpuInterrupt && fifoCount < packetSize)
  2.     {
  3.         //no mpu data - performing PID calculations and output to motors   
  4.         pid.Compute();  
  5.       
  6.         //Print the value of Input and Output on serial monitor to check how it is working.
  7.         Serial.print(input); Serial.print(" =>"); Serial.println(output);
  8.               
  9.         if (input>150 && input<200){//If the Bot is falling
  10.          
  11.         if (output>0) //Falling towards front
  12.         Forward(); //Rotate the wheels forward
  13.         else if (output<0) //Falling towards back
  14.         Reverse(); //Rotate the wheels backward
  15.         }
  16.         else //If Bot not falling
  17.         Stop(); //Hold the wheels still
  18.     }
复制代码

PID输出变量还决定了电机旋转的速度。 如果机器人即将摔倒,那么我们通过缓慢旋转车轮进行微小修正。 如果这些小的校正工作仍然有效,但如果机器人跌落,我们会提高电机的速度。 车轮旋转的速度值将由PI算法决定。 请注意,对于Reverse函数,我们将输出值乘以-1,以便我们可以将负值转换为正值。

  1. void Forward() //Code to rotate the wheel forward
  2. {
  3.     analogWrite(6,output);
  4.     analogWrite(9,0);
  5.     analogWrite(10,output);
  6.     analogWrite(11,0);
  7.     Serial.print("F"); //Debugging information
  8. }

  9. void Reverse() //Code to rotate the wheel Backward
  10. {
  11.     analogWrite(6,0);
  12.     analogWrite(9,output*-1);
  13.     analogWrite(10,0);
  14.     analogWrite(11,output*-1);
  15.    Serial.print("R");
  16. }

  17. void Stop() //Code to stop both the wheels
  18. {
  19.     analogWrite(6,0);
  20.     analogWrite(9,0);
  21.     analogWrite(10,0);
  22.     analogWrite(11,0);
  23.     Serial.print("S");
  24. }
复制代码
回复

使用道具 举报

风筝
发表于: 2018-9-3 23:26:01 | 显示全部楼层

Arduino自平衡机器人的工作过程

DIY-Self-Balancing-Robot-in-action.jpg


准备好硬件后,可以将代码上传到Arduino开发板。确保连接正确,因为我们使用的是锂离子电池,需要特别小心。因此,请仔细检查是否存在短路,并确保即使您的机器人遇到一些小的影响,端子也不会短接。启动模块并打开串行监视器,如果您的Arduino可以成功与MPU6050通信,并且如果一切正常,您应该看到以下界面。

Communication-Between-Arduino-and-MPU6050.png


在这里,我们以input => output格式看到PID算法的输入和输出值。如果机器人完全平衡,输出值将为0。输入值是MPU6050传感器的当前值。字母“F”表示机器人向前移动,“R”表示机器人向后移动。


在PID的初始阶段,我建议将Arduino电缆连接到机器人,这样您就可以轻松监控输入和输出的值,并且很容易纠正并上传您的程序的Kp、Ki和Kd值。


希望本文有助于制作自己的自平衡机器人,如果你在制作过程种遇到任何问题,请将你的问题回复本帖。


代码

以下是本篇文章使用的完整代码: main.rar (2.63 KB, 下载次数: 135)

回复

使用道具 举报

driver
发表于: 2018-10-22 22:39:50 | 显示全部楼层

你好,这是一个很棒的项目,但我在制作时,卡在了PID参数调试上,麻烦提供下方向(看不了youtube的视频)。不胜感激
回复

使用道具 举报

风筝
发表于: 2018-10-24 22:16:54 | 显示全部楼层

driver 发表于 2018-10-22 22:39
你好,这是一个很棒的项目,但我在制作时,卡在了PID参数调试上,麻烦提供下方向(看不了youtube的视频)。 ...

这个项目的难点就在于PID参数的调节上,不同的结构和齿轮,参数不一样。甚至于同一批的自平衡机器人,参数也会不一样。可以加个QQ好友细聊。
回复

使用道具 举报

xiaobai
发表于: 2019-8-12 15:41:05 | 显示全部楼层

请问  此Arduino草图计算传感器的偏移值  时,显示陀螺仪已经连接成功,但是串口只输出...  ...  ...是什么原因,此时arduino uno只连了陀螺仪
回复

使用道具 举报

hacker_Dx
发表于: 2019-8-16 12:29:41 | 显示全部楼层

L298N的速度控制不是使用EN吗?我看到您的设计直接对控制信号IN进行输出,这个应该是不可以的吧
回复

使用道具 举报

xiaobai
发表于: 2019-8-22 10:05:48 | 显示全部楼层

[img][/img]显示陀螺仪连接成功,但一直显示...
回复

使用道具 举报

xiaobai
发表于: 2019-8-22 10:07:27 | 显示全部楼层

C:\Users\Administrator\Desktop
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 377 | 回复: 685



手机版|

GMT+8, 2019-10-21 23:24 , Processed in 0.171877 second(s), 31 queries . Powered by Discuz! X3.4

YiBoard一板网 © 2015-2018 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表