极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11413|回复: 3

平衡小车轮子只会往一个方向转

[复制链接]
发表于 2015-10-2 21:28:38 | 显示全部楼层 |阅读模式
各位大神,我用arduino nano+mpu6050+l298n做一个平衡小车,结果小车的轮子只会往一个方向转,这是什么原因?
  1. #include "PID_v1.h"
  2. #include "Wire.h"
  3. #include "I2Cdev.h"
  4. #include "MPU6050_6Axis_MotionApps20.h"
  5. MPU6050 mpu(0x68);

  6. #define center  0x7F

  7. char flag=0;
  8. char num=0;
  9. double time;
  10. signed int speeds = 0;
  11. signed int oldspeed =0;
  12. byte inByte ;
  13. // MPU control/status vars
  14. bool dmpReady = false;   
  15. uint8_t mpuIntStatus;
  16. uint8_t devStatus;   
  17. uint16_t packetSize;   
  18. uint16_t fifoCount;   
  19. uint8_t fifoBuffer[64];  

  20. signed int speedcount=0;
  21.   
  22. // orientation/motion vars
  23. Quaternion q;           // [w, x, y, z]         quaternion container
  24. VectorFloat gravity;    // [x, y, z]            gravity vector
  25. float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector
  26. float angle;
  27. double Setpoint, Input, Output;
  28. double kp = 21,ki = 450,kd = 0.8;//需要你修改的参数

  29. double Setpoints, Inputs, Outputs;
  30. double sp = 0.8,si = 0.8,sd = 0.55;//需要你修改的参数

  31. unsigned char dl=17,count;

  32. union{
  33.         signed int all;
  34.         unsigned char s[2];
  35. }data;
  36.    

  37. volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
  38. void dmpDataReady() {
  39.   mpuInterrupt = true;
  40. }
  41. PID myPID(&Input, &Output, &Setpoint,kp,ki,kd, DIRECT);

  42. PID sPID(&Inputs, &Outputs, &Setpoints,sp,si,sd, DIRECT);

  43. void motor(int v)
  44. {
  45.   if(v>0)
  46.   {
  47.     v+=dl;
  48.     digitalWrite(6,0);
  49.     digitalWrite(7,1);
  50.     digitalWrite(8,1);
  51.     digitalWrite(9,0);   
  52.     analogWrite(10,v);
  53.     analogWrite(11,v);
  54.   }
  55.   else if(v<0)
  56.   {
  57.     v=-v;
  58.     v+=dl;
  59.     digitalWrite(6,1);
  60.     digitalWrite(7,0);
  61.     digitalWrite(8,0);
  62.     digitalWrite(9,1);   
  63.     analogWrite(10,v);
  64.     analogWrite(11,v);
  65.   }
  66.   else
  67.   {
  68.     analogWrite(10,0);
  69.     analogWrite(11,0);  
  70.   }
  71. }

  72. void motort(int v)
  73. {
  74.   if(v>0)
  75.   {
  76.     v+=dl;
  77.     digitalWrite(8,1);
  78.     digitalWrite(9,0);
  79.     analogWrite(10,v);
  80.   }
  81.   else if(v<0)
  82.   {
  83.     v=-v;
  84.     v+=dl;
  85.     digitalWrite(8,0);
  86.     digitalWrite(9,1);  
  87.     analogWrite(10,v);
  88.   }
  89.   else
  90.   {
  91.     analogWrite(10,0);
  92.   }
  93. }

  94. void setup()
  95. {
  96.   pinMode(6,OUTPUT);
  97.   pinMode(7,OUTPUT);
  98.   pinMode(8,OUTPUT);
  99.   pinMode(9,OUTPUT);
  100.   pinMode(10,OUTPUT);
  101.   pinMode(11,OUTPUT);
  102.   digitalWrite(6,0);
  103.   digitalWrite(7,1);
  104.   digitalWrite(8,1);
  105.   digitalWrite(9,0);
  106.   analogWrite(10,0);
  107.   analogWrite(11,0);
  108.   Serial.begin(115200);
  109.   Wire.begin();

  110.   delay(100);
  111.    
  112.   Serial.println("Initializing I2C devices...");
  113.   mpu.initialize();
  114.   Serial.println("Testing device connections...");
  115.   Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
  116.   delay(2);
  117.   Serial.println("Initializing DMP...");
  118.   devStatus = mpu.dmpInitialize();
  119.   if (devStatus == 0)
  120.   {
  121.     Serial.println("Enabling DMP...");
  122.     mpu.setDMPEnabled(true);
  123.     Serial.println("Enabling interrupt detection (Arduino external interrupt 0)...");
  124.     attachInterrupt(0, dmpDataReady, RISING);
  125.     mpuIntStatus = mpu.getIntStatus();
  126.     Serial.println("DMP ready! Waiting for first interrupt...");
  127.     dmpReady = true;
  128.     packetSize = mpu.dmpGetFIFOPacketSize();
  129.   }
  130.   else
  131.   {
  132.     Serial.print("DMP Initialization failed (code ");
  133.     Serial.print(devStatus);
  134.     Serial.println(")");
  135.   }
  136.    
  137.   Setpoint = -10.2;
  138.   myPID.SetTunings(kp,ki,kd);
  139.   myPID.SetOutputLimits(-255+dl,255-dl);
  140.   myPID.SetSampleTime(5);
  141.   myPID.SetMode(AUTOMATIC);

  142.   sPID.SetTunings(sp,si,sd);
  143.   sPID.SetOutputLimits(-10,70);
  144.   sPID.SetSampleTime(200);
  145.   sPID.SetMode(AUTOMATIC);


  146.   attachInterrupt(1,speed,RISING);
  147. }
  148.   
  149. void loop()
  150. {
  151.   if (!dmpReady)
  152.     return;
  153.   // wait for MPU interrupt or extra packet(s) available
  154.   if (!mpuInterrupt && fifoCount < packetSize)
  155.     return;
  156.   mpuInterrupt = false;
  157.   mpuIntStatus = mpu.getIntStatus();
  158.   fifoCount = mpu.getFIFOCount();
  159.   if ((mpuIntStatus & 0x10) || fifoCount == 1024)
  160.   {
  161.    mpu.resetFIFO();
  162.   }
  163.   else if (mpuIntStatus & 0x02)
  164.   {
  165.      while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
  166.      mpu.getFIFOBytes(fifoBuffer, packetSize);
  167.      fifoCount -= packetSize;
  168.      mpu.dmpGetQuaternion(&q, fifoBuffer);
  169.      mpu.dmpGetGravity(&gravity, &q);
  170.      mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);  //从DMP中取出Yaw、Pitch、Roll三个轴的角度,放入数组ypr。单位:弧度
  171.      angle=-ypr[1] * 180/M_PI;
  172.   }


  173.   Inputs = speedcount;
  174.    sPID.Compute();

  175.     Setpoint = -10.2+Outputs;

  176.   Input = angle;
  177.   myPID.Compute();
  178.    
  179.   if(angle>60||angle<0)
  180.   Output=0;
  181.   if(flag)
  182.   {
  183.   motort(Output);
  184.   flag=0;
  185.   }
  186.   else {
  187.         motor(Output);
  188.          
  189.   }
  190.    
  191.   if (Serial.available() > 0) {
  192.     inByte = Serial.read();
  193.   }
  194.   if(inByte == 'w'){
  195.   kp+=0.5;}
  196.   else if(inByte == 'q'){
  197.   kp-=0.5;}
  198.   else if(inByte == 'r'){
  199.   ki+=10;}
  200.   else if(inByte == 'e'){
  201.   ki-=10;}
  202.   else if(inByte == 'y'){
  203.   kd+=0.01;}
  204.   else if(inByte == 't'){
  205.   kd-=0.01;}
  206.   else if(inByte == 'i'){
  207.   dl+=1;}
  208.   else if(inByte == 'u'){
  209.   dl-=1;}
  210.   else if(inByte == 's'){
  211.   sp+=0.1;}
  212.   else if(inByte == 'a'){
  213.   sp-=0.1;}
  214.    else if(inByte == 'f'){
  215.   si+=1;}
  216.   else if(inByte == 'd'){
  217.   si-=1;}
  218.    else if(inByte == 'h'){
  219.   sd+=0.01;}
  220.   else if(inByte == 'g'){
  221.   sd-=0.01;}
  222.   else if(inByte == 'v'){
  223.   Setpoints+=0.7;}
  224.   else if(inByte == 'b'){
  225.   Setpoints-=0.7;}
  226.   else if(inByte == '1'){
  227.   Setpoints+=0.2;}
  228.   else if(inByte == '2'){
  229.   Setpoints-=0.2;}
  230.   else if(inByte == 'n'){
  231.   Setpoints+=2;
  232.   flag=1;}
  233.   else if(inByte == 'm'){
  234.   Setpoints-=2;
  235.   flag=1;}
  236.   
  237.   inByte='x';
  238.   
  239.   sPID.SetTunings(sp,si,sd);  
  240.   myPID.SetTunings(kp,ki,kd);  

  241.   num++;
  242.   if(num==20)
  243.   {num=0;
  244.   Serial.print(kp);
  245.   Serial.print(',');
  246.   Serial.print(ki);
  247.   Serial.print(',');
  248.   Serial.print(kd);
  249.   Serial.print(',');
  250.   Serial.print(dl);
  251.   Serial.print("  ");
  252.   Serial.print(sp);
  253.   Serial.print(',');
  254.   Serial.print(si);
  255.   Serial.print(',');
  256.   Serial.print(sd);
  257.    Serial.print(',');
  258.   Serial.println(angle);
  259.   }

  260. }



  261. void speed()
  262. {
  263.         if(digitalRead(6)){
  264.         speedcount+=1;
  265.         }
  266.         else
  267.         speedcount-=1;
  268. }
复制代码
回复

使用道具 举报

发表于 2015-10-3 08:35:44 | 显示全部楼层
控制两个车轮速度,它就会左转右转
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-10-3 15:02:00 | 显示全部楼层
suoma 发表于 2015-10-3 08:35
控制两个车轮速度,它就会左转右转

怎么控制?麻烦提示一下,我是超级新手
回复 支持 反对

使用道具 举报

发表于 2015-10-3 22:35:08 | 显示全部楼层
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-16 12:47 , Processed in 0.054392 second(s), 18 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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