user35678: I am working on a project of a robot arm. The joints are made of servo motor. The basic function can be describe as:

The robot arm (the servos) were moved manually by the Logitech joystick.
The user could press a certain button to remember a position. I made 6 buttons for 6 positions, in detail.
After the remembering, if an activating button was pressed, the robot arm would move repeatedly around those 6 positions until a stopping button was pressed.

The problem was the bold words.
In order to make the robot arm could move repeatedly with one pressing, I used a while loop.
However, when the program was in while loop, the joystick events stopped updating no matter how I pressed or pulled the joystick. Therefore, I couldn't program a stopping button.
I guessed that was because the joystick events were called outside the loop, but I don't know how to get it inside. My code was based on the example of the USB Host Shield library.
Here is the code. It contained 3 files. My robot also has some more function so I only quote the part that I had problem here.
.ino file:

#include <usbhid.h>
#include <hiduniversal.h>
#include <usbhub.h>
#include "le3dp_rptparser.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;
USBHub                                          Hub(&Usb);
HIDUniversal                                    Hid(&Usb);
JoystickEvents                                  JoyEvents;
JoystickReportParser                            Joy(&JoyEvents);

//int waist_back, shoulder_back, wrist_back, gripper_back;

void setup()
{
  Serial.begin( 115200 );
#if !defined(__MIPSEL__)
  while (!Serial);
#endif
  Serial.println("Start");

   if (Usb.Init() == -1)
       Serial.println("OSC did not start.");

  delay( 200 );

  if (!Hid.SetReportParser(0, &Joy))
      ErrorMessage<uint8_t>(PSTR("SetReportParser"), 1  );

}

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

.cpp file: This was where I worked. Please look at the JoystickEvents::OnGamePadChanged
#include "le3dp_rptparser.h"

//Many parameters for robot here

JoystickReportParser::JoystickReportParser(JoystickEvents *evt) :
    joyEvents(evt)
{}

void JoystickReportParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
{
    bool match = true;

    // Checking if there are changes in report since the method was last called
    for (uint8_t i=0; i<RPT_GAMEPAD_LEN; i++) {
        if( buf[i] != oldPad[i] ) {
            match = false;
            break;
        }
  }
    // Calling Game Pad event handler
    if (!match && joyEvents) {
        joyEvents->OnGamePadChanged((const GamePadEventData*)buf);

        for (uint8_t i=0; i<RPT_GAMEPAD_LEN; i++) oldPad[i] = buf[i];
    }
}

void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt)
{
  Serial.print("X: ");
  Serial.print(evt->x);
  Serial.print(" Y: ");
  Serial.print(evt->y);
  Serial.print(" Hat Switch: ");
  Serial.print(evt->hat);
  Serial.print(" Twist: ");
  Serial.print(evt->twist);
  Serial.print(" Slider: ");
  Serial.print(evt->slider);
  Serial.print(" Buttons A: ");
  Serial.print(evt->buttons_a);
  Serial.print(" Buttons B: ");
  Serial.print(evt->buttons_b);
  Serial.println("");

  // Manual control program here. I didn't post because it was so long.


  //Activation

  if (evt->buttons_a == 32){
    while (evt->slider == 0){

    //Robot working here, also a long code that was out of limit for a block here.

    Serial.print(evt->slider);
    }
  }
}

.h file:
#if !defined(__HIDJOYSTICKRPTPARSER_H__)
#define __HIDJOYSTICKRPTPARSER_H__

#include <usbhid.h>

struct GamePadEventData
{
  union { //axes and hut switch
    uint32_t axes;
    struct {
      uint32_t x : 10;
      uint32_t y : 10;
      uint32_t hat : 4;
      uint32_t twist : 8;      
    };
  };
  uint8_t buttons_a;
  uint8_t slider;
  uint8_t buttons_b;
};

class JoystickEvents
{
public:
    virtual void OnGamePadChanged(const GamePadEventData *evt);
  static GamePadEventData mostRecentEvent;
};

#define RPT_GAMEPAD_LEN sizeof(GamePadEventData)/sizeof(uint8_t)

class JoystickReportParser : public HIDReportParser
{
    JoystickEvents      *joyEvents;

  uint8_t oldPad[RPT_GAMEPAD_LEN];

public:
    JoystickReportParser(JoystickEvents *evt);

    virtual void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
};

#endif // __HIDJOYSTICKRPTPARSER_H__

After the //Activation under JoystickEvents::OnGamePadChanged, no matter how I pulled the slider of the joystick, the event was not updated, the evt->slider always returned zero and the robot arm couldn't be stopped.
Is there any method to update the joystick event inside the while loop?
Or another method other than while loop to make something move repeatedly after pressing one button, and can be stopped with another button?
Thank you so much for reading, and please help me!

user35247: As full code is not posted I cant suggest you correctly but you should add the two buttons, START & STOP.
When STOP button is pressed all events (your code is performing on) should stop working.
Just make sure when you program for a joystick control, the code for START & STOP buttons  should fall under the joystick control loop.
if (STOP PRESSED){

}else if(START PRESSED){

    //INVOKE THE FUNCTIONS FOR ACTIONS TO BE PERFORMED
}


35678: <p>I am working on a project of a robot arm. The joints are made of servo motor. The basic function can be describe as:</p>

<ul>
<li>The robot arm (the servos) were moved manually by the Logitech joystick.</li>
<li>The user could press a certain button to remember a position. I made 6 buttons for 6 positions, in detail.</li>
<li>After the remembering, if an activating button was pressed, the robot arm would move repeatedly around those 6 positions <strong>until a stopping button was pressed</strong>.</li>
</ul>

<p>The problem was the bold words.</p>

<p>In order to make the robot arm could move repeatedly with one pressing, I used a <code>while</code> loop.</p>

<p>However, when the program was in <code>while</code> loop, the joystick events stopped updating no matter how I pressed or pulled the joystick. Therefore, I couldn't program a stopping button.</p>

<p>I guessed that was because the joystick events were called outside the loop, but I don't know how to get it inside. My code was based on the example of the USB Host Shield library.</p>

<p>Here is the code. It contained 3 files. My robot also has some more function so I only quote the part that I had problem here.</p>

<p>.ino file:
</p>

<pre class="lang-cpp prettyprint-override"><code>#include &lt;usbhid.h&gt;
#include &lt;hiduniversal.h&gt;
#include &lt;usbhub.h&gt;
#include "le3dp_rptparser.h"
// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include &lt;spi4teensy3.h&gt;
#include &lt;SPI.h&gt;
#endif

USB                                             Usb;
USBHub                                          Hub(&amp;Usb);
HIDUniversal                                    Hid(&amp;Usb);
JoystickEvents                                  JoyEvents;
JoystickReportParser                            Joy(&amp;JoyEvents);

//int waist_back, shoulder_back, wrist_back, gripper_back;

void setup()
{
  Serial.begin( 115200 );
#if !defined(__MIPSEL__)
  while (!Serial);
#endif
  Serial.println("Start");

   if (Usb.Init() == -1)
       Serial.println("OSC did not start.");

  delay( 200 );

  if (!Hid.SetReportParser(0, &amp;Joy))
      ErrorMessage&lt;uint8_t&gt;(PSTR("SetReportParser"), 1  );

}

void loop()
{
    Usb.Task();
}
</code></pre>

<p>.cpp file: This was where I worked. Please look at the <code>JoystickEvents::OnGamePadChanged</code></p>

<pre class="lang-cpp prettyprint-override"><code>#include "le3dp_rptparser.h"

//Many parameters for robot here

JoystickReportParser::JoystickReportParser(JoystickEvents *evt) :
    joyEvents(evt)
{}

void JoystickReportParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
{
    bool match = true;

    // Checking if there are changes in report since the method was last called
    for (uint8_t i=0; i&lt;RPT_GAMEPAD_LEN; i++) {
        if( buf[i] != oldPad[i] ) {
            match = false;
            break;
        }
  }
    // Calling Game Pad event handler
    if (!match &amp;&amp; joyEvents) {
        joyEvents-&gt;OnGamePadChanged((const GamePadEventData*)buf);

        for (uint8_t i=0; i&lt;RPT_GAMEPAD_LEN; i++) oldPad[i] = buf[i];
    }
}

void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt)
{
  Serial.print("X: ");
  Serial.print(evt-&gt;x);
  Serial.print(" Y: ");
  Serial.print(evt-&gt;y);
  Serial.print(" Hat Switch: ");
  Serial.print(evt-&gt;hat);
  Serial.print(" Twist: ");
  Serial.print(evt-&gt;twist);
  Serial.print(" Slider: ");
  Serial.print(evt-&gt;slider);
  Serial.print(" Buttons A: ");
  Serial.print(evt-&gt;buttons_a);
  Serial.print(" Buttons B: ");
  Serial.print(evt-&gt;buttons_b);
  Serial.println("");

  // Manual control program here. I didn't post because it was so long.


  //Activation

  if (evt-&gt;buttons_a == 32){
    while (evt-&gt;slider == 0){

    //Robot working here, also a long code that was out of limit for a block here.

    Serial.print(evt-&gt;slider);
    }
  }
}
</code></pre>

<p>.h file:</p>

<pre class="lang-cpp prettyprint-override"><code>#if !defined(__HIDJOYSTICKRPTPARSER_H__)
#define __HIDJOYSTICKRPTPARSER_H__

#include &lt;usbhid.h&gt;

struct GamePadEventData
{
  union { //axes and hut switch
    uint32_t axes;
    struct {
      uint32_t x : 10;
      uint32_t y : 10;
      uint32_t hat : 4;
      uint32_t twist : 8;      
    };
  };
  uint8_t buttons_a;
  uint8_t slider;
  uint8_t buttons_b;
};

class JoystickEvents
{
public:
    virtual void OnGamePadChanged(const GamePadEventData *evt);
  static GamePadEventData mostRecentEvent;
};

#define RPT_GAMEPAD_LEN sizeof(GamePadEventData)/sizeof(uint8_t)

class JoystickReportParser : public HIDReportParser
{
    JoystickEvents      *joyEvents;

  uint8_t oldPad[RPT_GAMEPAD_LEN];

public:
    JoystickReportParser(JoystickEvents *evt);

    virtual void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
};

#endif // __HIDJOYSTICKRPTPARSER_H__
</code></pre>

<p>After the <code>//Activation</code> under <code>JoystickEvents::OnGamePadChanged</code>, no matter how I pulled the slider of the joystick, the event was not updated, the <code>evt-&gt;slider</code> always returned zero and the robot arm couldn't be stopped.</p>

<p>Is there any method to update the joystick event inside the <code>while</code> loop?</p>

<p>Or another method other than <code>while</code> loop to make something move repeatedly after pressing one button, and can be stopped with another button?</p>

<p>Thank you so much for reading, and please help me!</p>
 35247: <p>As full code is not posted I cant suggest you correctly but you should add the two buttons, START &amp; STOP.</p>

<p>When STOP button is pressed all events (your code is performing on) should stop working.</p>

<p>Just make sure when you program for a joystick control, the code for START &amp; STOP buttons  should fall under the joystick control loop.</p>

<pre><code>if (STOP PRESSED){

}else if(START PRESSED){

    //INVOKE THE FUNCTIONS FOR ACTIONS TO BE PERFORMED
}
</code></pre>
