L298n Hbridge + Potentiometer + incremental encoder

Hi,

i am using the h bridge to control the direction of a dc motor using a potentiometer.
the encoder is used to give me feedback of the position of the motor.

the code i am using is:

  const int switchPin = 2;    // switch input
  const int motor1Pin = 9;    // H-bridge leg 1 (pin 2, 1A)
  const int motor2Pin = 10;    // H-bridge leg 2 (pin 7, 2A)
  const int enablePin = 8;    // H-bridge enable pin
  const int ledPin = 13;      // LED 
  const int Potmotor = A1;    // select the input pin for the potentiometer
 
        int sensorValue = 0;  // variable to store the value coming from the sensor
  
  //***********************************************************************************

void Zero_motor()
 
 {
 if(digitalRead(6) == HIGH)
    {
     digitalWrite(enablePin,LOW); 
    delay (4000);
  } 
 }   
  //***********************************************************************************
    
  void Pot_motor()
  {
  digitalWrite(enablePin, HIGH); 
    
    sensorValue = analogRead(Potmotor);              // read the value from the sensor
    
    // if the switch is high, motor will turn in one direction:
    if ((sensorValue > 512) == HIGH) {
      digitalWrite(motor1Pin, LOW);   // set leg 1 of the H-bridge low
      digitalWrite(motor2Pin, HIGH);  // set leg 2 of the H-bridge high
    } 
    // if the switch is low, motor will turn in the other direction:
    else {
      digitalWrite(motor1Pin, HIGH);  // set leg 1 of the H-bridge high
      digitalWrite(motor2Pin, LOW);   // set leg 2 of the H-bridge low
    }


}
  //************************************************************************************
  
  void setup() {

    // set the switch as an input:
    
    pinMode(switchPin, INPUT);

    // set all the other pins you're using as outputs:
    
    pinMode(motor1Pin, OUTPUT); 
    pinMode(motor2Pin, OUTPUT); 
    pinMode(enablePin, OUTPUT);
    pinMode(ledPin, OUTPUT);

    // set enablePin high so that motor can turn on:
    digitalWrite(enablePin, HIGH); 

    Zero_motor();
  }

  void loop() {
    
    Pot_motor();

  
  }

the problem i am now facing is trying to control the speed of the DC motor with the Pot how can i do this??

You would probably want to use analogWrite() (PWM) to control motor speed. I think you can use a PWM output on the Enable pin or on either of the H-bridge pins.

What is connected to Pin 6 as used in Zero_motor()?

johnwasser: Clue to the mysterious “6” - http://arduino.cc/forum/index.php/topic,67316.msg497111.html#msg497111 :slight_smile: OK, my reply there was a bit cryptic, but so was the question. :roll_eyes:

Hullait1: as johnwasser writes, you put the analogWrite on the Enable pin. You have to move that to one of the pins with PWM output, #6 is one of them. Combine that with some of the code from my reply earlier, where the map() function takes the analog-in valueand makes it suitable for analogWrite. The “digitalWrite(9)” (as you did not tell what kind of circuit you wrere using) is replaced by set the motorpin1/2 for direction controlas you do now.

will this allow me to control the speed of the motor?

will fluctuations in speed effect my reading from the incremental encoder later on?

Summary of this thread:

How do I control the speed of a motor?

You can use PWM to control the speed of your motor.

Will that allow me to control the speed of my motor?

And to answer your second question, no it should not affect your ability to read your encoder.

thanks for summarising..

however what i actually need information on is using PWM to control the speed of the motor.

I would like to be able to do the following using a POT.

FAST REVERSE - REVERSE - STOP - FORWARD - FAST FORWARD.

any ideas on code...

i am using a hbridge.. with the following inputs..

motor Vs - 12V 5v Supply Ground

and the following outputs to the arduino..

enable PWM1 PWM 2

and then a + and - terminal for the motor

Enable, PWM1, and PWM2 are not outputs. They are inputs.

Aren't there 2 enable pins?

Anyway, the direction of the motor is defined by the enable pin (OUTPUT). Set it HIGH to go one way, and LOW to go the other way.

Use analogWrite() on the PWM1 or PWM2 pin to set the speed of the motor. The 2nd argument ranges from 0 (stopped) to 255 (pedal to the metal).

the direction of the motor is defined by the enable pin (OUTPUT). Set it HIGH to go one way, and LOW to go the other way.

That is not the way my L298N works … at least not if Hullait1 is connecting the L298N direct. If it is on some motorshield, they have - probably - differnet pin/functions.
The way Hullait1 set the motor 1/2 to High/low or Low/High is the correct way.
Enable-LOW will set the Hbridge to HighImpedance (motor coasts slowly to stop), enable-HIGH will allow the control. (Setting both Motor 1/2 to HIGH or LOW will “short” the motor, resulting in quick stop)
(here is a quick-ref sheet; only use one set of pins for one dc motor)

Now, I have not tried this myself, but others have written that you use one of the PWM output pins on your Arduino (f.ex. 6) and connect that to the Enable pin.

So, back to the programming problem.
1st test: Change the digital Write(enablepin) to an analogWrite(enablepin,255). At this point your program still works like before.
2nd test: change the analogWrite to use other values than 255, fex 120, and your motor should now run at half speed (but otherwise the program works the same)

At that point in the program where you decide direction you have “sensorvalue” from the pot. In the first choice the value goes from 0…511. It needs be between 255…0 (note -going the other way) for the analogWrite to use it. Where you set the direction you also use analogWrite(enablepin…) to the 255…0 value.

For the other direction the value is between 512…1023 here you have to map that to 0 to 255.

i can get the program to run so that when i rotate the Pot i get:

Reverse - Stop - Forward

however i would like the motor to gradually move from:

Fast Reverse - Reverse - Stop - Forward - Fast forward

using the pot. with the centre of the pot 1023/2 being the stop position.

how can i do this?

hullait1:
i can get the program to run so that when i rotate the Pot i get:

Reverse - Stop - Forward

however i would like the motor to gradually move from:

Fast Reverse - Reverse - Stop - Forward - Fast forward

using the pot. with the centre of the pot 1023/2 being the stop position.

how can i do this?

int value = analogRead(PotPin);

int speed = abs(value - 512) / 2;  // 0..1023 -> -512.0..+512 -> 512..0..512 -> 256..0..256
int direction = value < 512;  // or "value > 512" to reverse the action of the pot

where do i use this?

this is the code i am using… i have edited to add this code:

const int motor1Pin = 9; // H-bridge leg 1 (pin 9, 1A)
const int motor2Pin = 10; // H-bridge leg 2 (pin 10, 2A)
const int enablePin =11; // H-bridge enable pin 11
const int PotPin = A1; // select the input pin for the potentiometer

int Reverse;
int Forward;
int sensorValue = 0; // variable to store the value coming from the sensor

int value = analogRead(PotPin);
int speed = abs(value - 512) / 2; // 0…1023 → -512.0…+512 → 512…0…512 → 256…0…256
int direction = value < 512; // or “value > 512” to reverse the action of the pot

void setup()
{
digitalWrite (enablePin, HIGH);
}

void loop()
{
if (value < 510)
{
Reverse = map(value, 0, 510, 255, 0);
analogWrite (motor1Pin, Reverse);
}
else if (analogRead(value) > 518)
{
Forward = map(value, 518, 1023, 0, 255);
analogWrite (motor2Pin, Forward);
}
else
{
analogWrite (motor1Pin, 0);
analogWrite (motor2Pin, 0);
}
}

how ever this only gives forward drive

In loop, value never changes.

value does not contain a valid pin number, so analogRead(value) is meaningless.

        int sensorValue = 0;  // variable to store the value coming from the sensor

A generic sensor, huh?

You are not getting the analogRead in the loop. I haven’t tested all of it, but this should correct some of the challenge.

void loop()
{
  int retval = analogRead(value);

  if (retval < 510)
  {
    Reverse = map(value, 0, 510, 255, 0);
    analogWrite (motor1Pin, Reverse);
  }
  else if(retval > 518)
  {
    Forward = map(value, 518, 1023, 0, 255);
    analogWrite (motor2Pin, Forward);
  }
  else
  {
    analogWrite (motor1Pin, 0);
    analogWrite (motor2Pin, 0);
  }
}

i still am only getting one direction…

here is the code:

  const int motor1Pin = 9;    // H-bridge leg 1 (pin 9, 1A)
  const int motor2Pin = 10;    // H-bridge leg 2 (pin 10, 2A)
  const int enablePin =11;    // H-bridge enable pin 11
  const int PotPin = A1;    // select the input pin for the potentiometer
  
        int Reverse;
        int Forward;
        int sensorValue = 0;  // variable to store the value coming from the sensor
  
        int value = analogRead(PotPin);
        int speed = abs(value - 512) / 2;           // 0..1023 -> -512.0..+512 -> 512..0..512 -> 256..0..256
        int direction = value < 512;                // or "value > 512" to reverse the action of the pot


        
void setup()
{
digitalWrite (enablePin, HIGH);
}

void loop()
{
  int retval = analogRead(value);

  if (retval < 510)
  {
    Reverse = map(value, 0, 510, 255, 0);
    analogWrite (motor1Pin, Reverse);
  }
  else if(retval > 518)
  {
    Forward = map(value, 518, 1023, 0, 255);
    analogWrite (motor2Pin, Forward);
  }
  else
  {
    analogWrite (motor1Pin, 0);
    analogWrite (motor2Pin, 0);
  }
}

do i need to put the enable pin high in the setup ()??

i am using the pot to alter the direction and speed. this is what i would like to do:

1023/2 forward to fast forward
=1023/2 stop position
<1023/2 reverse to fast reverse

I modified the code a bit. No A1 on the PotPort, just 1. You must also turn off the other PWM port when you change directions. I still have not had time to check your parameters on map, but I will. Check back in a few.

  const int motor1Pin = 9;    // H-bridge leg 1 (pin 9, 1A)
  const int motor2Pin = 10;    // H-bridge leg 2 (pin 10, 2A)
  const int enablePin =11;    // H-bridge enable pin 11
  const int PotPin = 1;    // select the input pin for the potentiometer
  
        int Reverse;
        int Forward;
        int sensorValue = 0;  // variable to store the value coming from the sensor
  
        int value = analogRead(PotPin);
        int speed = abs(value - 512) / 2;           // 0..1023 -> -512.0..+512 -> 512..0..512 -> 256..0..256
        int direction = value < 512;                // or "value > 512" to reverse the action of the pot


        
void setup()
{
digitalWrite (enablePin, HIGH);
}

void loop()
{
  int PotVal = analogRead(PotPin);

  if (PotVal < 510)
  {
    Reverse = map(PotVal, 0, 510, 255, 0);
    analogWrite(motor2Pin,0);
    analogWrite (motor1Pin, Reverse);
  }
  else if(retval > 518)
  {
    Forward = map(PotVal,value, 518, 1023, 0, 255);
    analogWrite(motor1Pin,0);
    analogWrite (motor2Pin, Forward);
  }
  else
  {
    analogWrite (motor1Pin, 0);
    analogWrite (motor2Pin, 0);
  }
}

the code appears to work however it works with the pot connected to analog A0 whereas i would like it to work with the pot connected to analog A1 i have tryed to alter this and the code is below however it doesnt seem to have any effect.

also has the max speed of the motor been effected with this code for max forward and reverse drive? it appears slower or it could just be me…

  const int motor1Pin = 9;    // H-bridge leg 1 (pin 9, 1A)
  const int motor2Pin = 10;    // H-bridge leg 2 (pin 10, 2A)
  const int enablePin =11;    // H-bridge enable pin 11
  const int PotPin = A1;    // select the input pin for the potentiometer
  
        int Reverse;
        int Forward;
        int sensorValue = 1;  // variable to store the value coming from the sensor
  
        int value = analogRead(PotPin);
        int speed = abs(value - 512) / 2;           // 0..1023 -> -512.0..+512 -> 512..0..512 -> 256..0..256
        int direction = value < 512;                // or "value > 512" to reverse the action of the pot


        
void setup()
{
digitalWrite (enablePin, HIGH);
}

void loop()
{
  int retval = analogRead(value);

  if (retval < 510)
  {
    Reverse = map(retval, 0, 510, 255, 0);
    analogWrite (motor1Pin, Reverse);
  }
  else if(retval > 518)
  {
    Forward = map(retval, 518, 1023, 0, 255);
    analogWrite (motor2Pin, Forward);
  }
  else
  {
    analogWrite (motor1Pin, 0);
    analogWrite (motor2Pin, 0);
  }
}

Check the new code in my previous post. You have an incorrect value for PortPin. Just "PortPin = 1". No A. You must also turn off the other PWM pin when you change direction.

i have altered the line as follows:

const int PotPin = A1;    // select the input pin for the potentiometer

but it still uses the pot connected to A0 which is for another application…

Also i do not understand what you mean by turning the other PWM off when changing direction :~

There are three inputs on the 298. Enable determines if the 298 does anything at all.

If the inputs are different, The HBridge "opens" in one direction, depending on which of the two pins are HIGH. If the inputs are the same, it goes into "brake" mode with Enable HIGH.

What you want to do is keep one of the inputs LOW, and pulse the other to control the speed. If you do not turn off the opposite PWM pin, the inputs may be in brake mode part of the time.

EDIT: You may want to disable the PWM completely on one pin. If the inputs are the same (LOW OR HIGH) the 298 goes into brake mode.