L298N Code problem

Hi,

I'm gonna make a quick presentation of what I'm talking about and what's my problem.

Recently I made a self balancing robot and I have little problem with coding, my problem
is that i get data from a Gyro sensor (once axe) and with that I try to balance 2 motors
with a L298N H.B.

The code that I'm using and I found it really easy to use and not making mistakes is from
a person from youtube.

Code that I'm using: (That's a part of the code, for Gyro just use your imagination that I got a
single variable and a single axes)

#define ENA 5  //enable A on pin 5 (needs to be a pwm pin)
#define ENB 3  //enable B on pin 3 (needs to be a pwm pin)
#define IN1 2  //IN1 on pin 2 conrtols one side of bridge A
#define IN2 4  //IN2 on pin 4 controls other side of A
#define IN3 6  //IN3 on pin 6 conrtols one side of bridge B
#define IN4 7  //IN4 on pin 7 controls other side of B

void setup()
{
  //set all of the outputs
  pinMode(ENA, OUTPUT);
  pinMode(ENB, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
}

void loop()
{
    // (Imagine a Variable that I'm using is a single axes that I use to balance my robot)
    //   Let's say we have  ax_y

Serial.println(ax_y,2);   // We got values from n...-15 to 15...n "which represent angle in real life"


  if (ax_y > 7){
      motorA(0,0);
      motorB(0,0);
delay(1);
      motorA (1,70);
      motorB (1,70); 
}
else if (ax_y < -7){
          motorA(0,0);
      motorB(0,0);
delay(1);
      motorA (2,70);
      motorB (2,70); 
}

else if (ax_y > -5 && ax_y < 5){
      motorA(0,0);
      motorB(0,0);
      delay(1);
}

 delay(147);  
 





}

//******************   Motor A control   *******************
void motorA(int mode, int percent)
{
  
  //change the percentage range of 0 -> 100 into the PWM
  //range of 0 -> 255 using the map function
  int duty = map(percent, 0, 100, 0, 255);
  
  switch(mode)
  {
    case 0:  //disable/coast
      digitalWrite(ENA, LOW);  //set enable low to disable A
      break;
      
    case 1:  //turn clockwise
      //setting IN1 high connects motor lead 1 to +voltage
      digitalWrite(IN1, HIGH);   
      
      //setting IN2 low connects motor lead 2 to ground
      digitalWrite(IN2, LOW);  
      
      //use pwm to control motor speed through enable pin
      analogWrite(ENA, duty);  
      
      break;
      
    case 2:  //turn counter-clockwise
      //setting IN1 low connects motor lead 1 to ground
      digitalWrite(IN1, LOW);   
      
      //setting IN2 high connects motor lead 2 to +voltage
      digitalWrite(IN2, HIGH);  
      
      //use pwm to control motor speed through enable pin
      analogWrite(ENA, duty);  
      
      break;
      
    case 3:  //brake motor
      //setting IN1 low connects motor lead 1 to ground
      digitalWrite(IN1, LOW);   
      
      //setting IN2 high connects motor lead 2 to ground
      digitalWrite(IN2, LOW);  
      
      //use pwm to control motor braking power 
      //through enable pin
      analogWrite(ENA, duty);  
      
      break;
  }
}

//******************   Motor B control   *******************
  void motorB(int mode, int percent)
{
  
  //change the percentage range of 0 -> 100 into the PWM
  //range of 0 -> 255 using the map function
  int duty = map(percent, 0, 100, 0, 255);
  
  switch(mode)
  {
    case 0:  //disable/coast
      digitalWrite(ENB, LOW);  //set enable low to disable B
      break;
      
    case 1:  //turn clockwise
      //setting IN3 high connects motor lead 1 to +voltage
      digitalWrite(IN3, HIGH);   
      
      //setting IN4 low connects motor lead 2 to ground
      digitalWrite(IN4, LOW);  
      
      //use pwm to control motor speed through enable pin
      analogWrite(ENB, duty);  
      
      break;
      
    case 2:  //turn counter-clockwise
      //setting IN3 low connects motor lead 1 to ground
      digitalWrite(IN3, LOW);   
      
      //setting IN4 high connects motor lead 2 to +voltage
      digitalWrite(IN4, HIGH);  
      
      //use pwm to control motor speed through enable pin
      analogWrite(ENB, duty);  
      
      break;
      
    case 3:  //brake motor
      //setting IN3 low connects motor lead 1 to ground
      digitalWrite(IN3, LOW);   
      
      //setting IN4 high connects motor lead 2 to ground
      digitalWrite(IN4, LOW);  
      
      //use pwm to control motor braking power 
      //through enable pin
      analogWrite(ENB, duty);  
      
      break;
  }
}
//**********************************************************

I tried many if, else if, else statments on my own but I always got a messed wheels they turn
not as they should. I even tried to make a 3rd switch to combine the data in a easier coding,
I tried any kid of "If" I could think.

I thought about using maping to turn the wheels from 0 to 100% speed while the angle rise
but never tried it, the problem is that the motors do not respond as exactly what i write in the code.

and do not talk about the wires or circuit everything is connected 100% fine.
they rotate in the same direction or same opposite direction, I done already tests

Any idea how else can I use the values from the "y" axis and combine it with the H.B motors?

You need to research the theory on how a self-balancing robot is supposed to work, and look at the working code that other people have posted. There are many examples. As you have discovered, "trial and error" programming is not a great approach.

I already know how a self balancing robot works and I know every theory about it, I got
already done a circuit, everything connected perfectly.
I do not got any kid of code errors my problem is that the motors do not respond as i program them
maybe i do not understand something about the L298N.

I already give PWM, got connected IN's code running perfectly I done several tests to be sure that
the L298N it's working perfectly and it is.

I got a Gyro, Acc sensor filtered with Kama. Filter every data from the sensor is perfectly.
What I'm trying to do is to use a axe in this example a "y ax"
and combine the data from the sensor with the motors and stabilize the robot.

I tried every kind of posibility with If, else if, else statment and now I'm trying with do.. while.

delay(10);  
 float x=0;
 float y=0;
if (angle_y <= -7.00 || angle_y >= 7.00){
motorA(3,100);
motorB(3,100);
    delay(3);
do
{
  delay(2);
  x = angle_y;
motorA(1,50);
motorB(1,50);
//angle_y=-angle_y;
if(angle_y < 5.00 && angle_y > -5.00){
      motorA(3,100);
    motorB(3,100);
  break;
}
}
while(x >= 7.00);
}
else{
    motorA(3,100);
    motorB(3,100);
    delay(3);
 do{
 delay(2);
motorA(2,50);
motorB(2,50);
//angle_y=-angle_y;
if(angle_y < 5.00 && angle_y > -5.00){
      motorA(3,100);
    motorB(3,100);
  break;
}
}
while(y <= -7.00);
}
 delay(10);

That's my current code I wrote to try balance the robot and I followed a "brain" logic loop on the code
to see line by line what it gonna do but the final results is different.

The motors spin correctly for few sec in the beginning but after moving it around "ax_y" the motors start spin strangely ... after 5sec the motors start spin continuously only in one direction.

ps (The circuit is 100% calibrated everything connected correctly)

Any kind of suggestions, maybe I'm not doing something right !?

I tried every kind of posibility with If, else if, else statment and now I'm trying with do.. while.

This approach has nothing to do with the theory, and it does not and will not work.

You need to research the theory on how a self-balancing robot is supposed to work

This approach has nothing to do with the theory

and it does not and will not work.

You could help me with something but not telling me that will not work.

if (angle_y > -5.00 && angle_y < 5.00){
motorA(3,100);
motorB(3,100);
}
else{ if (angle_y > 7){
    float x=0;
    float y=0; 
  do
{

  delay(2);
  x = angle_y;
motorA(1,70);
motorB(1,70);
x = y;
if (y < 5){ break;}
}
while(x >= 7.00);
}}

//Other way 

if (angle_y > -5.00 && angle_y < 5.00){
motorA(3,100);
motorB(3,100);
}
else{ if (angle_y < -7){
    float x=0;
    float y=0; 
  do
{

  delay(2);
  x = angle_y;
motorA(2,70);
motorB(2,70);
x = y;
if (y > -5){ break;}
}
while(x <= -7.00);
}}

 delay(10);

Other code that I'm testing right now, seams to work but there is some kind of problems as well,
the motors don't stop immediately when they arrive in the balance position 90 deg.angle.
It's like they have some kind of lag :smiley:

Hi,
What is the voltage and current rating of your motors.
What are you using and what voltage are you supplying the motor,

The L298 does have a volt drop across it when conducting.

Tom.... :slight_smile:

I'm using 2x battery 18650 they give me 12v 4000mAh
I use the HC02-48 geared motors, working voltave 3-6-12v.
Ofc I'm not using max PWM. The code that I wrote and posted above it's working really well
but there is still some natural errors. After many ecilibration the robot is doing itself the motors
start spin in one direction really fast and for long time till unplug the power or reset the chip.

I'm still in the holding hands around the robot to not fall down :smiley:

I didn't tried yet but I think and sounds logic to try the same code that I wrote above and a
PWM balance mapping for the motors, While the motors get/arrive in the balance position
then the PWM to get lower.

What I mean is that I observed the motors try to balance themselves violently, they push right and left
really fast to balance themselves and they create a violently oscilation that makes the robot
to crash :smiley:

That's a good idea from my side but I still got a problem with the motors they seems to have a low response
problem like their lagging. :expressionless:

You need to implement a PID controller, as the theory requires. Download the Arduino PID library and read up on how to tune it for your application.

I didn't knew about the PID and I done a fast reading, downloaded the Lib and show few examples
but I still didn't understood how it could work in my case.

The PID has 3 values which they try to balance the exact input -> output signal and make it stable
but how you use that 3 values Kp, Ki, Kp to balance a motor.

I don't know how to combine the 3 PID values with my own ones. O_o I even seen few PID examples on
youtube. But couldn't find any tutorial how to use that values in the way to control a motor, sensor or anything else.

I keep searching, if you have any easy tutorial or if you can explain to me how to use the values would be nice.

Almost every successful self-balancing robot uses a PID algorithm of some sort.

Google "PID tuning tutorial" for thousands of helpful web pages.