Cannot seem to run dc motor with servo motor together. I am using L298N driver with ESP32Servo driver library

I've been able to run my servo if I disable the Dc motor by "//toggle()" but when I run it with toggle, the servo doesn't seem to work anymore.

For a clearer description, I am powering my DC motor with a 12v 0.5A through the l298n driver while the servo is powered by the esp32.

#include <L298N.h>
#include <ESP32Servo.h>

#define button 34  // GPIO pin connected to button

#define led 33
Servo myservo;  // Create servo object to control a servo

// Pin definitions for motors
const unsigned int IN1 = 18;
const unsigned int IN2 = 5;
const unsigned int EN = 19;

const unsigned int IN12 = 4;
const unsigned int IN22 = 16;
const unsigned int EN2 = 0;

// Create motor instances
L298N motor(EN, IN1, IN2);
L298N motor2(EN2, IN12, IN22);

int servoPin = 32;  // Servo pin
int pos = 0;        // Servo position
unsigned long currentMillis = 0;

unsigned long buttonPreviousMillis = 0;  // Store last time servo was updated
unsigned long servoPreviousMillis = 0;
unsigned long fadePreviousMillis = 0;
int motorunning = 0;
byte toggleState = LOW;


const unsigned long buttonPeriod = 50;
const unsigned long servoPeriod = 15;  // Interval for servo updates
const unsigned long blinkPeriod = 500;
const unsigned long fadePeriod = 10;

void setup() {
  Serial.begin(115200);      // standard 50 hz servo
  myservo.attach(servoPin);  // attaches the servo on pin 18 to the servo object


  motor.setSpeed(250);   // Set motor speed
  motor2.setSpeed(250);  // Set second motor speed

  pinMode(button, INPUT);  // Initialize button pin

  pinMode(led, OUTPUT);
}

void toggle() {
  if (currentMillis - buttonPreviousMillis >= buttonPeriod) {
    buttonPreviousMillis = currentMillis;  //variable catch time from currentMillis

    if (digitalRead(button) == HIGH) {
      Serial.print("Button pressed");
      Serial.println();
      motor.forward();
      motor2.forward();
      Serial.println();
      motorunning = 1;

    } else {
      Serial.print("Button not pressed");
      Serial.println();
      motor.stop();
      motor2.stop();
      motorunning = 0;
    }
  }
}



void servoSweep() {
  if (digitalRead(button) == HIGH && motorunning == 1) {
    if (currentMillis - servoPreviousMillis >= servoPeriod) {
      servoPreviousMillis = currentMillis;
      Serial.print("Servo");
      Serial.println();
      pos += 1;        // Increment servo position
      if (pos > 60) {  // If position exceeds 50 degrees
        pos = 0;       // Reset to 0 degrees
      }
      myservo.write(pos);  // Move servo to the new position
    }
  }
}


void loop() {
  currentMillis = millis();  //MUST put in before commands
  // put your main code here, to run repeatedly:
  toggle();
  servoSweep();
}

Welcome to the forum

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the < CODE/ > icon above the compose window) to make it easier to read and copy for examination

https://forum.arduino.cc/t/how-to-get-the-best-out-of-this-forum

In my experience the easiest way to tidy up the code and add the code tags is as follows
Start by tidying up your code by using Tools/Auto Format in the IDE to make it easier to read. Then use Edit/Copy for Forum and paste what was copied in a new reply. Code tags will have been added to the code to make it easy to read in the forum thus making it easier to provide help.

Your topic has been moved the Programming category of the forum

Please post a schematic of your project showing all components, how they are interconnected and powered

That's never good idea.

Anyway, maybe l298n and servo use same timer causing your problem.
Maybe you could modify one of the libraries or try to use successive pwm channel/timer:
Create dumb servo object that you don't use for anything

Servo dumbservo1;
Servo dumbservo2;
Servo myservo;

and then:

dumbservo1.attach(14); //some unused pin
dumbservo2.attach(15); //some unused pin
myservo.attach(servoPin);

Never tested but you can try.

Edit:
What library exactly you use?
Esp32servo I found, uses:
ESP32PWM::allocateTimer();
but I don't see that in your code...

Hi there, how many ESP32PWM:allocateTimer(); do I need for my code? Also, do I need to enter in a number into the ()? I tried copy pasting the PMW code from the ESP32Servomotor library and it still doesn't work.
I really could use some help right now.

One should be enough for two servos. The point is to not use timer 0, which is probably used by the other library.

Hi there, I am using 2 DC motors and a servo motor. I've gotten a external power supply.

#include <L298N.h>
#include <ESP32Servo.h>

#define button 34  // GPIO pin connected to button

#define led 33
Servo myservo;  // Create servo object to control a servo

// Pin definitions for motors
const unsigned int IN1 = 18;
const unsigned int IN2 = 5;
const unsigned int EN = 19;

const unsigned int IN12 = 4;
const unsigned int IN22 = 16;
const unsigned int EN2 = 0;

// Create motor instances
L298N motor(EN, IN1, IN2);
L298N motor2(EN2, IN12, IN22);

int servoPin = 32;  // Servo pin
int pos = 0;        // Servo position
unsigned long currentMillis = 0;

unsigned long buttonPreviousMillis = 0;  // Store last time servo was updated
unsigned long servoPreviousMillis = 0;
unsigned long fadePreviousMillis = 0;
int motorunning = 0;
byte toggleState = LOW;


const unsigned long buttonPeriod = 50;
const unsigned long servoPeriod = 15;  // Interval for servo updates
const unsigned long blinkPeriod = 500;
const unsigned long fadePeriod = 10;

void setup() {
  Serial.begin(115200);      // standard 50 hz servo
  ESP32PWM::allocateTimer(0);
	myservo.setPeriodHertz(50);    // standard 50 hz servo
	myservo.attach(servoPin, 500, 2500); // attaches the servo on pin 18 to the servo object
	

  motor.setSpeed(250);   // Set motor speed
  motor2.setSpeed(250);  // Set second motor speed

  pinMode(button, INPUT);  // Initialize button pin

  pinMode(led, OUTPUT);
}

void toggle() {
  if (currentMillis - buttonPreviousMillis >= buttonPeriod) {
    buttonPreviousMillis = currentMillis;  //variable catch time from currentMillis

    if (digitalRead(button) == HIGH) {
      Serial.print("Button pressed");
      Serial.println();
      motor.forward();
      motor2.forward();
      Serial.println();
      motorunning = 1;

    } else {
      Serial.print("Button not pressed");
      Serial.println();
      motor.stop();
      motor2.stop();
      motorunning = 0;
    }
  }
}



void servoSweep() {
  if (motorunning == 1) {
    if (currentMillis - servoPreviousMillis >= servoPeriod) {
      servoPreviousMillis = currentMillis;
      Serial.print("Servo");
      Serial.println();
      pos += 1;        // Increment servo position
      if (pos > 60) {  // If position exceeds 50 degrees
        pos = 0;       // Reset to 0 degrees
      }
      myservo.write(pos);  // Move servo to the new position
    }
  }
}


void loop() {
  currentMillis = millis();  //MUST put in before commands
  // put your main code here, to run repeatedly:
  toggle();
  servoSweep();
}

These are the codes that I have modified. Currently timer 0 has been assigned to the servo motor. However is there a mistake in my program that may prevent the servo motor from moving alongside the DC motor?

I have implemented millis() in my code by the way.

Honestly, I don't know why I am running into these problems. The fact that they aren't any guide to run 2 dc motors and servo together must mean this problem is easily fixed

I suggested to not allocate timer 0...
Choose another.

Hi, I've used timer 1, then 2 then 3 and it still doesn't work

#include <L298N.h>
#include <ESP32Servo.h>

#define button 34  // GPIO pin connected to button

#define led 33
Servo myservo;  // Create servo object to control a servo

// Pin definitions for motors
const unsigned int IN1 = 18;
const unsigned int IN2 = 5;
const unsigned int EN = 19;

const unsigned int IN12 = 4;
const unsigned int IN22 = 16;
const unsigned int EN2 = 0;

// Create motor instances
L298N motor(EN, IN1, IN2);
L298N motor2(EN2, IN12, IN22);

int servoPin = 27;  // Servo pin
int servoPos = 0;   // Servo position
int servoIncrement = 3;
unsigned long currentMillis = 0;

unsigned long buttonPreviousMillis = 0;  // Store last time servo was updated
unsigned long servoPreviousMillis = 0;
unsigned long fadePreviousMillis = 0;
int motorunning = 0;
byte toggleState = LOW;


const unsigned long buttonPeriod = 200;
const unsigned long servoPeriod = 30;  // Interval for servo updates
const unsigned long blinkPeriod = 500;
const unsigned long fadePeriod = 10;

void setup() {
  Serial.begin(9600);  // standard 50 hz servo
  ESP32PWM::allocateTimer(1);
  
  ESP32PWM::allocateTimer(2);
  myservo.setPeriodHertz(50);           // standard 50 hz servo
  myservo.attach(servoPin, 500, 2500);  // attaches the servo on pin 18 to the servo object

  motor.setSpeed(250);   // Set motor speed
  motor2.setSpeed(250);  // Set second motor speed

  pinMode(button, INPUT_PULLUP);  // Initialize button pin

  pinMode(led, OUTPUT);
}

void toggle() {
  if (currentMillis - buttonPreviousMillis >= buttonPeriod) {
    buttonPreviousMillis = currentMillis;  //variable catch time from currentMillis

    if (digitalRead(button) == HIGH) {
      Serial.print("Button pressed");
      Serial.println();
      motor.forward();
      motor2.forward();
      Serial.println();
      motorunning = 1;

    } else {
      Serial.print("Button not pressed");
      Serial.println();
      motor.stop();
      motor2.stop();
      motorunning = 0;
    }
  }
}



void servoSweep() {
  if (currentMillis - servoPreviousMillis >= servoPeriod) {
    servoPreviousMillis = currentMillis;
    if (motorunning && digitalRead(button) == HIGH) {
      Serial.println("Motor is now running");
      servoPos += servoIncrement;
      /*if the servo position goes above 180, reverse the increment by turning it negative. If the servo position goes below 0 then reverse the neg increment to positive*/
      if ((servoPos > 90) || (servoPos < 0)) {
        servoIncrement = -servoIncrement;
      }
      //output the servo horn position
      Serial.println(servoPos);
      myservo.write(servoPos);
    }
    else{
      myservo.write(servoPos);
      
    }
  }
}

void loop() {
    currentMillis = millis();  //MUST put in before commands
    // put your main code here, to run repeatedly:
    toggle();
    servoSweep();
}


Ok, so I've used another timer and switched the if statement in the servoSweep. However, the servo just fidgets at a small angle. It seems the dc motor's pwm clashes with the servo

And what you get on serial monitor? Is it matching the behavior?

I'm not even sure if you have powering issue or software issue.
How is Esp32 powered? Hopefully not from the L298N.

Thanks for the help, man. I've already gotten an external power for the servo motor and have made some changes to the code. The part that really helped me was tweaking out the timer values for the toogle() and swervosweep().

#include <L298N.h>
#include <ESP32Servo.h>

#define button 34  // GPIO pin connected to button

#define led 33
Servo myservo;  // Create servo object to control a servo

// Pin definitions for motors
const unsigned int IN1 = 18;
const unsigned int IN2 = 5;
const unsigned int EN = 19;

const unsigned int IN12 = 4;
const unsigned int IN22 = 16;
const unsigned int EN2 = 0;

// Create motor instances
L298N motor(EN, IN1, IN2);
L298N motor2(EN2, IN12, IN22);

int servoPin = 27;  // Servo pin
int servoPos = 0;   // Servo position
int servoIncrement = 5;
unsigned long currentMillis = 0;

unsigned long buttonPreviousMillis = 0;  // Store last time servo was updated
unsigned long servoPreviousMillis = 0;
unsigned long fadePreviousMillis = 0;
int motorunning = 0;
byte toggleState = LOW;


const unsigned long buttonPeriod = 30;
const unsigned long servoPeriod = 20;  // Interval for servo updates
const unsigned long blinkPeriod = 500;
const unsigned long fadePeriod = 10;

void setup() {
  Serial.begin(9600);  // standard 50 hz servo
  ESP32PWM::allocateTimer(1);

  ESP32PWM::allocateTimer(2);
  myservo.setPeriodHertz(50);           // standard 50 hz servo
  myservo.attach(servoPin, 500, 2500);  // attaches the servo on pin 18 to the servo object

  motor.setSpeed(250);   // Set motor speed
  motor2.setSpeed(250);  // Set second motor speed

  pinMode(button, INPUT_PULLUP);  // Initialize button pin

  pinMode(led, OUTPUT);
}

void toggle() {
  if (currentMillis - buttonPreviousMillis >= buttonPeriod) {
    buttonPreviousMillis = currentMillis;  //variable catch time from currentMillis

    if (digitalRead(button) == HIGH) {
      Serial.print("Button pressed");
      Serial.println();
      motor.forward();
      motor2.forward();
      Serial.println();
      motorunning = 1;

    } else {
      Serial.print("Button not pressed");
      Serial.println();
      motor.stop();
      motor2.stop();
      motorunning = 0;
    }
  }
}



void servoSweep() {
  if (currentMillis - servoPreviousMillis >= servoPeriod) {
    servoPreviousMillis = currentMillis;
    myservo.attach(servoPin, 500, 2500);  // attaches the servo on pin 18 to the servo object

    if (motorunning && digitalRead(button) == HIGH) {
      Serial.println("Motor is now running");
      servoPos += servoIncrement;
      /*if the servo position goes above 180, reverse the increment by turning it negative. If the servo position goes below 0 then reverse the neg increment to positive*/
      if ((servoPos > 50) || (servoPos < 0)) {
        servoIncrement = -servoIncrement;
      }
      //output the servo horn position
      Serial.println(servoPos);
      myservo.write(servoPos);
    } else {
      
      myservo.write(0);
    }
  }
}

void loop() {
  currentMillis = millis();  //MUST put in before commands
  // put your main code here, to run repeatedly:
  toggle();
  servoSweep();
}