I'm building a self balancing robot i did everything till i hit this problem
I'm controlling the robot with arduino uno . as driver i'm using l98p shield with the datasheet attached
i mesure angle by the mpu 6050
the problem is when ever i start the sketch the 6v dc motors just rotate full speed in witch ever direction i tilt the robot in and keep moving that way despite on witch direction i tilt it in again .
(rotation stuck in one direction);
i tried separate batteries for the arduino and the motor driver since you can separate them electrically just by removing a connection between them didn't work either .
but when i use a different sketch that only meant to test the motors it changes direction smoothly despite on the frequency of the shifting between directions
this is my code
#include <Wire.h>
// offsets acc gyro 538 -1753 1966 -8 56 95
#define acc_x_offset 538
#define acc_y_offset -1753
#define acc_z_offset 1966
#define gyro_x_offset -8
#define gyro_y_offset 56
#define gyro_z_offset 95
int kp=5,ki=0.5,kd=0;
float err,err_p;
int angle_0=0;
float i,p,d,pidv;
int m1_pwm=10,m2_pwm=11;
int m1_dir=12,m2_dir=13;
float rad_to_deg = 180/3.141592654;
float temps,temps_p,temps_a;
long acc_x,acc_y,acc_z;
float a_x,a_y,a_z;
long gyro_x,gyro_y,gyro_z;
float g_x,g_y,g_z,angle_x;
void setup() {
Serial.begin(115200);
Wire.begin();
pinMode(m1_dir,OUTPUT);
pinMode(m2_dir,OUTPUT);
init_mpu();
}
void loop() {
temps_p=temps_a;
temps_a=millis();
temps=(temps_a-temps_p)/1000;
lire_accel();
lire_gyro();
filtre();
pid();
mot_mov();
Serial.println(pidv);
}
void init_mpu()
{
Wire.beginTransmission(0x68); // 0x68 l'address de mpu_6050
Wire.write(0x6B); // 0x6B l'adress de registre de reset
Wire.write(0x00); // mode cyclique
Wire.endTransmission(); //sortire
Wire.beginTransmission(0x68);
Wire.write(0x1B); // plein echelle gyro
Wire.write(0x00); // +- 250 deg/s
Wire.endTransmission();
Wire.beginTransmission(0x68);
Wire.write(0x1C); // plein echelle accel
Wire.write(0x00); // +-2g
Wire.endTransmission();
}
void lire_accel()
{
Wire.beginTransmission(0x68);
Wire.write(0x3B); // 1ere registre de l'info de accel
Wire.endTransmission(false);
Wire.requestFrom(0x68,6);
while(Wire.available()<6);
acc_x=Wire.read()<<8|Wire.read();
acc_y=Wire.read()<<8|Wire.read();
acc_z=Wire.read()<<8|Wire.read();
acc_x=(acc_x-acc_x_offset);
acc_y=(acc_y-acc_y_offset);
acc_z=(acc_z-acc_z_offset);
a_x=(atan((acc_y/16384.0)/sqrt(pow((acc_x/16384.0),2) + pow((acc_z/16384.0),2)))*rad_to_deg);
a_y=atan(-1*(acc_x/16384.0)/sqrt(pow((acc_y/16384.0),2) + pow((acc_z/16384.0),2)))*rad_to_deg;
}
void lire_gyro()
{
Wire.beginTransmission(0x68);
Wire.write(0x43); // 1ere registre de l'info de gyro
Wire.endTransmission(false);
Wire.requestFrom(0x68,4);
while(Wire.available()<4);
gyro_x=Wire.read()<<8|Wire.read();
gyro_y=Wire.read()<<8|Wire.read();
gyro_x=(gyro_x-gyro_x_offset);
gyro_y=(gyro_y-gyro_y_offset);
g_x=gyro_x/131.1;
g_y=gyro_y/131.1;
}
void filtre()
{
angle_x=0.98*(angle_x+ g_x*temps)+0.02*a_x;
}
void pid()
{
err=angle_x-angle_0;
p=err*kp;
d=kd*((err-err_p)/temps);
err_p=err;
if(-3<err<3)
i=i+ki*err;
pidv = p+d+i;
if(pidv<-255) pidv=-255;
if(pidv>255) pidv=255;
}
void mot_mov()
{
if (pidv<10)
{
digitalWrite(m1_dir,LOW);
digitalWrite(m2_dir,HIGH);
analogWrite(m1_pwm,abs(pidv));
analogWrite(m2_pwm,abs(pidv));
}
else if(pidv>10)
{
digitalWrite(m1_dir,LOW);
digitalWrite(m2_dir,HIGH);
analogWrite(m1_pwm,abs(pidv));
analogWrite(m2_pwm,abs(pidv));
}
else
{
digitalWrite(m1_dir,HIGH);
digitalWrite(m2_dir,LOW);
analogWrite(m1_pwm,0);
analogWrite(m2_pwm,0);
delay(100);
}
}
the reading are good all work properly untill i uncomment the motor_mov() function
motor_test_code.ino (399 Bytes)