极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: pww999

arduino摇控平衡车m2560+mpu6050+24l01 (已上传代码包)

  [复制链接]
发表于 2012-12-27 20:21:48 | 显示全部楼层
{:soso_e154:}{:soso_e154:}楼主的小车现在是什么情况了
回复 支持 反对

使用道具 举报

发表于 2013-1-13 13:44:46 | 显示全部楼层
pww999 发表于 2012-12-26 12:28
1楼已上传 I2Cdev包,解压后放到arduino-1.0.1\libraries 里面

另外上传了一个压缩包,里面包含了现时比 ...

多谢,问题解决了,但是下载到2560上,串口监视窗口没有数据产生,空白一片,没动静。
mpu-------arduino m2560
VIN--------
VCC--------3.3v
XDA-------
XCL-------
ADD-------GND
INT--------
SDA------A4
SCL-------A5
GND------GND
这样连接对吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-1-14 17:48:31 | 显示全部楼层
九元 发表于 2013-1-13 13:44
多谢,问题解决了,但是下载到2560上,串口监视窗口没有数据产生,空白一片,没动静。
mpu-------arduin ...

2560 有专用的 SDA SCL 接口,你查一下2560的原理图就行
回复 支持 反对

使用道具 举报

发表于 2013-1-14 19:38:14 | 显示全部楼层
pww999 发表于 2013-1-14 17:48
2560 有专用的 SDA SCL 接口,你查一下2560的原理图就行

谢了~接口解决了,又出现这个问题,以前下载没问题的
未命名0000000000000000.jpg
回复 支持 反对

使用道具 举报

发表于 2013-1-31 12:11:53 | 显示全部楼层
咨询FreeWay两轮平衡车(无刷电机+锂电池)
QQ:695118363
回复 支持 反对

使用道具 举报

发表于 2013-3-6 18:06:38 | 显示全部楼层
您好 ,请问下
kp = analogRead(8)*0.03;
ki = analogRead(9)*0.0002;
kd = analogRead(10)*1;
这是什么意思,您说是电位器取值....,我没明白您的意思,板子不加电位器 kp ki kd 应该写什么呢


谢谢
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-3-6 20:05:45 | 显示全部楼层
这个可调电阻采0-1024模拟量,如果不加的话,可以在 kp=0.03*500 每次递加或递减 5 调节,,.......
这样调节相当麻烦,最好还是加几个可调电阻方便调整 PID 参数
回复 支持 反对

使用道具 举报

发表于 2013-3-7 08:31:19 | 显示全部楼层

哦 明白了好的谢谢
回复 支持 反对

使用道具 举报

发表于 2013-3-7 08:34:00 | 显示全部楼层
kp=0.03*500 每次递加或递减 5 调节----ki 、kd 也是*500 每次递加或递减 5调节吧
回复 支持 反对

使用道具 举报

发表于 2013-3-11 09:33:19 | 显示全部楼层
楼主您好,请教一下您的PIDD中的 PID算法 为什么是                                LOutput=Output+RSpeed_Need;
ROutput=Output-RSpeed_Need;

这怎么理解啊?
请教大牛,帮忙解释下
回复 支持 反对

使用道具 举报

发表于 2013-3-17 18:45:41 | 显示全部楼层
之前在论坛上看到了“pww999”大神的自平衡小车,于是想弄辆试试,因为之前没有接出过arduino,制作过程中也碰到不少的问题,从师兄那弄来了Apc220模块,自己买了两块扩展板,l298p和v5扩展板。结合之前的看的《arduino开发实战指南》,于是改了一下楼主的代码,想用Apc220 控制,可是上电后,两电机只会往相反方向转,遥控就更不起作用了。。在检验跟下载时都没有出现问题,心顿时凉了一半。。
请问论坛上有哪位大神用过这模块或者弄过自平衡小车的,能抽空帮菜鸟看一下代码,不胜感激。。。


#include "Wire.h"
#include "SPI.h"  
#include "I2Cdev.h"
#include "MPU6050.h"

//--------MPU6050参数
MPU6050 accelgyro;
int16_t ax, ay, az;
int16_t gx, gy, gz;
#define Gry_offset -20     // 陀螺仪偏移量
#define Gyr_Gain 0.00763358    //对应的1G
#define pi 3.14159

//---------PID控制器参数
float kp, ki, kd,kpp;
float angleA,omega;
float LOutput,ROutput;

float LSpeed_Need=0.0,RSpeed_Need=0.0;
int data,adata;

  unsigned long now;
unsigned long preTime = 0;
float SampleTime = 0.08;  //-------------------互补滤波+PID 采样时间0.08 s
unsigned long lastTime;
float Input, Output, Setpoint;
float errSum,dErr,error,lastErr,f_angle;
int timeChange;

/*----------l298接m2560引脚,因为用的是扩展板l298p,
E1        M1                                
L        X        电机1控制禁止
H        H        电机1反转
H        L        电机1正转
PWM        X        对电机1调速

E2        M2        
L        X        电机2控制禁止
H        H        电机2反转
H        L        电机2正转
PWM        X        对电机2调速*/

int E1 = 5;   
int M1 = 4;
int E2 = 6;                        
int M2 = 7;
int comtemp;  //定义一个变量来储存串口APC220收到的数据
void setup()
{
Wire.begin();
Serial.begin(9600);
accelgyro.initialize();
delay(100);

  pinMode(M1, OUTPUT);   
  pinMode(M2, OUTPUT);
  pinMode(E1, OUTPUT);
  pinMode(E2, OUTPUT);
  delay(100);
  Serial.begin(9600);
}
void loop()
{ if ( Serial.available() )   //接受电脑串口的数据
    comtemp= Serial.read();
    switch(comtemp)
    {case 'w':                 //前进
              {LSpeed_Need=4;
              RSpeed_Need=4;}
              break;
     case 's':                 //后退
              {LSpeed_Need=-4;
               RSpeed_Need=-4;}
              break;
     case 'q':                  //左转
            {RSpeed_Need=18;}
              break;
     case 'e':                  //右转
              {LSpeed_Need=18;}
              break;
     case 't':                  //停止
             {LSpeed_Need=0;
              RSpeed_Need=0;
              Setpoint;}
              break;  
     defaut: {LSpeed_Need=0;    //否则也停止
              RSpeed_Need=0;
              Setpoint;}
              break;    }
              
    //下面的就跟pww99大神的代码。。。         
   // if (abs(angleA>38)){LSpeed_Need*=0.6;RSpeed_Need*=0.6;}
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  //------------------------------------------------------------------------
  angleA= atan2(ay , az) * 180 / pi+0.5;   // 根据加速度分量得到的角度(degree)加0.5偏移量
  //180度至0至-180(360度)取0度为坚直时中立点 因为坚直时有偏差,所以加0.5....
  omega=  Gyr_Gain * (gx +  Gry_offset); // 当前角速度(degree/s)

  if (abs(angleA)<45) {    // 角度小于45度 运行程序

PIDD();//---------------------互补滤波+PID--------------------------

PWMB(); //----------------------PWM调速输出--------------------------

delay(3);
   }
    else {      // 角度大于45度 停止PWM输出
analogWrite(E1, 0); //两电机调速端口结合自己的电机驱动板改了下..
analogWrite(E2, 0);        
  }
}


  void  PIDD(){
      kp = analogRead(8)*0.03; //取0~1024*  (这些值是小车调试后得出,请按自己小车调试后修改)
ki = analogRead(9)*0.0002;//取0~1024* .........
kd = analogRead(10)*1;  //取0~1024* .........
//kpp = analogRead(11)*0.005;
    //------------------互补滤波 ------------------------
  unsigned long now = millis();                           // 当前时间(ms)
    float dt = (now - preTime) / 1000.0;                    // 微分时间(ms)
    preTime = now;  
    float K = 0.8;                    
    float A = K / (K + dt);                    
   f_angle = A * (f_angle + omega * dt) + (1-A) * angleA;  // 互补滤波算法
//----------------------------PID控制器 ------------------------------
  //now = millis();
   timeChange = (now - lastTime);
   if(timeChange>=SampleTime)
   {
     Setpoint=LSpeed_Need;// =0,(+ -值使电机前进或后退)
        Input =f_angle;
      error = Setpoint- Input;
      errSum += error* timeChange;
      dErr = (error - lastErr)/ timeChange;
//PID Output
      Output = kp * error + ki * errSum + kd * dErr;
LOutput=Output+RSpeed_Need;//左电机
ROutput=Output-RSpeed_Need;//右电机
      lastErr = error;
      lastTime = now;
   }
   //  Serial.print(angleA); Serial.print("\t");
    //   Serial.print(omega);Serial.print("\t");
   // Serial.print(f_angle); Serial.print("\t");
    ///  Serial.println(Output);
}

void PWMB(){
  if(LOutput>0.3)//左电机-------或者取0
{ digitalWrite(M1,HIGH);}

else if(LOutput<-0.3)//-------或者取0
{ digitalWrite(M1,LOW); }   

  else  //刹车-------取0后可以不用
{ digitalWrite(M1,0);}

if(ROutput>0.3)//右电机--------或者取0
{  digitalWrite(M2,LOW); }

else if(ROutput<-0.3)//-------或者取0
{  digitalWrite(M2,HIGH); }

else  //刹车-------取0后可以不用
{ digitalWrite(M1,0);}
analogWrite(E1,min(255,abs(LOutput)+25)); //PWM调速a==0-255
analogWrite(E2,min(255,abs(ROutput)+23));
}
回复 支持 反对

使用道具 举报

发表于 2013-3-17 21:06:27 | 显示全部楼层
楼主 的卡尔曼  中 貌似 没有把测得数据给 void Kalman_Filter(double angle_m,double gyro_m)中两个参数
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-3-23 22:02:00 | 显示全部楼层
raphaelhhq 发表于 2013-3-17 18:45
之前在论坛上看到了“pww999”大神的自平衡小车,于是想弄辆试试,因为之前没有接出过arduino,制作过程中也 ...

先将apc220实验发送接能正常工作,
车子调试能站起来了,
最结合一起
一步步来,
回复 支持 反对

使用道具 举报

发表于 2013-3-24 10:48:31 | 显示全部楼层
嗯,感谢。现在有点进展了,请问楼主能详细解释一下,
analogWrite(E1,min(255,abs(LOutput)+25));
min ,255分别是指什么意思吗?因为模拟参量修改不是很懂,
看书曾介绍过摇杆向上的模拟参量和向下的参量计算公式,但到传感器这就懵了,电机驱动板需要,这计算数据,公式一定得改。。。我想弄懂这句话啊!!!不胜感激。
回复 支持 反对

使用道具 举报

发表于 2013-3-25 11:40:56 | 显示全部楼层
raphaelhhq 发表于 2013-3-24 10:48
嗯,感谢。现在有点进展了,请问楼主能详细解释一下,
analogWrite(E1,min(255,abs(LOutput)+25));
min  ...

我替楼主回答,不正确请拍砖。
在arduino用pmw控制电机输出值范围在0~255,这里min函数就是限定输出值不要超过255。
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊 ( 浙ICP备09023225号 )

GMT+8, 2020-7-4 00:02 , Processed in 0.077851 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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