Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XBox 360 Stops Responding for Short Periods #166

Closed
benahrens opened this issue Jul 10, 2015 · 7 comments
Closed

XBox 360 Stops Responding for Short Periods #166

benahrens opened this issue Jul 10, 2015 · 7 comments

Comments

@benahrens
Copy link

Intro

I'm using an XBox 360 (Microsoft brand wired USB) with an Arduino Mega 2560 and Arduino USB Host Shield. The XBox input will be translated by the Arduino into PWM control of some hydraulic valves. Full code is listed below.

I currently have LEDs attached to the outputs as loads to easily show what the PWM is doing. My code basically works as expected with one very important catch.

The Problem

After anywhere from a couple seconds to 10-20 seconds, the LEDs stop responding to control from the XBox 360 controller. Based on debug print statements I added (not in the code below) I know the loop keeps going and Xbox.Xbox360Connected = true, but that LeftHatXCurr = Xbox.getAnalogHat(LeftHatX); is stuck on the same value instead of reflecting the way I manipulate the left hat. This continues for 3-10 seconds, sometimes longer, and then without my resetting or doing anything, everything works as expected again. It's possible I'm doing (or failing to do) something to cause this, so please take a look at my code and let me know whether I'm at fault or maybe there's something else at play.

The Code

#include <XBOXUSB.h>

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

USB Usb;
XBOXUSB Xbox(&Usb);
int16_t LeftHatXPrev, LeftHatYPrev, RightHatXPrev, RightHatYPrev;
int16_t LeftHatXCurr, LeftHatYCurr, RightHatXCurr, RightHatYCurr;
int16_t AnalogHatZeroThresh;
int16_t AnalogHatMoveThresh;


void setup() {
  AnalogHatMoveThresh = 500;
  AnalogHatZeroThresh = 8000;
  LeftHatXPrev = 0;
  LeftHatXCurr = 0;

  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\nXBOX USB Library Started"));
}

void loop() {
  Usb.Task();
  if (Xbox.Xbox360Connected)
  {
    // **Left Hat X**
    checkLeftHatX();

    // **Left Hat Y**
    checkLeftHatY();

    // **Right Hat X**
    checkRightHatX();

    // **Right Hat Y**
    checkRightHatY();
  }
  else
  {
    Serial.print("\nNot connected");
  }
  delay(100);
}

void checkLeftHatX()
{
  // Make sure stick has moved AnalogHatMoveThresh before changing output
  LeftHatXCurr = Xbox.getAnalogHat(LeftHatX);  
  if(((LeftHatXCurr > LeftHatXPrev) && (LeftHatXCurr - LeftHatXPrev > AnalogHatMoveThresh)) || ((LeftHatXCurr < LeftHatXPrev) && (LeftHatXPrev - LeftHatXCurr > AnalogHatMoveThresh)))
  {
    if(LeftHatXCurr > AnalogHatZeroThresh)
    {
      // Extend 
      analogWrite(5, (float)LeftHatXCurr/32768*255-1);
      analogWrite(4, 0);
    }
    else if (LeftHatXCurr < -AnalogHatZeroThresh)
    {
      // Retract
      analogWrite(5, 0);
      analogWrite(4, (-((float)LeftHatXCurr)/32768)*255-1);
    }
    else
    {
      analogWrite(5,0);
      analogWrite(4,0);
    }

    LeftHatXPrev = LeftHatXCurr;
  }
}

void checkLeftHatY()
{
  // Make sure stick has moved AnalogHatMoveThresh before changing output
  LeftHatYCurr = Xbox.getAnalogHat(LeftHatY);
  if(((LeftHatYCurr > LeftHatYPrev) && (LeftHatYCurr - LeftHatYPrev > AnalogHatMoveThresh)) || ((LeftHatYCurr < LeftHatYPrev) && (LeftHatYPrev - LeftHatYCurr > AnalogHatMoveThresh)))
  {
    if(LeftHatYCurr > AnalogHatZeroThresh)
    {
      // Extend 
      analogWrite(6, floor((float)LeftHatYCurr/32768*255));
      analogWrite(7, 0);
    }
    else if (LeftHatYCurr < -AnalogHatZeroThresh)
    {
      // Retract
      analogWrite(6, 0);
      analogWrite(7, (-((float)LeftHatYCurr)/32768)*255);
    }
    else
    {
      analogWrite(6,0);
      analogWrite(7,0);
    }

    LeftHatYPrev = LeftHatYCurr;     
  }
}

void checkRightHatX()
{
  // Make sure stick has moved AnalogHatMoveThresh before changing output
  RightHatXCurr = Xbox.getAnalogHat(RightHatX);  
  if(((RightHatXCurr > RightHatXPrev) && (RightHatXCurr - RightHatXPrev > AnalogHatMoveThresh)) || ((RightHatXCurr < RightHatXPrev) && (RightHatXPrev - RightHatXCurr > AnalogHatMoveThresh)))
  {
    if(RightHatXCurr > AnalogHatZeroThresh)
    {
      // Extend 
      analogWrite(5, (float)RightHatXCurr/32768*255-1);
      analogWrite(4, 0);
    }
    else if (RightHatXCurr < -AnalogHatZeroThresh)
    {
      // Retract
      analogWrite(5, 0);
      analogWrite(4, (-((float)RightHatXCurr)/32768)*255-1);
    }
    else
    {
      analogWrite(5,0);
      analogWrite(4,0);
    }

    RightHatXPrev = RightHatXCurr;
  }
}

void checkRightHatY()
{
  // Make sure stick has moved AnalogHatMoveThresh before changing output
  RightHatYCurr = Xbox.getAnalogHat(RightHatY);
  if(((RightHatYCurr > RightHatYPrev) && (RightHatYCurr - RightHatYPrev > AnalogHatMoveThresh)) || ((RightHatYCurr < RightHatYPrev) && (RightHatYPrev - RightHatYCurr > AnalogHatMoveThresh)))
  {
    if(RightHatYCurr > AnalogHatZeroThresh)
    {
      // Extend 
      analogWrite(6, floor((float)RightHatYCurr/32768*255));
      analogWrite(7, 0);
    }
    else if (RightHatYCurr < -AnalogHatZeroThresh)
    {
      // Retract
      analogWrite(6, 0);
      analogWrite(7, (-((float)RightHatYCurr)/32768)*255);
    }
    else
    {
      analogWrite(6,0);
      analogWrite(7,0);
    }

    RightHatYPrev = RightHatYCurr;     
  }
}
@Lauszus
Copy link
Collaborator

Lauszus commented Jul 11, 2015

Try to remove the 100 ms delay. You have to call the Usb.Task() function approximately every 1 ms.

If you still need the 100 ms delay you can use millis/micros instead: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay.

@benahrens
Copy link
Author

Changing to 1ms delay works just fine. If you have time I'd be interested in why the 1ms is important but my problem is fixed so I will not be offended if I don't hear from you. Thanks for your time/help.

Ben

@Lauszus
Copy link
Collaborator

Lauszus commented Jul 13, 2015

The thing is that you can't read from the Xbox controller to quickly, that is why there is a delay :)

@Lauszus
Copy link
Collaborator

Lauszus commented Jul 13, 2015

But it can't be too long either as you have to read from it continuously.

@xxxajk
Copy link
Contributor

xxxajk commented Jul 13, 2015

... and that's why the toggle was wrong? Sounds to me like a broken USB
device.

Well, at least in the 3.0 lib, you can just do this sort of thing in the
background without anything extra, since you would just schedule it to hit
every 1ms. :-)

On Mon, Jul 13, 2015 at 12:31 PM, Kristian Sloth Lauszus <
notifications@github.com> wrote:

But it can't be too long either as you have to read from it continuously.


Reply to this email directly or view it on GitHub
#166 (comment)
.

Visit my github for awesome Arduino code @ https://github.com/xxxajk

@benahrens
Copy link
Author

@xxxajk I'm not sure what you mean by "the toggle was wrong"?

@Lauszus
Copy link
Collaborator

Lauszus commented Jul 13, 2015

@xxxajk the toggle was not wrong. It was simply reading from the input endpoint top fast, but yes 3.0 should be able to take care of it automatically.

romerod pushed a commit to romerod/USB_Host_Shield_2.0 that referenced this issue Jul 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants