Need help with ESP32, L298N Noise

Thread Starter

TGrundtvig

Joined Nov 13, 2024
2
I am doing a project making a 3D printed programmable trainset. I am using an L298N to drive two TT-motors (The common yellow ones used in many projects). Everything seemed to work fine and I could control the speed and direction of the motors. But now I need to add some micro switches that can read code-blocks in the tracks. I have attached the microswitches so they connect to ground, when activated and I have attached interrupt routines using the FALLING setting. I started out using the build-in pullup resistors and everything works, as long as the motors are not running. As soon as the motors start running I get a lot of false calls of my interrupt routines even though the microswitches are not activated. I have measured with an oscilloscope and there seems to be a lot of noise in the system that causes the false reads. I have tried external 5.1K ohm pullup resistors and added 100 pF capacitors to the motors, but nothing seems to help. Does anyone have similar experiences and maybe a solution. Right now I am out of options and this is completely stalling the project. Best regards Tobias.
 

Thread Starter

TGrundtvig

Joined Nov 13, 2024
2
Here is my simplified Code:
Code:
// Motor A
int motor1Pin1 = 27;
int motor1Pin2 = 26;
int enable1Pin = 14;
int switchFrontPin = 2;
int switchBackPin = 4;
int switchLeftPin = 5;
int switchRightPin = 15;

// Motor variables
const int freq = 30000;
const int pwmChannel = 0;
const int resolution = 8;
int dutyCycle = 0;
int targetDutyCycle = 0;
boolean forward = true;
unsigned int motorChangeTimeMicros = 10000;
unsigned long lastMotorChange = 0;

//Code block variables
enum STATE {RUNNING, STOPPED};
STATE state = STATE::STOPPED;
bool onBlock = false;
bool leftBit = false;
bool rightBit = false;
byte values[1024];
unsigned int valueIndex = 0;
unsigned int lastValueIndex = 0;
unsigned int blockCount = 0;
unsigned int lastBlockCount = 0;
unsigned long stoppedTime = 0;

//Interrupt functions:
void IRAM_ATTR switchFrontInterrupt()
{
    if(!onBlock)
    {
      onBlock = true;
      leftBit = false;
      rightBit = false;
    }
}

void IRAM_ATTR switchBackInterrupt()
{
    if(onBlock)
    {
      byte value = 0;
      if(leftBit)
      {
        value += 2;
      }
      if(rightBit)
      {
        value += 1;
      }
      values[valueIndex++] = value;
      if(valueIndex == 1024)
      {
        valueIndex = 0;
      }
      onBlock = false;
      ++blockCount;
    }
}

void IRAM_ATTR switchLeftInterrupt()
{
    leftBit = true;
}

void IRAM_ATTR switchRightInterrupt()
{
    rightBit = true;
}


void setup() {
  // sets the pins as outputs:
  pinMode(motor1Pin1, OUTPUT);
  pinMode(motor1Pin2, OUTPUT);
  pinMode(enable1Pin, OUTPUT);
  pinMode(switchFrontPin, INPUT_PULLUP);
  pinMode(switchBackPin, INPUT_PULLUP);
  pinMode(switchLeftPin, INPUT_PULLUP);
  pinMode(switchRightPin, INPUT_PULLUP);

  //Configure interrupts
  attachInterrupt(switchFrontPin, switchFrontInterrupt, FALLING);
  attachInterrupt(switchBackPin, switchBackInterrupt, FALLING);
  attachInterrupt(switchLeftPin, switchLeftInterrupt, FALLING);
  attachInterrupt(switchRightPin, switchRightInterrupt, FALLING);
 
  // configure LEDC PWM
  ledcAttachChannel(enable1Pin, freq, resolution, pwmChannel);
  Serial.begin(115200);
  Serial.println("Welcome!");
}

void loop()
{
  unsigned long curTime = micros();
  motorUpdate(curTime);
  if(blockCount != lastBlockCount)
  {
    Serial.print("BlockCount: ");
    Serial.println(blockCount);
    lastBlockCount = blockCount;
  }
  if(state == STATE::STOPPED && curTime > stoppedTime + 10000000)
  {
      Serial.println("Start train");
      setDirection(true);
      targetDutyCycle = 255;
      state = STATE::RUNNING;
  }
  else if(state == STATE::RUNNING && blockCount >= 3)
  {
    Serial.println("Stop train");
    targetDutyCycle = 0;
    blockCount = 0;
    stoppedTime = curTime;
    state = STOPPED;
  }
 
}

void motorUpdate(unsigned long curTimeMicros)
{
  if(targetDutyCycle != dutyCycle && curTimeMicros >= lastMotorChange + motorChangeTimeMicros)
  {
    if(dutyCycle > targetDutyCycle)
    {
      --dutyCycle;
    }
    else
    {
      ++dutyCycle;
    }
    lastMotorChange = curTimeMicros;
    ledcWrite(enable1Pin, dutyCycle);
  }
}

void setDirection(bool dir)
{
  forward = dir;
  digitalWrite(motor1Pin1, forward);
  digitalWrite(motor1Pin2, !forward);
}
 

MisterBill2

Joined Jan 23, 2018
27,160
You can also put capacitors across the motors.
Are the switches and their wires near the motors and their wires?? can you use shielded wiring??
 

MaxHeadRoom

Joined Jul 18, 2013
30,557
In the past I have used the designated pair L297/L298, Also are you using the Descrete IC or the popular L296 board.?
Do you have the Schottky diodes across the outputs.?
 

georgf

Joined Aug 12, 2021
12
those internal pull-up's of the ESP are very high value resistores, try put in a 1k pull-up, the schottky diodes cross the motor and to GND are a must to cut the reactive spikes from the motors inductivity, , are you using PWM as a motor control, try other frequency, capacitor cross the motor an other must.
 

georgf

Joined Aug 12, 2021
12
you may have a contaminated ground, check your ground wiring, as of the GND current of the motor drive is directly connected to the power source, you could check with oscilloscope
 

MisterBill2

Joined Jan 23, 2018
27,160
Consider that a DC motor needs voltage across the motor to run, how is putting diodes across the motor going to help?? Or are the diodes supposed to "clamp" the noise spikes? Is the diode really going to clamp by switching on at only 100 millivolts above the DC operating voltage.Also, consider that in a lot of electric trains the voltage is varied to control the speed. Yes, I am aware that many systems use PWM to control the train speed. Certainly capacitors across the motor and also a low resistance bifilar series filter choke, can pprobably help.
 

MisterBill2

Joined Jan 23, 2018
27,160
OK, those diodes are not really across the motor, but across the power supply. Interesting protection scheme for the driver IC. NOTE the capacitors across both voltage supplies.
 
Top