Motor won't run backwards with UNO and L298N

Hi, I'm new to Arduino and to the forum and I was hoping for some help.
I'm attempting to control 2 motors and a servo with a PS4 controller using an Arduino UNO and an L298N motor controller but I've encountered issues.
The system mostly worked except the motors spinning at different speeds, which I assumed was a resistance issue until I introduced the servo and the motor connected to IN3 and IN4 wouldn't spin backwards for some reason.
I tried reverting the code, switching out components for new ones, switching the motors, changing the Arduino, motor controller, USB shield to try and solve this but no luck, I've also reassembled it dozens of times and this issue was always present, so I doubt this problem is due to assembly.

I altered the code to change what buttons controlled what and that's how I discovered that one of the motors wouldn't spin backwards, by which point it had changed so that IN3 and IN4 worked fine and now IN1/IN2 are the issue.

I'm using a modified version of code I found online on maker.pro

Also currently the R1/R2 controls don't work but I'm pretty sure that's because I wrote them in wrong.

//Source Code
#include <PS4BT.h>
#include <usbhub.h>
#include <ServoTimer2.h>

// Satisfy the IDE, which needs to see the include statement in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>
int IN1 = 3;       //control pin for first motor
int IN2 = 4;       //control pin for first motor
int IN3 = 5;        //control pin for second motor
int IN4 = 6;        //control pin for second motor
USB Usb;
//USBHub Hub1(&Usb); // Some dongles have a hub inside
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so

/* You can create the instance of the PS4BT class in two ways */
// This will start an inquiry and then pair with the PS4 controller - you only have to do this once
// You will need to hold down the PS and Share button at the same time, the PS4 controller will then start to blink rapidly indicating that it is in pairing mode
PS4BT PS4(&Btd, PAIR);

// After that you can simply create the instance like so and then press the PS button on the device
//PS4BT PS4(&Btd);

bool printAngle, printTouch;
uint8_t oldL2Value, oldR2Value;

ServoTimer2 servo;
int angle = 927;

void setup() {
   pinMode(IN1, OUTPUT);  
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);  
  pinMode(IN4, OUTPUT);
  servo.attach(7);
  servo.write(angle);

  Serial.begin(115200);
#if !defined(__MIPSEL__)
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); // Halt
  }
  Serial.print(F("\r\nPS4 Bluetooth Library Started"));

}
void loop() {
  Usb.Task();

  if (PS4.connected()) {
  //  if (PS4.getAnalogHat(LeftHatX) > 137 || PS4.getAnalogHat(LeftHatX) < 117 || PS4.getAnalogHat(LeftHatY) > 137 || PS4.getAnalogHat(LeftHatY) < 117 || PS4.getAnalogHat(RightHatX) > 137 || PS4.getAnalogHat(RightHatX) < 117 || PS4.getAnalogHat(RightHatY) > 137 || PS4.getAnalogHat(RightHatY) < 117) {
      if (PS4.getAnalogButton(L2) != oldL2Value)
      {
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    Serial.print("\nFORWARDS ");
        }
      else if (PS4.getAnalogButton(R2) != oldR2Value)
      {
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);

    Serial.print("\nBACKWARDS ");
        }
        else if (PS4.getButtonClick(L1))
        {
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    Serial.print("\nLEFT ");
          }
          else if (PS4.getButtonClick(R1))
        {
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
        Serial.print("\nRIGHT ");
          }
          else {
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
    Serial.print("\nNEUTRAL ");
          }
             { servo.write(map(PS4.getAnalogHat(RightHatX), 255, 0, 1100, 2044));
    Serial.println(PS4.getAnalogHat(RightHatX));
  }
      
}
}

Is this valid code?
And if so: what is it supposed to do?
It seems a mixup of C code and a pre compiler directive.

Please autoformat your code and post again. (Ctrl-t in IDE).

I am not familiar with PS4BT.
Trouble shooting is best done by adding Serial.print("some relevant message"); as the first line in each if block... that way you can see if the if block is executed or not.

1 Like

The chance of getting the exact same value from an analog controller twice is pretty low...
Also the oldL2Value is never changed in your program...

I managed to get the L2 button to control it through just sticking it in and seeing what happened and that worked so I just didn't question it.

That if !defined thing was always there and all the code validated so I have zero clue what it does but it never seemed to cause any problems when my motors were working, majority of the code comes from https://maker.pro/arduino/projects/how-to-control-an-arduino-robot-with-a-ps4-bluetooth-controller, the servo was from me and I ended up changing the controls to L2/R2 etc simply to see if that would make it work.

Add a Serial.print to see the value that is returned from
PS4.getAnalogButton(L2)
See if it ever gets 0....

This sequence usually makes the vehicle rotate right because one motor is mounted in the opposite orientation. The IN1/IN2 motor pushing forward and the IN3/IN4 motor pushing the opposite of forward... resulting in a right rotation.

So, when you say "backwards" is that because the display is showing "backwards?"

    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);

    Serial.print("\nBACKWARDS ");

This routine rotates the vehicle left (IN1/IN2 backwards, IN3/IN4 opposite of backwards).

The wiring's set up so they both spin the right way I want, the issues with one of the motors just doesn't get power sometimes, or both, or neither, its very random and all over the place.

Show a drawing of the devices.

  • The 'car' does not turn because you are checking getButtonClick ( which is true only in the exact moment you press the button ) use instead getButtonPress ( which is true as long as you press the button ).
  • Also comparing getAnalogButton() with an unitialized variable is not a good idea. Compare it with a 'threshold' value, 128 for example ( I assume that function returns 0 when the button is not pressed and 255 when pressed, but not sure about that )
  • verify also the output on the debug monitor, is your friend in understanding what's going on, you should have a 'series of equal strings' as long as you press a button ( ex: forwards, forwards, forwards... ) and you should not have any 'neutral' string in between ( if this is the case it means something is not working as it should )