Controlling 4x motors using PCF8575, L298N and ESP32

Hi all,

Can anyone tell me why this sketch keeps on rebooting when run? It compiles OK and when compiled it keeps rebooting. When the serial lead is removed and a 12V battery for the L298N is applied it still does nothing. I assume it still reboots. I initially had a brownout issue but I’ve included the few lines of code to eliminate that.


#include <Wire.h>
#include "PCF8575.h"
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"

// Define the custom I2C pins
#define I2C_SDA_PIN 21
#define I2C_SCL_PIN 22

// Initialize the PCF8575 at address 0x20
PCF8575 pcf8575(0x20);

// Motor A
int motor1Forward = 1; 
int motor1Back = 0; 
int EnableMoror1 = 8;
int motor2Forward = 3; 
int motor2Back = 2; 
int EnableMoror2 = 9;
int motor3Forward = 4; 
int motor3Back = 5; 
int EnableMoror3 = 10;
int motor4Forward = 6; 
int motor4Back = 7; 
int EnableMoror4 = 11;

//Set motor Speeds
int Motor1Speed = 0; // 0 (Off) to 255 (top speed)
int Motor2Speed = 0; // 0 (Off) to 255 (top speed)
int Motor3Speed = 0; // 0 (Off) to 255 (top speed)
int Motor4Speed = 0; // 0 (Off) to 255 (top speed)

// Setting PWM properties
const int freq = 30000;
const int pwmChannel0 = 0;
const int pwmChannel1 = 1;
const int pwmChannel2 = 2;
const int pwmChannel3 = 3;
const int resolution = 8;
int dutyCycle = 200;

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // Disable brownout detector
    
  Serial.begin(115200);
  delay(1000);

  // testing
  Serial.print("Testing DC Motor...");

  Wire.end();                              // End default I2C (optional but good practice)
  Wire.setPins(I2C_SDA_PIN, I2C_SCL_PIN);  // Set custom pins: SDA to GPIO 27, SCL to GPIO 22
  Wire.begin();

  delay(1000);
  // sets the pins as outputs:
  pcf8575.pinMode(motor1Forward, OUTPUT);
  pcf8575.pinMode(motor1Back, OUTPUT);
  pcf8575.pinMode(motor2Forward, OUTPUT);
  pcf8575.pinMode(motor2Back, OUTPUT);
  pcf8575.pinMode(motor3Forward, OUTPUT);
  pcf8575.pinMode(motor3Back, OUTPUT);
  pcf8575.pinMode(motor4Forward, OUTPUT);
  pcf8575.pinMode(motor4Back, OUTPUT);

  pcf8575.pinMode(EnableMoror1, OUTPUT);
  pcf8575.pinMode(EnableMoror2, OUTPUT);
  pcf8575.pinMode(EnableMoror3, OUTPUT);
  pcf8575.pinMode(EnableMoror4, OUTPUT);

  pcf8575.begin();
  // Configure PWM for motor speed control using new API
  ledcAttachChannel(EnableMoror1, freq, resolution, pwmChannel0);
  ledcAttachChannel(EnableMoror2, freq, resolution, pwmChannel1);
  ledcAttachChannel(EnableMoror3, freq, resolution, pwmChannel2);
  ledcAttachChannel(EnableMoror4, freq, resolution, pwmChannel3);

  // Set initial PWM duty cycle to 0 (motors off)
  analogWrite(EnableMoror1, Motor1Speed);
  analogWrite(EnableMoror2, Motor2Speed);
  analogWrite(EnableMoror3, Motor3Speed);
  analogWrite(EnableMoror4, Motor4Speed);
}

void loop() {
  // Move the DC motor forward at maximum speed
  Serial.println("Moving motor 1 Forward");
  pcf8575.digitalWrite(motor1Forward, HIGH); 
  pcf8575.digitalWrite(motor1Back, LOW);
  Motor1Speed = 100; //Set speed
  analogWrite(EnableMoror1, Motor1Speed);  //Run at Motor1Speed speed
  delay(2000);
  AllMotorsOff();

  Serial.println("Moving motor 2 Forward");
  pcf8575.digitalWrite(motor2Forward, HIGH); 
  pcf8575.digitalWrite(motor2Back, LOW);
  Motor2Speed = 100; //Set speed
  analogWrite(EnableMoror2, Motor2Speed);  //Run at Motor2Speed speed
  delay(2000);
  AllMotorsOff();

  Serial.println("Moving motor 3 Forward");
  pcf8575.digitalWrite(motor3Forward, HIGH); 
  pcf8575.digitalWrite(motor3Back, LOW);
  Motor3Speed = 100; //Set speed
  analogWrite(EnableMoror3, Motor3Speed);  //Run at Motor3Speed speed
  delay(2000);
  AllMotorsOff();

  Serial.println("Moving motor 4 Forward");
  pcf8575.digitalWrite(motor4Forward, HIGH); 
  pcf8575.digitalWrite(motor4Back, LOW);
  Motor4Speed = 100; //Set speed
  analogWrite(EnableMoror4, Motor4Speed);  //Run at Motor3Speed speed
  delay(2000);
  AllMotorsOff();
}

void AllMotorsOff(){
  pcf8575.digitalWrite(motor1Forward, LOW);
  pcf8575.digitalWrite(motor1Back, LOW);
  pcf8575.digitalWrite(motor2Forward, LOW);
  pcf8575.digitalWrite(motor2Back, LOW);
  pcf8575.digitalWrite(motor3Forward, LOW);
  pcf8575.digitalWrite(motor3Back, LOW);
  pcf8575.digitalWrite(motor4Forward, LOW);
  pcf8575.digitalWrite(motor4Back, LOW); 
}

ERROR:

rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4980
load:0x40078000,len:16612
load:0x40080400,len:3500
entry 0x400805b4
Testing DC Motor...ets Jul 29 2019 12:21:46

rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4980
load:0x40078000,len:16612
load:0x40080400,len:3500
entry 0x400805b4

It was working until I added the motor speed coding for each of the 4 motors. The way it is written is pretty long winded. Once working I’ll shorten it.


Hi, @lexter333

Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

Please no Fritzy diagrams.

Can you post some images of your project?
So we can see your component layout.

Thanks... Tom.... :smiley: :+1: :coffee: :australia:

Does it keep crashing if you comment out everything inside the loop function?

TG1WDT <<

You can't eliminate a brownout issue in code. If the voltage to the ESP is still dropping below a certain voltage it will still reset.

It was working until I added the motor speed coding

You can't do PWM through the PCF8575.
Those pins need to be connected directly from the ESP to the L298 board.

It doesn’t have anything to do with the electronics. I’ve removed the ESP32 from the circuit and powered it up with the same result.

rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4980
load:0x40078000,len:16612
load:0x40080400,len:3500
entry 0x400805b4
Testing DC Motor...ets Jul 29 2019 12:21:46

rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4980
load:0x40078000,len:16612
load:0x40080400,len:3500
entry 0x400805b4
Testing DC Motor...

I’ve added a few serial prints in the setup and it fails at the ledcAttachChannel functions. It doesn’t go any further. To me it looks correct to me. Am I missing something?

#include <Wire.h>
#include "PCF8575.h"
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"

// Define the custom I2C pins
#define I2C_SDA_PIN 21
#define I2C_SCL_PIN 22

// Initialize the PCF8575 at address 0x20
PCF8575 pcf8575(0x20);

// Motor A
int motor1Forward = 1; 
int motor1Back = 0; 
int EnableMoror1 = 8;
int motor2Forward = 3; 
int motor2Back = 2; 
int EnableMoror2 = 9;
int motor3Forward = 4; 
int motor3Back = 5; 
int EnableMoror3 = 10;
int motor4Forward = 6; 
int motor4Back = 7; 
int EnableMoror4 = 11;

//Set motor Speeds
int Motor1Speed = 0; // 0 (Off) to 255 (top speed)
int Motor2Speed = 0; // 0 (Off) to 255 (top speed)
int Motor3Speed = 0; // 0 (Off) to 255 (top speed)
int Motor4Speed = 0; // 0 (Off) to 255 (top speed)

// Setting PWM properties
const int freq = 30000;
const int pwmChannel0 = 0;
const int pwmChannel1 = 1;
const int pwmChannel2 = 2;
const int pwmChannel3 = 3;
const int resolution = 8;
int dutyCycle = 200;

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // Disable brownout detector
    
  Serial.begin(115200);
  delay(1000);

  // testing
  Serial.print("Testing DC Motor...");

  Wire.end();                              // End default I2C (optional but good practice)
  Wire.setPins(I2C_SDA_PIN, I2C_SCL_PIN);  // Set custom pins: SDA to GPIO 27, SCL to GPIO 22
  Wire.begin();

  delay(1000);
  // sets the pins as outputs:
  Serial.println("Setting up PCF8575 pins...");
  pcf8575.pinMode(motor1Forward, OUTPUT);
  pcf8575.pinMode(motor1Back, OUTPUT);
  pcf8575.pinMode(motor2Forward, OUTPUT);
  pcf8575.pinMode(motor2Back, OUTPUT);
  pcf8575.pinMode(motor3Forward, OUTPUT);
  pcf8575.pinMode(motor3Back, OUTPUT);
  pcf8575.pinMode(motor4Forward, OUTPUT);
  pcf8575.pinMode(motor4Back, OUTPUT);

  pcf8575.pinMode(EnableMoror1, OUTPUT);
  pcf8575.pinMode(EnableMoror2, OUTPUT);
  pcf8575.pinMode(EnableMoror3, OUTPUT);
  pcf8575.pinMode(EnableMoror4, OUTPUT);
  Serial.println("Pins setup...");

  pcf8575.begin();
  Serial.println("pcf8575 began");
  
  Serial.println("Setting up ledcAttachChannel...");
  // Configure PWM for motor speed control using new API
  ledcAttachChannel(EnableMoror1, freq, resolution, pwmChannel0);
  ledcAttachChannel(EnableMoror2, freq, resolution, pwmChannel1);
  ledcAttachChannel(EnableMoror3, freq, resolution, pwmChannel2);
  ledcAttachChannel(EnableMoror4, freq, resolution, pwmChannel3);

  // Set initial PWM duty cycle to 0 (motors off)
  Serial.println("Setting up Speed...");
  analogWrite(EnableMoror1, Motor1Speed);
  analogWrite(EnableMoror2, Motor2Speed);
  analogWrite(EnableMoror3, Motor3Speed);
  analogWrite(EnableMoror4, Motor4Speed);
  Serial.println("Setup complete...");
}

void loop() {
  // Move the DC motor forward at maximum speed
  Serial.println("Moving motor 1 Forward");
  pcf8575.digitalWrite(motor1Forward, HIGH); 
  pcf8575.digitalWrite(motor1Back, LOW);
  Motor1Speed = 100; //Set speed
  analogWrite(EnableMoror1, Motor1Speed);  //Run at Motor1Speed speed
  delay(2000);
  AllMotorsOff();

  Serial.println("Moving motor 2 Forward");
  pcf8575.digitalWrite(motor2Forward, HIGH); 
  pcf8575.digitalWrite(motor2Back, LOW);
  Motor2Speed = 100; //Set speed
  analogWrite(EnableMoror2, Motor2Speed);  //Run at Motor2Speed speed
  delay(2000);
  AllMotorsOff();

  Serial.println("Moving motor 3 Forward");
  pcf8575.digitalWrite(motor3Forward, HIGH); 
  pcf8575.digitalWrite(motor3Back, LOW);
  Motor3Speed = 100; //Set speed
  analogWrite(EnableMoror3, Motor3Speed);  //Run at Motor3Speed speed
  delay(2000);
  AllMotorsOff();

  Serial.println("Moving motor 4 Forward");
  pcf8575.digitalWrite(motor4Forward, HIGH); 
  pcf8575.digitalWrite(motor4Back, LOW);
  Motor4Speed = 100; //Set speed
  analogWrite(EnableMoror4, Motor4Speed);  //Run at Motor3Speed speed
  delay(2000);
  AllMotorsOff();
}

void AllMotorsOff(){
  pcf8575.digitalWrite(motor1Forward, LOW);
  pcf8575.digitalWrite(motor1Back, LOW);
  pcf8575.digitalWrite(motor2Forward, LOW);
  pcf8575.digitalWrite(motor2Back, LOW);
  pcf8575.digitalWrite(motor3Forward, LOW);
  pcf8575.digitalWrite(motor3Back, LOW);
  pcf8575.digitalWrite(motor4Forward, LOW);
  pcf8575.digitalWrite(motor4Back, LOW); 
} 
rst:Setting up PCF8575 pins...
Pins setup...
pcf8575 began
Setting up ledcAttachChannel...
ets Jul 29 2019 12:21:46

rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4980
load:0x40078000,len:16612
load:0x40080400,len:3500
entry 0x400805b4
Testing DC Motor...

Yes, see post #5

Those pin numbers are not valid for the ledc functions

Pins 8,9,10,11 are connected to the flash, that is why it is resetting.

The ledc issue might need falling back ESP board support from 3.x to 2.x.

Sorry Jim, I missed your previous post. That now makes sense, I’ll give it a go today and let you know how I get on.

You can still use the PCF8575 for the INx pins but the enable pins for PWM need to be connected directly to the ESP. Also I would just use the Arduino analogWrite() and forget about the ledc stuff.

Now, time to have fun!

1 Like