Controlling Servo with a PS4 controller

Hi everybody. For my first arduino project I am buidling a PS4 controller controlled ''RC" car. I just got the motor control to work but now i am having issues with the steering which is done with a SG92R servo. When i try to make the servo do anything in my existing code for the RC car it doesn't work but when I try the exact same thing out of context(so in a different file with nothing but the servo code) it does work. Can anyone spot the problem? Any advice/help would be greatly appreciated.

so here it doesn't work:

#include <PS4BT.h>
#include <usbhub.h>
#include <Servo.h>;


// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>

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;

Servo servo;
int angle = 90;



void setup() {


  pinMode(6, OUTPUT);  //motor PWM
  pinMode(5, OUTPUT);  //motor direction
  pinMode(4, OUTPUT);  //motor direction
  servo.attach(11);
  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() {
  // put your main code here, to run repeatedly:
servo.write(180); //why does this not work???

  Usb.Task();

  if (PS4.connected()) {

    if (abs(PS4.getAnalogButton(R2)-oldR2Value)> 5 && PS4.getAnalogButton(R2)> 5) {
      oldR2Value = PS4.getAnalogButton(R2);
      Serial.print(oldR2Value);
      analogWrite(6, map(oldR2Value, 0, 255, 150, 255));
      digitalWrite(5, LOW);
      digitalWrite(4, HIGH);
    }
    else if (abs(PS4.getAnalogButton(L2)-oldL2Value)> 5 && PS4.getAnalogButton(L2)> 5) {
      oldL2Value = PS4.getAnalogButton(L2);
      Serial.print(oldL2Value);
      analogWrite(6, map(oldL2Value, 0, 255, 150, 255));
      digitalWrite(5, HIGH);
      digitalWrite(4, LOW);
    }
    else if (PS4.getAnalogButton(L2) < 5 && PS4.getAnalogButton(R2) < 5){
      digitalWrite(6, 0); 
     
    }


  }
   
    
   if (PS4.getButtonClick(PS)) {
    Serial.print(F("\r\nPS"));
    PS4.disconnect();
}
}

But this does work:

#include <Servo.h>;

Servo servo;
int angle = 10;

void setup() {
  // put your setup code here, to run once:
servo.attach(11);
servo.write(angle);
}

void loop() {

servo.write(180);
}

I guess there is some incompatibility between Servo.h and one of the other libraries you have included. You could add them to your simple code one by one until it stops working. Or it may be a timer problem so you could change Servo.h to ServoTimer2.h and see if that helps.

But just for interest why do you want to to keep on writing 180 to your servo over and over and over again? That doesn't seem likely to do any useful steering.

Steve

hahah no first i mapped the left joystick of the controller against the 180 degrees of the motor so:
servo.write(map(PS4.getAnalogHat(LeftHatX), 0, 255, 0, 180)
but i wanted see if the bare minimum would work and work up from there but it didnt.
thanks for the advice!! i am definetely gonna try it

Hi @thijsvannoordt , How did you solve it in the end? I'm facing the same issue.

Hi wardman, it was a while ago but i think i switched around the servo wires because not all digital ports on the UNO act the same, who knew!(probably everyone but me). so maybe just try out all available ports to see if another port does work, just in case this is my code:

//#include <NewPing.h>
#include <ServoTimer2.h>
#include <PS4BT.h>
#include <usbhub.h>



// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>
//NewPing sonar(10, 11, 50);
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(6, OUTPUT);  //motor PWM
  pinMode(5, OUTPUT);  //motor direction
  pinMode(4, OUTPUT);  //motor direction
  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() {
  // put your main code here, to run repeatedly:
//Serial.println(sonar.ping_cm());

  Usb.Task();

  if (PS4.connected()) {

    servo.write(map(PS4.getAnalogHat(LeftHatX), 255, 0, 1100, 2044));
    Serial.println(PS4.getAnalogHat(LeftHatX));
    if (abs(PS4.getAnalogButton(R2)-oldR2Value)> 5 && PS4.getAnalogButton(R2)> 5) {
      oldR2Value = PS4.getAnalogButton(R2);
      //Serial.print(oldR2Value);
      analogWrite(6, map(oldR2Value, 0, 255, 150, 255));
      digitalWrite(5, LOW);
      digitalWrite(4, HIGH);
      
    }
  //  else if (abs(PS4.getAnalogButton(R2)-oldR2Value)> 5 && PS4.getAnalogButton(R2)> 5 && sonar.ping_cm() < 10 )  {
  //    analogWrite(6, 100);
  //    digitalWrite(5, LOW);
  //    digitalWrite(4, HIGH);

  //  }
      
    else if (abs(PS4.getAnalogButton(L2)-oldL2Value)> 5 && PS4.getAnalogButton(L2)> 5) {
      oldL2Value = PS4.getAnalogButton(L2);
      //Serial.print(oldL2Value);
      analogWrite(6, map(oldL2Value, 0, 255, 150, 255));
      digitalWrite(5, HIGH);
      digitalWrite(4, LOW);
    }
    
    else if (PS4.getAnalogButton(L2) < 5 && PS4.getAnalogButton(R2) < 5){
      digitalWrite(6, 0); 
    }


  }
   
    
   if (PS4.getButtonClick(PS)) {
    Serial.print(F("\r\nPS"));
    PS4.disconnect();
}
}

looking at my code again (after a while), i see that i am mapping the input from the controller from 1100 to 2044 maybe also check the u are mapping the right values

oh and i used the different library ServoTimer2.h. that was very important i think, im sorry im all over the place it was a while ago