One button start, One button stop (C++)

So, frequently I had to change some of the controls in our team’s controller. one of those changes is to start and stop the selected motor with the same button. like I beat the button, the motor starts spinning. With the second click on the same button, the motor stops.
I searched about this topic but I didn’t see anything that can help me understand how I make this code. So, please if y’all have any idea about it, reply to me ASAP. Anything will be helpful!

i have a code like this on IQ, but also works on V5, just change the Controller button stuff

This dude made toggle code previously, go look Here

1 Like

That’s interesting!
but if I want to do the same thing with the same lines of code but on another button to reverse the motor and stop it.
I already tried to copy and paste those lines of code and change the variables and bools but suddenly it didn’t work as I wish :slightly_smiling_face: .

If you still need code, this should work fine for what you want.

int ButtonSetting = 0;

void ButtonCallback() {
  ButtonSetting = ButtonSetting + 1;
  if (ButtonSetting == 1) {
    Motor.spin(forward);
  }
  else if (ButtonSetting == 2) {
    Motor.stop();
  }
  else {
    ButtonSetting = 1;
    Motor.spin(forward)
  }
}

In driver control code call that function for the button you want using controller pressed function.


Do you mean like that?

Not really
you cannot have a function inside anther function (usercontrol in this case) in C, and I think @Skylynx1 intended that function to get called when the button is pressed by registering as a callback.
but there are simpler ways to do this, I’m sure a forum search will turn up something.

Oh, and I just noticed some else.
Don’t use Controller1.ButtonB.PRESSED unless you really understand it, it’s a mostly undocumented part of the VEX API.

4 Likes

Here, a couple of examples for you. Obviously move most of the code into usercontrol, except leave the event registration in main if you go that route.

This one using the button pressing() API, it detects the release to press transition.

example using pressing and state flags
/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Module:       main.cpp                                                  */
/*    Author:       james                                                     */
/*    Created:      2/16/2023, 8:38:46 PM                                     */
/*    Description:  EXP project                                               */
/*                                                                            */
/*----------------------------------------------------------------------------*/
#include "vex.h"

using namespace vex;

// A global instance of vex::brain used for printing to the V5 brain screen
vex::brain       Brain;

// define your global instances of motors and other devices here
vex::controller  Controller1;
vex::motor       m1(PORT1);

int main() {
    bool bButtonLast = false;
    bool bButtonState = false;

    while(1) {
        bool bButton = Controller1.ButtonB.pressing();

        // look for release to press transition  
        if( bButton && !bButtonLast ) {
          if( !bButtonState ) {
            bButtonState = true;
            m1.spin(forward, 50, rpm );
          }
          else {
            bButtonState = false;
            m1.stop();
          }
        }
        // save current button state        
        bButtonLast = bButton;


        // Allow other tasks to run
        this_thread::sleep_for(10);
    }
}

This one uses an event handler.

example using pressed callback
/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Module:       main.cpp                                                  */
/*    Author:       james                                                     */
/*    Created:      2/16/2023, 8:38:46 PM                                     */
/*    Description:  EXP project                                               */
/*                                                                            */
/*----------------------------------------------------------------------------*/
#include "vex.h"

using namespace vex;

// A global instance of vex::brain used for printing to the V5 brain screen
vex::brain       Brain;

// define your global instances of motors and other devices here
vex::controller  Controller1;
vex::motor       m1(PORT1);

void buttonHandler() {
    static bool bButtonState = false;

    if( !bButtonState ) {
      bButtonState = true;
      m1.spin(forward, 50, rpm );
    }
    else {
      bButtonState = false;
      m1.stop();
    }
}

int main() {
    Controller1.ButtonB.pressed( buttonHandler );

    while(1) {
        // Allow other tasks to run
        this_thread::sleep_for(10);
    }
}

and finally, this is how the special PRESSED API would be used.

This API was originally created for the block coding in the, now obsolete, vex coding studio application. It more or less does what my first example above does, that is, tracks the state of the button and reports if a released to press change has occurred since it was last called, once called the internal flag will be cleared. The advantage is this is happening inside vexos using the same code that also handles the conventional event handling.

undocumented PRESSED
int main() {
    bool bButtonState = false;

    while(1) {
        // look for special PRESSED event state
        if( Controller1.ButtonB.PRESSED ) {
          if( !bButtonState ) {
            bButtonState = true;
            m1.spin(forward, 50, rpm );
          }
          else {
            bButtonState = false;
            m1.stop();
          }
        }

        // Allow other tasks to run
        this_thread::sleep_for(10);
    }
}
7 Likes

Thanks a lot :saluting_face: !!
I will try it and I’ll inform you what happens.