L298N driver problem

Hi. I’m new on this forum.
I want to build an autonomous car that can get out of the maze. Everything is purchased: Arduino UNO, L298N motor driver, HC-SR04 as proximity sensors and a chassis. The problem I face is or from Arduino, or from the driver. Branch A (which supplies engine A) gives a lower voltage than branch B (which supplies the engine B) and automatically cause a wheel rotation more slowly than the other one. This problem occur when in the code appears the reading parameters from the proximity sensors (three in number). I can say that the motors driver is powered from 12.5V , Arduino from USB and proximity sensors to 4.8V. I connected wires like in the photo attached bellow.

Here is the motors driver: http://www.amazon.com/Generic-Module-Stepper-Controller-Arduino/dp/B00HHYBW0E

Here is a video showing the voltage difference between the two branches: Dropbox - Error

This is the code:

int  IN3  =  8 ; 
int  IN4  =  9 ;
int  IN1  =  1 ;
int  IN2  =  2 ;
int ENA=10;
int ENB=11;

const int trigPin = A2;
const int echoPin = A3;
const int trigPin2 = A0;
const int echoPin2 = A1;
const int trigPin3 = A4;
const int echoPin3 = A5;
long duration, cmd, duration2, cmc, duration3, cms;

long microsecondsToCentimeters(long microseconds)
{
  return microseconds / 29 / 2;
}

void senzor(){
 ///////////////////////1st sensor-for right//////////////////////////// 
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);

  cmd = microsecondsToCentimeters(duration);
  if(cmd>=45 || cmd<=1)
    Serial.print("Out of range ");
  else
    {Serial.print("Right ");
    Serial.print(cmd);
    Serial.print("cm   ");
    }
  
  
   ///////////////////////2nd sensor-for center////////////////////////////
  
  digitalWrite(trigPin2, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin2, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigPin2, LOW);

  duration2 = pulseIn(echoPin2, HIGH);

  cmc = microsecondsToCentimeters(duration2);
  if(cmc>=45 || cmc<=1)
    Serial.print("Out of range ");
  else
    {Serial.print("Center ");
    Serial.print(cmc);
    Serial.print("cm   ");
    }
 
   ///////////////////////3th sensor-for left////////////////////////////
  
  digitalWrite(trigPin3, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin3, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigPin3, LOW);

  duration3 = pulseIn(echoPin3, HIGH);

  cms = microsecondsToCentimeters(duration3);
  if(cms>=45 || cms<=1)
    Serial.print("Out of range ");
  else
    {Serial.print("Left ");
    Serial.print(cms);
    Serial.print("cm   ");
    }  
  Serial.println("      ");
  
 
  
  
}

void  setup ()
{ Serial.begin(9600);
  
  pinMode  ( IN1 ,  OUTPUT );     
  pinMode  ( IN2 ,  OUTPUT );     
  pinMode  ( IN3 ,  OUTPUT );     
  pinMode  ( IN4 ,  OUTPUT );
  pinMode  ( ENA ,  OUTPUT );  
  pinMode  ( ENB ,  OUTPUT );
  pinMode(trigPin,OUTPUT);
  pinMode(echoPin,INPUT);
  pinMode(trigPin2,OUTPUT);
  pinMode(echoPin2,INPUT);
  pinMode(trigPin3,OUTPUT);
  pinMode(echoPin3,INPUT);
}


void back()
{ analogWrite  ( ENA  ,  0 );
  analogWrite  ( ENB ,  0 ); 
  
}

void go()
{ analogWrite(ENA,255);
  digitalWrite  ( IN2 ,  LOW);
  digitalWrite  ( IN1 ,  HIGH ); 
  analogWrite(ENB,255);
  digitalWrite  ( IN4 ,  HIGH);
  digitalWrite  ( IN3 ,  LOW ); 
 
}


void  loop ()
{ 
 
  senzor(); 
  if(cmc>=10)
    go();
  else
    back();
   

}

I would start by losing the Arduino for testing purposes. In go() you're PWM-ing both sides at 255 so in theory both sides (ENA and ENB) at 255 should have full voltage.

So, why not just test the driver board by itself with no Arduino then you'll know if the driver board itself is good or not.

I already tested the driver without arduino and voltages on both branches are approximately equal.
If proximity sensors are disconnected (or even connected, but do not write anything about them in code) on each branch have the same voltage (measured with measuring device). If I connect them (or write something in code related to them) appears the difference in voltage between branches

As a test maybe change the ENA and ENBs from analogWrite 255's to digitalWrite HIGHs? (EDIT although that probably won't help in the light of what you say about the sensors, but anything's worth a try I guess)

Can you also please edit your first post to put the code in code tags by selecting it and hitting the # button above the :sweat_smile:. That way the code...

will look like this()
{
}

.... which is waaaaay easier to read.

Reference
Language | Libraries | Comparison | Changes
analogWrite()
Description
The frequency of the PWM signal on most pins is approximately 490 Hz. On the Uno and similar boards, pins 5 and 6 have a frequency of approximately 980 Hz. Pins 3 and 11 on the Leonardo also run at 980 Hz.

I notice the Fritzing you posted for the L298 doesn't match with pin assignments in the code you posted.
I am not sure how you actually have it wired up.
Make sure that if you use pins 5 or 6 for Enable, that you use BOTH or NEITHER because they are double the frequency of the other pins (PWM frequency)
Try using 5 & 6 for ENable.

In the meantime, while you are troubleshooting the problem, you could even out the speeds by multiplying the analogWrite value for one of the two enables by the reciprical of the ratio of the two voltages to obtain the value that would most closely match the value of the other motor.
ie:
this is just an example
motor-A = 10.6V for a value of 255
motor-B= 12.3V for a value of 255
10.6/12.3=0.8617
0.8617 * 255 = 219.7 =>220
multiply all of motor-B's analogWrite values by 0.8617 before sending them to motor-B

click the MODIFY button in the upper right of the post window.
Highlight all you code.
click the "#" CODE TAGS button on the toolbar above just to the left of the QUOTE button.
click SAVE (at the bottom).
When you post code on the forum, please make a habit of using the code tags "#" button.

ax_lip97:
I already tested the driver without arduino and voltages on both branches are approximately equal.
If proximity sensors are disconnected (or even connected, but do not write anything about them in code) on each branch have the same voltage (measured with measuring device). If I connect them (or write something in code related to them) appears the difference in voltage between branches

I wrote up a longer reply about the batteries, voltages, hookup, etc - but I think I see your problem now (maybe):

STOP USING PIN 1 as an output!

If you plan on using pins 0 and/or 1 on the Arduino, these serve the serial I/O for the USB serial interface. You can use them, as long as you don't plan on using the USB. Otherwise, you can't use them.

I think what is happening to you is that in your code, you have pin 1 (transmit) set as an output for the motor driver (for one of the motors). Everything else is hooked up to higher number pins, so they are ok. But that particular pin is being used to set (partially) the direction of the motor control for one of the motors (or something like that).

Now - at the same time, you have the sensors hooked up and sensing. In your code, when they do that, you also do some serial printing, which outputs (aka - transmits) from the Arduino to the PC - and guess which pin that toggles?

Yep - Pin 1 is then toggled - which is likely causing that motor to run strangely as the sensors work. I would bet that if you removed the serial printing from that code (or better - move the function of pin 1 to another higher pin) - everything would start to work better.

That's just my best guess, though. Good luck - hope it works!

:smiley:

I tried to change the AnalogWrite in digitalWrite and the same problem. The problem is that in the video the voltage difference was smaller (about 2V). Now it's 5-6V. And I can't adjust the value of ENA and ENB so that the wheels to spin simultaneously. I moved the pins in 5 and 6 ports, but same problem

Well spotted cr0sh...

I will try immediately what cr0sh said

Now - at the same time, you have the sensors hooked up and sensing. In your code, when they do that, you also do some serial printing, which outputs (aka - transmits) from the Arduino to the PC - and guess which pin that toggles?

Yep - Pin 1 is then toggled - which is likely causing that motor to run strangely as the sensors work. I would bet that if you removed the serial printing from that code (or better - move the function of pin 1 to another higher pin) - everything would start to work better.

NOTE TO SELF,
DON'T ALLOCATE SERIAL Tx PIN TO MOTOR DIRECTION IN A SKETCH DOING SERIAL PRINTS......

So... I connected IN1 from PIN 1 to PIN 3 and erased from code everything about serial print. I still have a difference around 0,2-0,4 V between motor A and motor B and because of that my robot goes to left. Any possible problem? I did what raschemmel said , but each time is another voltage difference (0.2-0.4V)

I did what raschemmel said , but each time is another voltage difference (0.2-0.4V)

What are you talking about that I said to do here ? (that you did…)

This example. I tried to put into practice, but always is another voltage difference

raschemmel:

this is just an example
motor-A = 10.6V for a value of 255
motor-B= 12.3V for a value of 255
10.6/12.3=0.8617
0.8617 * 255 = 219.7 =>220
multiply all of motor-B's analogWrite values by 0.8617 before sending them to motor-B

Post the code you modified

int  IN3  =  8 ; 
int  IN4  =  9 ;
int  IN1  =  3 ;
int  IN2  =  2 ;
int ENA=5;
int ENB=6;

const int trigPin = A2;
const int echoPin = A3;
const int trigPin2 = A0;
const int echoPin2 = A1;
const int trigPin3 = A4;
const int echoPin3 = A5;
long duration, cmd, duration2, cmc, duration3, cms;

long microsecondsToCentimeters(long microseconds)
{
  return microseconds / 29 / 2;
}

void sensor(){
 ///////////////////////1st sensor-for right//////////////////////////// 
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);

  cmd = microsecondsToCentimeters(duration);
  
  
   ///////////////////////2nd sensor-for center////////////////////////////
  
  digitalWrite(trigPin2, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin2, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigPin2, LOW);

  duration2 = pulseIn(echoPin2, HIGH);

  cmc = microsecondsToCentimeters(duration2);
  
   ///////////////////////3th sensor-for left////////////////////////////
  
  digitalWrite(trigPin3, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin3, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigPin3, LOW);

  duration3 = pulseIn(echoPin3, HIGH);

  cms = microsecondsToCentimeters(duration3);
   
  
}

void  setup ()
{
  pinMode  ( IN1 ,  OUTPUT );     
  pinMode  ( IN2 ,  OUTPUT );     
  pinMode  ( IN3 ,  OUTPUT );     
  pinMode  ( IN4 ,  OUTPUT );
  pinMode  ( ENA ,  OUTPUT );  
  pinMode  ( ENB ,  OUTPUT );
  pinMode(trigPin,OUTPUT);
  pinMode(echoPin,INPUT);
  pinMode(trigPin2,OUTPUT);
  pinMode(echoPin2,INPUT);
  pinMode(trigPin3,OUTPUT);
  pinMode(echoPin3,INPUT);
}


void back()
{ analogWrite  ( ENA  ,  0 );
  analogWrite  ( ENB ,  0 ); 
  
}

void go()
{ analogWrite(ENA,255);
  digitalWrite  ( IN2 ,  LOW);
  digitalWrite  ( IN1 ,  HIGH ); 
  analogWrite(ENB,255);     //   analogWrite(ENB,244);
  digitalWrite  ( IN4 ,  HIGH);
  digitalWrite  ( IN3 ,  LOW ); 
 
}

void  loop ()
{ 
 
  sensor(); 
  if(cmc>=10)
    go();
  else
    back();
   

}

analogWrite(ENB,255); // analogWrite(ENB,244);

First of all, the comment is not going to effect the speed.
Second. This is not what I described.

this is just an example
motor-A = 10.6V for a value of 255
motor-B= 12.3V for a value of 255
10.6/12.3=0.8617
0.8617 * 255 = 219.7 =>220
multiply all of motor-B’s analogWrite values by 0.8617 before sending them to motor-B

I don’t even know which motor is going faster . You said it’s turning LEFT so the motor-A is WHAT ? (left or right ?)
Measure the voltage on the two motors.
devide one by the other
Enter that ratio as this value:

 float speedratio
motorB_speed = speedratio*motorA_speed; // Multiply FASTER MOTOR SPEED BY RATIO (RATIO <1)
  analogWrite(ENB,motorB_speed);     //    SEND REDUCED VALUE TO MOTOR THAT WAS PREVIOUSLY TURNING TOO FAST
  int  IN3  =  8 ; 
int  IN4  =  9 ;
int  IN1  =  3 ;
int  IN2  =  2 ;
int ENA=5;
int ENB=6;
int motorA_speed=255;
float motorA_voltage=10.5;
float motorB_voltage=12.3;
int motorB_speed;
float speedratio=motorA_voltage/motorB_voltage;

const int trigPin = A2;
const int echoPin = A3;
const int trigPin2 = A0;
const int echoPin2 = A1;
const int trigPin3 = A4;
const int echoPin3 = A5;
long duration, cmd, duration2, cmc, duration3, cms;

long microsecondsToCentimeters(long microseconds)
{
  return microseconds / 29 / 2;
}

void sensor(){
 ///////////////////////1st sensor-for right//////////////////////////// 
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);

  cmd = microsecondsToCentimeters(duration);
  
  
   ///////////////////////2nd sensor-for center////////////////////////////
  
  digitalWrite(trigPin2, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin2, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigPin2, LOW);

  duration2 = pulseIn(echoPin2, HIGH);

  cmc = microsecondsToCentimeters(duration2);
  
   ///////////////////////3th sensor-for left////////////////////////////
  
  digitalWrite(trigPin3, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin3, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigPin3, LOW);

  duration3 = pulseIn(echoPin3, HIGH);

  cms = microsecondsToCentimeters(duration3);
   
  
}

void  setup ()
{
  pinMode  ( IN1 ,  OUTPUT );     
  pinMode  ( IN2 ,  OUTPUT );     
  pinMode  ( IN3 ,  OUTPUT );     
  pinMode  ( IN4 ,  OUTPUT );
  pinMode  ( ENA ,  OUTPUT );  
  pinMode  ( ENB ,  OUTPUT );
  pinMode(trigPin,OUTPUT);
  pinMode(echoPin,INPUT);
  pinMode(trigPin2,OUTPUT);
  pinMode(echoPin2,INPUT);
  pinMode(trigPin3,OUTPUT);
  pinMode(echoPin3,INPUT);
}


void back()
{ analogWrite  ( ENA  ,  0 );
  analogWrite  ( ENB ,  0 ); 
  
}

void go()
{ analogWrite(ENA,motorA_speed);
  digitalWrite  ( IN2 ,  LOW);
  digitalWrite  ( IN1 ,  HIGH ); 


  motorA_speed = speedratio*motorB_speed;
  analogWrite(ENB,motorB_speed);     //   analogWrite(ENB,244);



  digitalWrite  ( IN4 ,  HIGH);
  digitalWrite  ( IN3 ,  LOW ); 
 
}

void  loop ()
{ 
 
  sensor(); 
  if(cmc>=10)
    go();
  else
    back();
   

}

FYI, IT WOULD MAKE IT MUCH EASIER FOR US IF YOU CHANGE YOUR VARIABLE NAMES TO LEFTMOTOR AND RIGHTMOTOR
OR SLOWMOTOR AND FASTMOTOR so we know what’s what.

I entered some voltages for the two motors. Replace the values I entered with the correct values (without the “V”) in the code
declarations for “motorA_voltage” and motorB_voltage"

ax_lip97:
I still have a difference around 0,2-0,4 V between motor A and motor B and because of that my robot goes to left. Any possible problem?

In an earlier post, you said:

I already tested the driver without arduino and voltages on both branches are approximately equal

Was that "approximately equal" better than the "0,2-0,4 V" you're getting now?

Also jbtw, without some kind of encoding on the shafts of the motors, you don't know that they would turn at the same speed even with exactly the same voltage. It might be that a manufacturing difference between the two "identical" motors is actually contributing more to the problem than the difference in the voltages on the two channels.

EDIT: I get a difference of just over 0.1V on the two channels of my 298 @Vs=12, under no load. Unfortunately I have no motors to put on as a load, nor any resistors of high enough wattage to let me get appreciable current to test.

I have 10R resistors which would give 1.2A but alas they're puny 1/4W ones and they'd need to dissipate 15W...

Motor A is the left motor and Motor B is the right one. The right is faster than left. Today I will edit the code and post here