motor turn full speed in one directio (l298p + arduino uno)

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)

any ideas ?

I'm not sure what the point of posting the code that works and not the code that doesn't work is. I expect the problem is in the non-working code that you haven't shown us.

Please do not attach this code (people reading the forum on mobile devices can't read .ino files). Post it correctly between </> code tags as described in "How to use this forum - please read".

Steve

i did every thing like the one that works

i just want general advice on why would something like that happen

can't post the code cuz it's for school project .

medzed:
i did every thing like the one that works

Except that you had other devices connected and working and a lot more code with all sorts of conditional statements and probably a few libraries, any of which could be messing things up.

Good luck with your project but I can't help with code and circuits that I can't see.

Steve

i've edited the post and included my code as you see i'ts simple i hope you can find some bug i couldn't see

medzed:
i just want general advice on why would something like that happen

and

it's for school project .

It sounds like you are trying to do as much of this yourself as you can.
That is very commendable.
You will likely get more help for displaying that desire on your part.

i've edited the post and included my code

In the future, don't do that. Making significant changes to earlier posts breaks the flow of the thread and others cannot understand who said what, when. Just place new information in new posts, inline with the conversation.

Edit: I did look at your code. Nothing jumps out at me, but admittedly I have never used PID logic.

Do you really mean if pidv < 10 do something or if pidv > 10 do exactly the same thing else if pidv is exactly 10 do something different?

And "if(-3<err<3)" almost certainly isn't doing what you think it is.

Steve

thank you for your response

about the pid<10 bit i just forgott to change it back i was experimenting with it

digitalWrite(m1_dir,LOW); // change to HIGH for the other direction
digitalWrite(m2_dir,HIGH);//change to LOW for the other direction
analogWrite(m1_pwm,abs(pidv));
analogWrite(m2_pwm,abs(pidv));

but tell me more about the " if(-3<err<3) " how exactly does it dont do what i think

it's suppose to calculate the i if the tilt window is between -3 and 3 is that wrong

i repeat the readings are good until i un_comment the motor_move function

i began to think it's about the dc motor's interfering with the mpu6050 and not the actual code

That's not proper C++ as the compiler would have explained to you if you had warnings switched on (and read the warning).

Try something more like "if (err >= -3 && err <= 3)".

Steve

that didn't make any different as i expected but thank you for noticing

i should mention that i googled this problem and found people with the same exact problem but there is no

solution offered in the comments if we found a solution we'd be the first i think :slight_smile: :slight_smile:

Also bit confused, never see a reset of “i” so it just continually grows in you PID sub?

i=i+ki*err;

ki=0 so it's irrelevent to the problem right now i think

int kp=5,ki=0.5,kd=0;

ki does not equal 0....

Hello,

can't post the code cuz it's for school project .

So how you can solved your own problems?

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 .

i am not sure,but have you check the output wiring? should be GND output from arduino to the motor, and + - external power supply on it.

And check this page.

maybe can help you with it. Goodluck

i'll try adding cappacitors in parallel with the motors i'll post the result later thank you for the reply