L298n speed control not working

I am designing a fire fighting robot and am using L298n motor driver for the motors.When sending Pwm signal to the driver for speed control only Pwm on pin 11 goes. The Pwm output on pin 10 doesn't work.


```cpp
#include <Servo.h>
#include <Wire.h>
#include <Adafruit_MLX90614.h>

Adafruit_MLX90614 mlx;

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

int flame_sensor = 8;
int flame = 0;
int motor1pin1 = 2;
int motor1pin2 = 3;
int motor2pin1 = 4;
int motor2pin2 = 5;
float d1 = 3.8;
double temp = 0;
float fire_temp = 35.5;
int motorspeed = 100;
int motor1speedpin = 11;
int motor2speedpin = 10;


void setup() {
  Serial.begin(9600);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  myservo.write(90);
  pinMode(motor1pin1, OUTPUT);
  pinMode(motor1pin2, OUTPUT);
  pinMode(motor2pin1, OUTPUT);
  pinMode(motor2pin2, OUTPUT);
  pinMode(motor1speedpin, OUTPUT);
  pinMode(motor2speedpin, OUTPUT);
  pinMode(flame_sensor, INPUT);
  mlx.begin();
  
}

void scan() {
  while(true){
    for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
      // in steps of 1 degree
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(15);                       // waits 15 ms for the servo to reach the position
      if(Serial.available()>0){           // read value from serial monitor
  	    flame = Serial.readString().toInt();
      }
      if (digitalRead(flame_sensor)==0||flame==1){
        if (pos<90){
          digitalWrite(motor1pin1, HIGH);
          digitalWrite(motor1pin2, LOW);

          digitalWrite(motor2pin1, LOW);
          digitalWrite(motor2pin2, HIGH);

          delay(d1*(90-pos));

          digitalWrite(motor1pin1, LOW);
          digitalWrite(motor1pin2, LOW);

          digitalWrite(motor2pin1, LOW);
          digitalWrite(motor2pin2, LOW);
          myservo.write(90);
          break;
        } else if(pos>90)
          digitalWrite(motor1pin1, LOW);
          digitalWrite(motor1pin2, HIGH);

          digitalWrite(motor2pin1, HIGH);
          digitalWrite(motor2pin2, LOW);

          delay(d1*(pos-90));

          digitalWrite(motor1pin1, LOW);
          digitalWrite(motor1pin2, LOW);

          digitalWrite(motor2pin1, LOW);
          digitalWrite(motor2pin2, LOW);
          myservo.write(90);
          break;
      }
    }
    
    if(pos != 181){
      break;
    }
    
    for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(15);                       // waits 15 ms for the servo to reach the position
      if(Serial.available()>0){           // read value from serial monitor
    	  flame = Serial.readString().toInt();
        }
      if (digitalRead(flame_sensor)==0||flame==1){
        if (pos<90){
          digitalWrite(motor1pin1, HIGH);
          digitalWrite(motor1pin2, LOW);

          digitalWrite(motor2pin1, LOW);
          digitalWrite(motor2pin2, HIGH);

          delay(d1*(90-pos));

          digitalWrite(motor1pin1, LOW);
          digitalWrite(motor1pin2, LOW);

          digitalWrite(motor2pin1, LOW);
          digitalWrite(motor2pin2, LOW);
          myservo.write(90);
          break;
        } else if(pos>90){
          digitalWrite(motor1pin1, LOW);
          digitalWrite(motor1pin2, HIGH);

          digitalWrite(motor2pin1, HIGH);
          digitalWrite(motor2pin2, LOW);

          delay(d1*(pos-90));

          digitalWrite(motor1pin1, LOW);
          digitalWrite(motor1pin2, LOW);

          digitalWrite(motor2pin1, LOW);
          digitalWrite(motor2pin2, LOW);
          myservo.write(90);
          break;
          }
      }
    }

    if(pos != -1){
      break;
    }

  }
}
void loop(){
  scan();
  while(true){
    temp = mlx.readObjectTempC();
    Serial.println(mlx.readObjectTempC());
    if (temp > fire_temp) {
      digitalWrite(motor1pin1, LOW);
      digitalWrite(motor1pin2, LOW);

      digitalWrite(motor2pin1, LOW);
      digitalWrite(motor2pin2, LOW);
      break;
    } else {
      analogWrite(motor1speedpin, motorspeed);
      analogWrite(motor2speedpin, motorspeed);
      digitalWrite(motor1pin1, HIGH);
      digitalWrite(motor1pin2, LOW);

      analogWrite(motor2speedpin, motorspeed);
      digitalWrite(motor2pin1, HIGH);
      digitalWrite(motor2pin2, LOW);
    }
  }
}
1 Like

The Servo library disables PWM on pins 9 and 10.

Read the documentation. Servo library.
`

On boards other than the Mega, use of the library disables analogWrite() (PWM) functionality on pins 9 and 10, whether or not there is a Servo on those pins.

Good job on your first post. You provided relevant information and posted the code properly. Most new users don't bother reading the guidelines. Thanks.

1 Like

I used pin 6 and it still didn't work. for some reason using analogWrite(motor2speedpin, -motorspeed);worked.

Welcome! Post an annotated schematic showing how you have wired this. Be sure to include all connections, power, ground, and power sources. Links to any non standard devices will help us help you.

MOSFET pump motor driver.

Choose MOSFET to handle motor stall current. Stall current should be listed on the motor data sheet or motor data plate.

Although I cannot share an annotated diagram, Here are the pin connections
Pin 1 Pin 2
Arduino 2 L298n In3
Arduino 3 L298n In4
Arduino 4 L298n In2
Arduino 5 L298n In1
Arduino 6 L298n ENA
Arduino 7
Arduino 8 Flame sensor D0
Arduino 9 Servo Signal
Arduino 11 L298n ENB
Arduino A4 MLX90614 SDA
Arduino A5 MLX90614 SCL
Arduino Vin 9v (Via Power Distribution Board)
Arduino Gnd Gnd (Via Power Distribution Board)
Arduino Gnd Flame sensor Gnd
Arduino 5v Flame sensor Vcc
L298n 5v Servo 5v
L298n Gnd Servo Gnd
L298n Gnd MLX90614 Gnd
L298n 5v MLX90614 Vin

Why not?


            +---|EXT|--------|USB|---+
            |    PWR          A5/SCL |
            |                 A4/SDA |
            |          UNO      AREF |
            |                    GND |            +-----+
            | IOREF          SCK/D13 |            |SERVO|       
            | RST             DI/D12 |            | GND |-------+
            | 3V3             DO/D11~|----+       | VCC |-----+ |
      +-----| +5V                D10~|  +-|-------| SIG |     | |
      |     | GND                 D9~|--+ |       +-----+     | |
    +-|-----| GND                 D8 |--+ |   +------------+  | |
  +-|-|-----| Vin                 D7 |  | +---| ENB  L298N |  | |
  | | |     |                     D6~|--|-----| ENA        |  | |
  | | |     | A0                  D5~|--|-----| IN1     5V |--+ |
  | | |     | A1                  D4 |--|-----| IN2    GND |--|-+
  | | |     | A2             INT1/D3 |--|-----| IN4        |  | |
  | | |     | A3             INT0/D2~|--|-----| IN3        |  | |
  | | | +---| A4/DA  RS CK DI  TX>D1 |  |     +------------+  | |
  | | | | +-| A5/CL  GD D0 5V  RX<D0 |  |     +------------+  | |
  | | | | | +------------------------+  +-----| SIG  FLAME |  | |
  | +-|-|-|-----------------------------------| GND SENSOR |  | |
  | | +-|-|-----------------------------------| VCC        |  | |
  | |   | |  +---------+                      +------------+  | |
  +-|---|-|--| 9V  PDB |                                      | |
    +---|-|--| GND     |                      +------------+  | |
        | |  +---------+                      |  MLX90614  |  | |
        | +-----------------------------------| SCL    VCC |--+ |
        +-------------------------------------| SDA    GND |----+
                                              +------------+

While working on the code and improving it I encountered another problem. When scan2 completes and starts scan1, scan1 doesn't complete and scan2 starts again. Here is the new code

#include <Servo.h>
#include <Wire.h>
#include <Adafruit_MLX90614.h>

#define len 10

Adafruit_MLX90614 mlx;

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

int flame_sensor = 8;
int flame = 0;
int motor1pin1 = 2;
int motor1pin2 = 3;
int motor2pin1 = 4;
int motor2pin2 = 5;
float d1 = 3.4;
float temp = 0;
float fire_temp = 39.0;
int motorspeed = 100;
int motor1speedpin = 11;
int motor2speedpin = 6;
float scan_temp = 0;
float max_temp = 0;
float scan_temp_array[len];
int degree = 0;
int pos1 = 0;
int pos2 = 0;
int equal = 0;
int i = 0;
long sum = 0;
int pump = 7;

void setup() {
  Serial.begin(9600);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  myservo.write(90);
  pinMode(motor1pin1, OUTPUT);
  pinMode(motor1pin2, OUTPUT);
  pinMode(motor2pin1, OUTPUT);
  pinMode(motor2pin2, OUTPUT);
  pinMode(motor1speedpin, OUTPUT);
  pinMode(motor2speedpin, OUTPUT);
  pinMode(flame_sensor, INPUT);
  mlx.begin();
  
}
void put_of_fire(){
  digitalWrite(pump, HIGH);
  for (pos = 45; pos <= 135; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(30);
  }
  digitalWrite(pump, LOW);
}
void scan1() {
  Serial.println("scan1");
  for (pos = 45; pos <= 135; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    sum = 0;
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(5);
    Serial.println(len);
    for (i = 0; i<=len; i+=1) {
      scan_temp_array[i]=mlx.readObjectTempC();
      delay(1);
    }
    Serial.println("read");
    for (i = 0; i<=len; i+=1) {
      sum += scan_temp_array[i];
    }
    Serial.println("added");
    scan_temp = roundf(sum/len);
    Serial.println(scan_temp);
    if (scan_temp >= max_temp){
      if (scan_temp != max_temp){
        max_temp = scan_temp;
        degree = pos;
      }
      else {
        equal=1;
        if (pos<90) {
          pos1 = pos;
        } 
        else {
          pos2 = pos;
        }
      }
    }
  }
  if (equal == 1) {
  degree = (pos1+pos2)/2;
  }
  if (degree<90){
  digitalWrite(motor1speedpin, HIGH);
  digitalWrite(motor1pin1, HIGH);
  digitalWrite(motor1pin2, LOW);

  digitalWrite(motor2speedpin, HIGH);
  digitalWrite(motor2pin1, LOW);
  digitalWrite(motor2pin2, HIGH);

  delay(d1*(90-degree));

  digitalWrite(motor1pin1, LOW);
  digitalWrite(motor1pin2, LOW);

  digitalWrite(motor2pin1, LOW);
  digitalWrite(motor2pin2, LOW);
  myservo.write(90);
  return;
} else if(degree>90){
  digitalWrite(motor1speedpin, HIGH);
  digitalWrite(motor1pin1, LOW);
  digitalWrite(motor1pin2, HIGH);

  digitalWrite(motor2speedpin, HIGH);
  digitalWrite(motor2pin1, HIGH);
  digitalWrite(motor2pin2, LOW);

  delay(d1*(degree-90));

  digitalWrite(motor1pin1, LOW);
  digitalWrite(motor1pin2, LOW);

  digitalWrite(motor2pin1, LOW);
  digitalWrite(motor2pin2, LOW);
  myservo.write(90);
  return;
  }
}
void scan2() {
  while(true){
    Serial.println("scan2");
    for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
      // in steps of 1 degree
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(30);                       // waits 15 ms for the servo to reach the position
      if(Serial.available()>0){           // read value from serial monitor
    	  flame = Serial.readString().toInt();
        }
      if (digitalRead(flame_sensor)==0||flame==1){
        if (pos<90){
          digitalWrite(motor1speedpin, HIGH);
          digitalWrite(motor1pin1, HIGH);
          digitalWrite(motor1pin2, LOW);

          digitalWrite(motor2speedpin, HIGH);
          digitalWrite(motor2pin1, LOW);
          digitalWrite(motor2pin2, HIGH);

          delay(d1*(90-pos));

          digitalWrite(motor1pin1, LOW);
          digitalWrite(motor1pin2, LOW);

          digitalWrite(motor2pin1, LOW);
          digitalWrite(motor2pin2, LOW);
          myservo.write(90);
          Serial.println("scan2 break1");
          break;
        } else if(pos>90){
          digitalWrite(motor1speedpin, HIGH);
          digitalWrite(motor1pin1, LOW);
          digitalWrite(motor1pin2, HIGH);

          digitalWrite(motor2speedpin, HIGH);
          digitalWrite(motor2pin1, HIGH);
          digitalWrite(motor2pin2, LOW);

          delay(d1*(pos-90));

          digitalWrite(motor1pin1, LOW);
          digitalWrite(motor1pin2, LOW);

          digitalWrite(motor2pin1, LOW);
          digitalWrite(motor2pin2, LOW);
          myservo.write(90);
          Serial.println("scan2 break1");
          break;
          }
      }
    }
    
    if(pos != 181){
      Serial.println("scan2 to scan1");
      scan1();
      break;
    }
    
    for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(30);                       // waits 15 ms for the servo to reach the position
      if(Serial.available()>0){           // read value from serial monitor
    	  flame = Serial.readString().toInt();
        }
      if (digitalRead(flame_sensor)==0||flame==1){
        if (pos<90){
          digitalWrite(motor1speedpin, HIGH);
          digitalWrite(motor1pin1, HIGH);
          digitalWrite(motor1pin2, LOW);

          digitalWrite(motor2speedpin, HIGH);
          digitalWrite(motor2pin1, LOW);
          digitalWrite(motor2pin2, HIGH);

          delay(d1*(90-pos));

          digitalWrite(motor1pin1, LOW);
          digitalWrite(motor1pin2, LOW);

          digitalWrite(motor2pin1, LOW);
          digitalWrite(motor2pin2, LOW);
          myservo.write(90);
          Serial.println("scan2 break1");
          break;
        } else if(pos>90){
          digitalWrite(motor1speedpin, HIGH);
          digitalWrite(motor1pin1, LOW);
          digitalWrite(motor1pin2, HIGH);

          digitalWrite(motor2speedpin, HIGH);
          digitalWrite(motor2pin1, HIGH);
          digitalWrite(motor2pin2, LOW);

          delay(d1*(pos-90));

          digitalWrite(motor1pin1, LOW);
          digitalWrite(motor1pin2, LOW);

          digitalWrite(motor2pin1, LOW);
          digitalWrite(motor2pin2, LOW);
          myservo.write(90);
          Serial.println("scan2 break1");
          break;
          }
      }
    }

    if(pos != -1){
      Serial.println("scan2 to scan1");
      scan1();
      break;
    }
    analogWrite(motor1speedpin, motorspeed);
    analogWrite(motor2speedpin, -motorspeed);
    digitalWrite(motor1pin1, HIGH);
    digitalWrite(motor1pin2, LOW);

    digitalWrite(motor2pin1, HIGH);
    digitalWrite(motor2pin2, LOW);
    
    delay(500);

    digitalWrite(motor1pin1, LOW);
    digitalWrite(motor1pin2, LOW);

    digitalWrite(motor2pin1, LOW);
    digitalWrite(motor2pin2, LOW);

  }
}
void loop(){
  scan2();
  Serial.println("main loop");
  while(true){
    temp = mlx.readObjectTempC();
    Serial.println(mlx.readObjectTempC());
    if (temp > fire_temp) {
      digitalWrite(motor1pin1, LOW);
      digitalWrite(motor1pin2, LOW);

      digitalWrite(motor2pin1, LOW);
      digitalWrite(motor2pin2, LOW);
      delay(99999999);
      put_of_fire();
      break;
    } else {
      analogWrite(motor1speedpin, motorspeed);
      analogWrite(motor2speedpin, -motorspeed);
      digitalWrite(motor1pin1, HIGH);
      digitalWrite(motor1pin2, LOW);

      digitalWrite(motor2pin1, HIGH);
      digitalWrite(motor2pin2, LOW);
    }
  }
}

Here is the serial logs
20:57:28.507 -> scan2 break1
20:57:28.507 -> scan2 to scan1
20:57:28.540 -> scan1
20:57:28.540 -> 10
20:57:29.002 -> scan2
20:57:40.374 -> scan2

You use "break;" eleven times. As you describe, it causes functions to get POPped off the stack before completion. You should write your code to avoid using "break;"... it seems to be a holdover from BASIC computer language.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.