BB8 Droid Coding - controlling BTS7960 motor driver via PS3 controller

Hi there,

I am building a functioning BB8 droid to use in my charity work for a local children’s hospital and have so far compiled a code which successfully controls three servos and activates sounds in the droid, all controlled via a PS3 controller.

My setup is a Mega with a USB host shield and BT dongle, connected via serial to an Uno running a MP3 shield (which is dedicated to producing the sound effects).

My final two challenges are controlling the main motors via a BTS7960 motor driver, and I was hoping someone might be able to help please?

I have a test rig consisting of LEDs/resistors on a breadboard in place of a motor driver to test the PWM output is working, but am having a little trouble with the code.

I modified the PWM code using an example of a sketch I found, and suspect that part of it is wrong. At the moment, the droid responds fine to the ‘old’ commands I previously had working (the three servos and sounds), but the moment I touch the ‘left analogue hat y axis’ to try the PWM output the droid stops responding.

Is there anything obvious that jumps out as being wrong in the code?

Here is the code which works fine (without the PWM addition)

/*
 Matthew Reading
 December 2017
 This is a modified version of the BT_RC_Trim.ino sketch by Barrett Anderies
 For more information visit my facebook page www.facebook.com/wellingtonironman
 */

#include <PS3BT.h>                                                    //Include the necessary libraries.
#include <Servo.h>
#include <SPI.h>

USB Usb;
BTD Btd(&Usb);
PS3BT PS3(&Btd); 

Servo servo1;                                                         //Create instances of type Servo. servo1 is the dome rotate servo and servo2 and servo3 is the head tilt.
Servo servo2;
Servo servo3;


void setup() {
  Serial.begin(115200);                                              
  if (Usb.Init() == -1) {                                            
    Serial.print(F("\r\nOSC did not start"));
    while(1); //halt
  }         
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  servo1.attach(5);                                                  //Dome rotate servo on digital pin 5
  servo2.attach(3);                                                  //head tilt right side on digital pin 3
  servo3.attach(4);                                                  //head tilt left side on digital pin 4
}
void loop() 
{
  Usb.Task();

  if(PS3.PS3Connected || PS3.PS3NavigationConnected) {
   
    servo1.write(map(PS3.getAnalogHat(RightHatX), 0, 255, 180, 0)); // write dome steer command
    servo2.write(map(PS3.getAnalogHat(RightHatY), 0, 255, 0, 135)); // write dome tilt command
    servo3.write(map(PS3.getAnalogHat(RightHatY), 0, 255, 180, 45));

    if (PS3.getButtonClick(L1))
      Serial.print(F("\r\n1"));
    if (PS3.getButtonClick(R1))
      Serial.print(F("\r\n2"));
    if (PS3.getButtonClick(L3))
      Serial.print(F("\r\n3"));
    if (PS3.getButtonClick(UP))
      Serial.print(F("\r\n4"));
    if (PS3.getButtonClick(R3))
      Serial.print(F("\r\n5"));
    if (PS3.getButtonClick(CIRCLE))
      Serial.print(F("\r\n+++++++++++++++++++6"));
    if (PS3.getButtonClick(DOWN))
      Serial.print(F("\r\n7"));
    if (PS3.getButtonClick(RIGHT))
      Serial.print(F("\r\n8"));
    if (PS3.getButtonClick(LEFT))
      Serial.print(F("\r\n9"));

    if (PS3.getButtonClick(PS))
      PS3.disconnect();

  }
  else
  {
    servo1.write(90);
    servo2.write(90);
    servo3.write(90);
  }
}

And here is the modified code which doesn’t work properly.

/*
 Matthew Reading
 December 2017
 This is a modified version of the BT_RC_Trim.ino sketch by Barrett Anderies
 For more information visit my facebook page www.facebook.com/wellingtonironman
 */

#include <PS3BT.h>                                                    //Include the necessary libraries.
#include <Servo.h>
#include <SPI.h>

USB Usb;
BTD Btd(&Usb);
PS3BT PS3(&Btd); 

Servo servo1;                                                         //Create instances of type Servo. servo1 is the dome rotate servo and servo2 and servo3 is the head tilt.
Servo servo2;
Servo servo3;

#define pwmA 9
#define pwmB 10
 
int motorSpeedFwd = 0;
int motorSpeedRev = 0;

void setup() {
  Serial.begin(115200);                                              
  if (Usb.Init() == -1) {                                            
    Serial.print(F("\r\nOSC did not start"));
    while(1); //halt
  }         
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  servo1.attach(5);                                                  //Dome rotate servo on digital pin 5
  servo2.attach(3);                                                  //head tilt right side on digital pin 3
  servo3.attach(4);                                                  //head tilt left side on digital pin 4
}
void loop() 
{
  Usb.Task();

  if(PS3.PS3Connected || PS3.PS3NavigationConnected) {
   
    servo1.write(map(PS3.getAnalogHat(RightHatX), 0, 255, 180, 0)); // write dome steer command
    servo2.write(map(PS3.getAnalogHat(RightHatY), 0, 255, 0, 135)); // write dome tilt command
    servo3.write(map(PS3.getAnalogHat(RightHatY), 0, 255, 180, 45));

    if (PS3.getButtonClick(L1))
      Serial.print(F("\r\n1"));
    if (PS3.getButtonClick(R1))
      Serial.print(F("\r\n2"));
    if (PS3.getButtonClick(L3))
      Serial.print(F("\r\n3"));
    if (PS3.getButtonClick(UP))
      Serial.print(F("\r\n4"));
    if (PS3.getButtonClick(R3))
      Serial.print(F("\r\n5"));
    if (PS3.getButtonClick(CIRCLE))
      Serial.print(F("\r\n+++++++++++++++++++6"));
    if (PS3.getButtonClick(DOWN))
      Serial.print(F("\r\n7"));
    if (PS3.getButtonClick(RIGHT))
      Serial.print(F("\r\n8"));
    if (PS3.getButtonClick(LEFT))
      Serial.print(F("\r\n9"));

    // Y-axis used for forward and backward control
if (PS3.getAnalogHat(LeftHatY) < 99) {
// Convert the declining Y-axis readings for going backward from into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedFwd = map(PS3.getAnalogHat(LeftHatY), 99, 0, 0, 255);
}
else if (PS3.getAnalogHat(LeftHatY) > 155) {
// Convert the increasing Y-axis readings for going forward into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedRev = map(PS3.getAnalogHat(LeftHatY), 155, 255, 0, 255);
}
// If joystick stays in middle the motors are not moving
else {
motorSpeedFwd = 0;
motorSpeedRev = 0;
}
// Prevent buzzing at low speeds (Adjust according to your motors)
if (motorSpeedFwd < 70) {
motorSpeedFwd = 0;
}
if (motorSpeedRev < 70) {
motorSpeedRev = 0;
}
analogWrite(pwmA, motorSpeedFwd); // Send PWM signal to motor driver Fwd
analogWrite(pwmB, motorSpeedRev); // Send PWM signal to motor driver Rev  

    if (PS3.getButtonClick(PS))
      PS3.disconnect();

  }
  else
  {
    servo1.write(90);
    servo2.write(90);
    servo3.write(90);
  }
}

Really appreciate any help you can give, thank you.

I’ve made a few changes to the code to fix obvious issues, but am still not able to get the pwm signal to work. The code works as normal until I touch the Left Analog hat and then it stops working entirely.

Is there anyone that might be able to see what I’m doing wrong please?

/*
Matthew Reading
December 2017
This is a modified version of the BT_RC_Trim.ino sketch by Barrett Anderies
For more information visit my facebook page www.facebook.com/wellingtonironman
*/

#include <PS3BT.h> //Include the necessary libraries.
#include <Servo.h>
#include <SPI.h>

USB Usb;
BTD Btd(&Usb);
PS3BT PS3(&Btd); 

Servo servo1; //Create instances of type Servo. servo1 is the dome rotate servo and servo2 and servo3 is the head tilt.
Servo servo2;
Servo servo3;

#define pwmA 9
#define pwmB 10

int motorSpeedFwd = 0;
int motorSpeedRev = 0;

void setup() {
Serial.begin(115200); 
if (Usb.Init() == -1) { 
Serial.print(F("\r\nOSC did not start"));
while(1); //halt
} 
pinMode(3, OUTPUT);
pinMode(5, OUTPUT);
pinMode(4, OUTPUT);
pinMode(pwmA, OUTPUT);
pinMode(pwmB, OUTPUT);
servo1.attach(5); //Dome rotate servo on digital pin 5
servo2.attach(3); //head tilt right side on digital pin 3
servo3.attach(4); //head tilt left side on digital pin 4
}
void loop() 
{
Usb.Task();

if(PS3.PS3Connected || PS3.PS3NavigationConnected) {

servo1.write(map(PS3.getAnalogHat(RightHatX), 0, 255, 180, 0)); // write dome steer command
servo2.write(map(PS3.getAnalogHat(RightHatY), 0, 255, 0, 135)); // write dome tilt command
servo3.write(map(PS3.getAnalogHat(RightHatY), 0, 255, 180, 45));

if (PS3.getButtonClick(L1))
Serial.print(F("\r\n1"));
if (PS3.getButtonClick(R1))
Serial.print(F("\r\n2"));
if (PS3.getButtonClick(L3))
Serial.print(F("\r\n3"));
if (PS3.getButtonClick(UP))
Serial.print(F("\r\n4"));
if (PS3.getButtonClick(R3))
Serial.print(F("\r\n5"));
if (PS3.getButtonClick(CIRCLE))
Serial.print(F("\r\n+++++++++++++++++++6"));
if (PS3.getButtonClick(DOWN))
Serial.print(F("\r\n7"));
if (PS3.getButtonClick(RIGHT))
Serial.print(F("\r\n8"));
if (PS3.getButtonClick(LEFT))
Serial.print(F("\r\n9"));

if (PS3.getAnalogHat(LeftHatY) < 99) {
motorSpeedFwd = (map(PS3.getAnalogHat(LeftHatY), 99, 0, 0, 255));
}
if (PS3.getAnalogHat(LeftHatY) > 155) {
motorSpeedRev = (map(PS3.getAnalogHat(LeftHatY), 155, 255, 0, 255));
}
if (PS3.getAnalogHat(LeftHatY) > 100 && PS3.getAnalogHat(LeftHatY) < 154) {
motorSpeedRev = 0;
motorSpeedFwd = 0;
}

analogWrite(pwmA, motorSpeedFwd); // Send PWM signal to motor driver Fwd
analogWrite(pwmB, motorSpeedRev); // Send PWM signal to motor driver Rev 

if (PS3.getButtonClick(PS))
PS3.disconnect();

}
else
{
servo1.write(90);
servo2.write(90);
servo3.write(90);
}
}

Fixed it. For future reference, dpins 9 and 10 are used by the USB shield. I recoded to pins 6 and 7 and it's working :)