pwm 无法调节电机速度
我用电机控制板LN298 驱动电机,接线不用说了,很简单。程序如下://=================motor=======================
//Motor A
int PWMA = 9; //Speed control
int Left_1 = 8; //Direction
int Left_2 = 7; //Direction
//Motor B
int PWMB = 10; //Speed control
int Right_1 = 6; //Direction
int Right_2 = 5; //Direction
int PWMA_Start=30;
int PWMB_Start=30;
//=========================================================
。。。中间省略
void motor_move(int dir,int PWMA_VAL,int PWMB_VAL)//当 dir=1,表示前进,当 dir=2表示 后退 //
{
switch(dir){
case 1://当 dir=1,表示前进//
digitalWrite (Left_1,HIGH);
digitalWrite(Left_2,LOW);
analogWrite(PWMA,PWMA_VAL);
digitalWrite (Right_1,HIGH);
digitalWrite(Right_2,LOW);
analogWrite(PWMB,PWMB_VAL);
break;
case 2://backward
digitalWrite (Left_1,LOW);
digitalWrite(Left_2,HIGH);
analogWrite(PWMA,PWMA_VAL);
digitalWrite (Right_1,LOW);
digitalWrite(Right_2,HIGH);
analogWrite(PWMB,PWMB_VAL);
break;
case 3://turn left
digitalWrite (Left_1,HIGH);
digitalWrite(Left_2,LOW);
analogWrite(PWMA,PWMA_VAL);
digitalWrite (Right_1,LOW);
digitalWrite(Right_2,HIGH);
analogWrite(PWMB,PWMB_VAL);
break;
case 4://turn right
digitalWrite (Left_1,LOW);
digitalWrite(Left_2,HIGH);
analogWrite(PWMA,PWMA_VAL);
digitalWrite (Right_1,HIGH);
digitalWrite(Right_2,LOW);
analogWrite(PWMB,PWMB_VAL);
break;
case 5://stop
digitalWrite (Left_1,HIGH);
digitalWrite(Left_2,HIGH);
analogWrite(PWMA,PWMA_VAL);
digitalWrite (Right_1,HIGH);
digitalWrite(Right_2,HIGH);
analogWrite(PWMB,PWMB_VAL);
break;
}
}
但是改变PWM值无法调节速度,不知道什么原因,有人遇到过吗?有解决办法吗?帮忙看看是不是程序的问题。 #include <I2Cdev.h>
#include <MPU6050.h>
#include <Wire.h>
#include <stdlib.h>
//=================motor=======================
//Motor A
int PWMA = 9; //Speed control
int Left_1 = 8; //Direction
int Left_2 = 7; //Direction
//Motor B
int PWMB = 10; //Speed control
int Right_1 = 6; //Direction
int Right_2 = 5; //Direction
int PWMA_Start=30;
int PWMB_Start=30;
//=========================================================
MPU6050 accelgyro;
unsigned long now, lastTime = 0;
float dt; //微分时间
int16_t ax, ay, az, gx, gy, gz; //加速度计陀螺仪原始数据
float aax=0, aay=0, agx=0, agy=0, agz=0; //角度变量
long axo = 0, ayo = 0, azo = 0; //加速度计偏移量
long gxo = 0, gyo = 0, gzo = 0; //陀螺仪偏移量
float pi = 3.1415926;
float AcceRatio = 16384.0; //加速度计比例系数
float GyroRatio = 131.0; //陀螺仪比例系数
uint8_t n_sample = 8; //加速度计滤波算法采样个数
float aaxs = {0}, aays = {0}; //x,y轴采样队列
long aax_sum, aay_sum; //x,y轴采样和
float a_x={0},a_y={0},g_x={0},g_y={0};//加速度计协方差计算队列
float Px=1, Rx, Kx, Sx, Vx, Qx; //x轴卡尔曼变量
float Py=1, Ry, Ky, Sy, Vy, Qy; //y轴卡尔曼变量
////=================加入串口通信代码调试==========================
void setup(){
Wire.begin();
Serial.begin(38400);
//====================motor_setting===================
pinMode(PWMA, OUTPUT);
pinMode(Left_1, OUTPUT);
pinMode(Left_2, OUTPUT);
pinMode(PWMB, OUTPUT);
pinMode(Right_1, OUTPUT);
pinMode(Right_2, OUTPUT);
//======================================================
accelgyro.initialize(); //初始化
unsigned short times = 100; //采样次数
for(int i=0;i<times;i++){
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); //读取六轴原始数值
axo += ax; ayo += ay; azo += az; //采样和
gxo += gx; gyo += gy; gzo += gz;
}
axo /= times; ayo /= times; azo /= times; //计算加速度计偏移
gxo /= times; gyo /= times; gzo /= times; //计算陀螺仪偏移
}
void loop(){
unsigned long now = millis(); //当前时间(ms)
dt = (now - lastTime) / 1000.0; //微分时间(s)
lastTime = now; //上一次采样时间(ms)
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);//读取六轴原始数值
float accx = ax / AcceRatio; //x轴加速度
float accy = ay / AcceRatio; //y轴加速度
float accz = az / AcceRatio; //z轴加速度
aax = atan(accy / accz) * (-180) / pi;//x轴对于水平面的夹角
aay = atan(accx / accz) * 180 / pi; //y轴对于水平面的夹角
aax_sum = 0; // 对于加速度计原始数据的滑动加权滤波算法
aay_sum = 0;
for(int i=1;i<n_sample;i++){
aaxs = aaxs;
aax_sum += aaxs * i;
aays = aays;
aay_sum += aays * i;
}
aaxs = aax;
aax_sum += aax * n_sample;
aax = (aax_sum / (11*n_sample/2.0)) * 9 / 7.0; //角度调幅至0-90°
aays = aay; //此处应用实验法取得合适的系数
aay_sum += aay * n_sample; //本例系数为9/7
aay = (aay_sum / (11*n_sample/2.0)) * 9 / 7.0;
float gyrox = - (gx-gxo) / GyroRatio * dt; //x轴角速度
float gyroy = - (gy-gyo) / GyroRatio * dt; //y轴角速度
agx += gyrox; //x轴角速度积分
agy += gyroy; //x轴角速度积分
/* kalmen start */
Sx = 0; Rx = 0;
Sy = 0; Ry = 0;
for(int i=1;i<10;i++){ //测量值平均值运算
a_x = a_x; //即加速度平均值
Sx += a_x;
a_y = a_y;
Sy += a_y;
}
a_x = aax;
Sx += aax;
Sx /= 10; //x轴加速度平均值
a_y = aay;
Sy += aay;
Sy /= 10; //y轴加速度平均值
for(int i=0;i<10;i++){
Rx += sq(a_x - Sx);
Ry += sq(a_y - Sy);
}
Rx = Rx / 9; //得到方差
Ry = Ry / 9;
Px = Px + 0.0025; // 0.0025在下面有说明...
Kx = Px / (Px + Rx); //计算卡尔曼增益
agx = agx + Kx * (aax - agx); //陀螺仪角度与加速度计速度叠加
Px = (1 - Kx) * Px; //更新p值
Py = Py + 0.0025;
Ky = Py / (Py + Ry);
agy = agy + Ky * (aay - agy);
Py = (1 - Ky) * Py;
/* kalmen end */
Serial.print(agx);Serial.print(",");
Serial.print(agy);Serial.println();
if(-3<agy){
motor_move(1,PWMA_Start,PWMA_Start);
}
else if(-4.0>agy){
motor_move(2,PWMA_Start,PWMB_Start);
}
else
{
motor_move(5,0,0);
}
}
//============================motor function========================
void motor_move(int dir,int PWMA_VAL,int PWMB_VAL)//当 dir=1,表示前进,当 dir=2表示 后退 //
{
switch(dir){
case 1://当 dir=1,表示前进//
digitalWrite (Left_1,HIGH);
digitalWrite(Left_2,LOW);
analogWrite(PWMA,PWMA_VAL);
digitalWrite (Right_1,HIGH);
digitalWrite(Right_2,LOW);
analogWrite(PWMB,PWMB_VAL);
break;
case 2://backward
digitalWrite (Left_1,LOW);
digitalWrite(Left_2,HIGH);
analogWrite(PWMA,PWMA_VAL);
digitalWrite (Right_1,LOW);
digitalWrite(Right_2,HIGH);
analogWrite(PWMB,PWMB_VAL);
break;
case 3://turn left
digitalWrite (Left_1,HIGH);
digitalWrite(Left_2,LOW);
analogWrite(PWMA,PWMA_VAL);
digitalWrite (Right_1,LOW);
digitalWrite(Right_2,HIGH);
analogWrite(PWMB,PWMB_VAL);
break;
case 4://turn right
digitalWrite (Left_1,LOW);
digitalWrite(Left_2,HIGH);
analogWrite(PWMA,PWMA_VAL);
digitalWrite (Right_1,HIGH);
digitalWrite(Right_2,LOW);
analogWrite(PWMB,PWMB_VAL);
break;
case 5://stop
digitalWrite (Left_1,HIGH);
digitalWrite(Left_2,HIGH);
analogWrite(PWMA,PWMA_VAL);
digitalWrite (Right_1,HIGH);
digitalWrite(Right_2,HIGH);
analogWrite(PWMB,PWMB_VAL);
break;
}
}
//==================================================================程序参考了别人的,具体名字忘了,在此谢过。
这个只是用了其中一个轴,实际上有些代码可以省略,没有去改,只是用角度控制,但是没有用到PID计算设定电机速度,车子站立后抖动厉害,速度无法调节是很大原因,过调严重。速度是按最大值输出的,不知道什么原因导致PWM调节失效。 應檢查以下的 dir ,PWMA 及 PWMB 的傳來值是否正確。
void motor_move(int dir,int PWMA_VAL,int PWMB_VAL)//当 dir=1,表示前进,当 dir=2表示 后退 //
...
L298N 使能(ENA ENB)端要接高电平。其他两脚接控制端,一端接pwm 。一端接普通数字口控制正反向 eddiewwm 发表于 2014-4-13 20:47 static/image/common/back.gif
應檢查以下的 dir ,PWMA 及 PWMB 的傳來值是否正確。
void motor_move(int dir,int PWMA_VAL,int PWMB_ ...
输入的值是没有问题的,谢谢你的回答。 Workspace 发表于 2014-4-13 21:01 static/image/common/back.gif
L298N 使能(ENA ENB)端要接高电平。其他两脚接控制端,一端接pwm 。一端接普通数字口控制正反向
使能端高电平是默认设置,没有改动,完全是按照这个说明图接的,应该没有问题呀。 究竟是什么问题呢? //Motor A
int PWMA = 9; //pwm控制是吧
int Left_1 = 8; //
int Left_2 = 7; //
7是使能端或者8是
但是
case 1://当 dir=1,表示前进//
digitalWrite (Left_1,HIGH);
digitalWrite(Left_2,LOW);
case 2://backward
digitalWrite (Left_1,LOW);
digitalWrite(Left_2,HIGH);//使能端一会高一会低。肯定不行
//还有要是改变电机速度必须改变PWM的值(0-255) Workspace 发表于 2014-4-14 11:27 static/image/common/back.gif
//Motor A
int PWMA = 9; //pwm控制是吧
int Left_1 = 8; //
8,7是数字端控制电机left方向的
PWMB才是控制电机Right使能端 本帖最后由 fish6823 于 2014-4-14 14:59 编辑
能上张你的接线图吗?看你的图没看出PWMA与B接哪里,而且PWM值30太低了,一般电机不会动的,一般是100左右才动,你的电机能动是不是接错线了。
按说应该是A1、A2、B1、B2接正反转控制,ENA、ENB接PWM,但你的图上ENA、ENB短接了。 fish6823 发表于 2014-4-14 14:56 static/image/common/back.gif
能上张你的接线图吗?看你的图没看出PWMA与B接哪里,而且PWM值30太低了,一般电机不会动的,一般是100左右才 ...
这个图是说明书的,不可能错的呀,兄弟,PWM值我不管设多少都一样,这才是问题。 活着就是幸福 发表于 2014-4-14 16:01 static/image/common/back.gif
这个图是说明书的,不可能错的呀,兄弟,PWM值我不管设多少都一样,这才是问题。
我的意思是你的9、10口接的是图中ENA、ENB那两个跳线的口? 活着就是幸福 发表于 2014-4-14 09:33 static/image/common/back.gif
输入的值是没有问题的,谢谢你的回答。
若真已確認輸入值沒問題,而函數也是已知可行的,那麼剩下來的就是硬件和接線等問題了!
页:
[1]