Help, New to Arduino Programming.

I hope im posting this in the right place, but, Ive been trying to get my usb xbox controller to control a "car" I made using two servos and a caster wheel. the servos are futaba s3003 that have been modded for continuous rotation, 0-180, 90 being the stopping point. The code i used is derived from the xbox library provided with the usb host shield, modified to fit my needs. The code compiles, however only one servo responds to the xbox controller while the other just jerks, it does manage to jerk in the correct direction it just doesnt spin smoothly. If anyone can help me understand what it is I may be doing wrong and a way I can possibly get it fixed. Thank you, I hope i explained everything clearly.

#include <XBOXUSB.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <Servo.h>

Servo servoLeft;
Servo servoRight;
USB Usb;
XBOXUSB Xbox(&Usb);


void setup() {
Serial.begin(115200);
  while (!Serial);
  if (Usb.Init() == -1) {
  Serial.print(F("\r\nOSC did not start"));
  while (1);
  }
  Serial.print(F("\r\nXBOX USB Library Started"));
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  servoLeft.attach(3); 
  servoRight.attach(5);
}

void loop() {
  
  Usb.Task();
  
  if (Xbox.Xbox360Connected) {
 
    servoLeft.write(map(Xbox.getAnalogHat(RightHatY), 0, 32767, 90, 180));
     servoRight.write(map(Xbox.getAnalogHat(RightHatY), 0, 32767, 90, 0)); //this is the servo that im having problems with
}
  else
  servoLeft.write(90); 
  servoRight.write(90); 
}

I formatted your code:

void loop() {

  Usb.Task();

  if (Xbox.Xbox360Connected) {

    servoLeft.write(map(Xbox.getAnalogHat(RightHatY), 0, 32767, 90, 180));
    servoRight.write(map(Xbox.getAnalogHat(RightHatY), 0, 32767, 90, 0)); //this is the servo that im having problems with
  }
  else
    servoLeft.write(90); 
  servoRight.write(90);    // <----------- this is always done
}

http://www.gammon.com.au/forum/?id=12153#trap10

Thank you, that fixed my problem
I’m not sure if I would have to open another post about this, but I thought that if I could solve the previous problem, from my last post, then I could finally get the ‘car’ to turn, however I ran into the same problem. I’ve tried many different variations of the code, even separating the actions into two if statements to no avail. This is the final variation

#include <XBOXUSB.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <Servo.h>

Servo servoLeft;
Servo servoRight;
USB Usb;
XBOXUSB Xbox(&Usb);


void setup() {
  Serial.begin(115200);
  while (!Serial);
  if (Usb.Init() == -1) {
  Serial.print(F("\r\nOSC did not start"));
  while (1);
  } //end if
  Serial.print(F("\r\nXBOX USB Library Started"));
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  servoLeft.attach(3); 
  servoRight.attach(5);
} //end setup

void loop() {
  
  Usb.Task();
  
  if (Xbox.Xbox360Connected) {
 
     servoRight.write(map(Xbox.getAnalogHat(RightHatY), 0, 32767, 90, 180));
     servoLeft.write(map(Xbox.getAnalogHat(RightHatY), 0, 32767, 90, 0));
     servoRight.write(map(Xbox.getAnalogHat(LeftHatX), 0, 32767, 90, 0)); //this is where i tried to seperate this into its own if statement which also did not work
     servoLeft.write(map(Xbox.getAnalogHat(LeftHatX), 0, 32767, 90, 0));
  } //end if
  
  //else i tried the else statement with ServoRight and ServoLeft together and apart but still face the same problem
  //servoRight.write(90); 
  //servoLeft.write(90);

} //end

I’m having the same problem as before where the servos manage to jerk in the correct direction however they don’t spin smoothly as they did when I took the line out as Nick Gammon instructed. Again I am a beginner with this, so I apologize in advance if these are simple problems, but I lack in programming experience. Thank you.

I’m using the RightHatY to make the ‘car’ move forward and backwards and the LeftHatX to move it left and right.

You should get in the habit of putting the { on a new lines AND properly indenting your code.

  if (Usb.Init() == -1)
  {
     Serial.print(F("\r\nOSC did not start"));
     while (1);
  } //end if

is so much clearer (to me, at least) than

  if (Usb.Init() == -1) {
  Serial.print(F("\r\nOSC did not start"));
  while (1);
  } //end if
     servoRight.write(map(Xbox.getAnalogHat(RightHatY), 0, 32767, 90, 180));

What did you read from the XBox thing? What did you map it to? When you write code like this, you can't tell. This is "cross your fingers and hope it works" code.

     int rightVal = Xbox.getAnalogHat(RightHatY);
     int rightMap = map(rightVal, 0, 32767, 90, 180);
     servoRight.write(rightMap);

Now, if there are questions, you can Serial.print() rightVal and rightMap and see where the problems are.

     servoRight.write(map(Xbox.getAnalogHat(RightHatY), 0, 32767, 90, 180));
     servoLeft.write(map(Xbox.getAnalogHat(RightHatY), 0, 32767, 90, 0));
     servoRight.write(map(Xbox.getAnalogHat(LeftHatX), 0, 32767, 90, 0)); //this is where i tried to seperate this into its own if statement which also did not work
     servoLeft.write(map(Xbox.getAnalogHat(LeftHatX), 0, 32767, 90, 0));

Two servos, 4 write statements, with input from two different sources. Something doesn't feel right, here.

I apologize i will be sure to practice better programming etiquette.

In the xboxusb example code the serial prints that in all directions for both hats the values range from -32768 to 32767, 0 is the position where the hats are at rest. I know that the servos range from 0 to 180, 90 being the position of no movement. so the map was to try and relate those values to one another, which worked in the first step when trying to get the 'car' to move forward and backward by moving the RightHat in the +Y and -Y directions. How ever as you mentioned when I tried to repeat the same for the X movements the servos don't move, and I'm assuming, by what you said, that its because I'm telling the servos to write 4 different positions form 2 sources. Hope I was able to explain my thought process. Thank you.

which worked in the first step when trying to get the 'car' to move forward and backward by moving the RightHat in the +Y and -Y directions.

So, if movement of the stick in the Y direction is to move the car forwards or backwards (strange to use Y for that), what is movement in the X direction supposed to do?

And, yes, you are confusing the hell out of the servos right now.

The x direction will be used to turn the 'car', left and right movements.

@Pauls: Several times I've seen where you prefer the brace style mentioned above. My preference is:

if (Usb.Init() == -1)  {
  Serial.print(F("\r\nOSC did not start"));
  while (1)
    ;
} //end if

which I find every bit as easy to read, plus I get to see one more line of the source file. I think that, the more source you can see at one time, the easier it is to read the code. Given the few nano acres of screen space we have, I think this style is every bit as acceptable...just a matter of taste.

A braces war! :slight_smile:

 if (Usb.Init() == -1)
  {
     Serial.print(F("\r\nOSC did not start"));
     while (1);
  } //end if

That makes more sense to me. The two braces are lined up. Although we could probably tidy it up a bit ...

 if (Usb.Init() == -1)
    {
     Serial.print(F("\r\nOSC did not start"));
     while (true) 
       { }
    } //end if

Now the whole "if" block is indented the same amount. Makes sense to me. :wink:

The x direction will be used to turn the 'car', left and right movements.

How? How is this physically going to happen?

The only way that it can happen on a two-wheel (or track) drive vehicle is to make one motor turn faster than the other.

So, your X values are going to have to be used to create a difference between the right and left speeds. The larger the value, the larger the difference. A positive value means the right side runs slower. A negative value means that the left side runs slower.

There are only going to be two Servo::write() calls, with different values.

@Nick: Naw, not a war, just an alternative style. I started out with K and R back in the late 1970’s when many displays only had 16 lines and got used to that style. For me, the extra line for the brace makes it no more readable than before, but that’s because of what I’m used to.

That said, I would never advocate the style that has:

while (1) ;

How many times have we seen on this Forum something like

for (int i = 0; i < MAX; i++) ;   <-- Opps~
   Serial.println(msg[i]);

or something similar with another loop form? Also, I would always suggest using braces with any keyword (e.g., if, for do, while, switch, etc.) that can define a statement block even though it may not be required. I that sense, I like your while better than Paul’s. It makes the statement block more clear and, many times, you end up adding a line either to debug or correct the block anyway…may as well start out with it in place.

Again, it a matter of style so no one way is going to win the hearts of all.