Programming Help: Press and Release

I need help programming a certain function. I am use to programming a button on a VEX remote to do the action while being held down, and doing nothing when the button is not held down. Now I need to program a function so that when I press the button down and then release, the motor will start up and continue to move forever until I press and release another button which reverses it, then when I press and release another button, it will stop. Here is my code which only makes the motor work while the button is pressed. Can someone show me how to program this piece of code so that When I press and release button 6U the two motors will go full speed, and when I press and release button 6D, the two motors will reverse, and then when I press button 8D, the two motors will stop. If anyone can help, I would appreciate it! Thanks in advance.

	if(vexRT[Btn6UXmtr2] == 1) //if button 6U is pressed on the partner remote
	{
		motor(leftflywheel) = 127; //the flywheel will launch balls into the air
		motor(rightflywheel) = 127; //the flywheel will launch balls into the air
	}
	else if(vexRT[Btn6DXmtr2] == 1) //if button 6D is pressed on the partner remote
	{
		motor(leftflywheel) = -127; //the flywheel will travel in the opposite direction, not launching the ball
		motor(rightflywheel) = -127; //the flywheel will travel in the opposite direction, not launching the ball
	}
	else//nothing will happen if nothing is pressed
	{
		motor(leftflywheel) = 0; //the flywheel will do nothing
		motor(rightflywheel) = 0; //the flywheel will do nothing
	}

Basically, you just need to have the buttons toggle a variable, and set the motors based on that variable.

int flywheel=0;

if(vexRT[Btn6UXmtr2] == 1) //if button 6U is pressed on the partner remote
     flywheel =1;
else if(vexRT[Btn6DXmtr2] == 1) //if button 6D is pressed on the partner remote
     flywheel = -1;
else if(vexRT[Btn8DXmtr2] == 1)//shutdown flywheels if 8D is pressed 
     flywheel = 0;

if(flywheel == 1){
     motor(leftflywheel) = 127; //the flywheel will launch balls into the air
     motor(rightflywheel) = 127; //the flywheel will launch balls into the air
}
else if(flywheel == -1){
     motor(leftflywheel) = -127; //the flywheel will travel in the opposite direction, not launching the ball
     motor(rightflywheel) = -127; //the flywheel will travel in the opposite direction, not launching the ball
}
else{
     motor(leftflywheel) = 0; //the flywheel will do nothing
     motor(rightflywheel) = 0; //the flywheel will do nothing
} 
 

You may want to be careful about reversing the flywheels at speed. Out of curiosity, why do you want to reverse them?

You don’t really need to use a variable to do it. This should work pretty well
if(buttonApressed){
flywheel how forward
}
else if(buttonBpressed){
flywheel is reversed
}
else if(buttonCpressed){
flywheel stops
}
Sorry for the sudo code but I’m typing this on my phone.

Edit: yeah that’s true. You could just replace else with else if, so the motors don’t default to 0

Thank you all for the help. The reason I want to have the flywheel reverse is in the slim chance a ball were to be caught in the flywheel, we would need to reverse it to dislodge it. We probably wouldn’t ever use this in competition, but I would rather be safe than sorry.

You need a toggle function. And other people explained it nicely. Usually when I’m programming I make a separate task just called toggle loop to run all my toggle features – pneumatics, toggle a motor direction, control modes, anything that you wanna change with a button. Especially pneumatics.

But beware of the damage your flywheel motors are taking every time field control forcefully shuts the down.

+1 to this. You want to toggle to a new state which would slow down the motor and look for slower velocity to start a reverse.

Having the motor control in a background task is another mechanism and the buttons just change a variable controlling state. The task picks up this new value and performs the sequence of events to slow down and then reverses the motor in its own sweet time. Doing that sequence of events outside of a task can block the rest of the control of the robot. It can be done but is typically a bit harder. (This is triggering a saga of slow the motor)

How would I go about programming that?

Here’s an example I found. Instead of pneumatics you want to start a sequence of events to slow down the motor.

https://vexforum.com/showthread.php?p=370396

If this does not help I can try and whip something up.

I am sorry, but this still does not make sense to me. If you could make a little sample and explain it, I would greatly appreciate it. I have been looking at other posts about toggling functions, but I cannot grasp the idea yet. Thank you all for your help!!!

Simple enough.

When you start talking about toggles, we need to introduce the concept of “state.” Pressing the button changes the state of a variable.

In your case you need two toggles and two states.

First we initialize the state variables:


bool motorMoving = false, motorReverse = false;

Alternatively…

bool motorMoving = false;
bool motorReverse = false;

Alternatively (if you want to kill 6 bytes of memory for no reason)…

int motorMoving = false;
int motorReverse = false;

Now somewhere in a while loop wherever your drive code is…

// Motor moving toggle
if(vexRT[Btn6UXmtr2]) {

	// Reverse motor state (! means NOT, as in opposite !true = false, !false = true)
	motorMoving = !motorMoving;
}

// Motor reversed toggle
if(vexRT[Btn6DXmtr2]) {

	// Reverse motor state (! means NOT, as in opposite !true = false, !false = true)
	motorReverse = !motorReverse;
}

Unfortunately this will continue to flip states if you hold the button more than whatever the wait in your loop is, I have a simple solution to that but I have to go for class, I’ll post that in a few hours.

EDIT: You need some code at the end to actually read the state and drive the motors, again class will post later.

OK so the problem is our drive code loop cycles at some really fast rate, probably once every 20ms. Humans are slow, pressing a button may take 100-120 ms to complete. This means the button may be held down during two or more cycles of the drive code.

We could trap on that event and not allow any other code to run until the button is pressed but this is a bad idea for many reasons. Maybe the driver slams down two buttons at once, in which case the first one may block out the code that checks for the other one. Blah blah blah, there’s a better way…

… but unfortunately it involves more state.

bool motorMoving = false;
bool motorReverse = false;
bool buttonApressed = false;
bool buttonBpressed = false;

while(true) {

	// Motor moving toggle
	if(vexRT[Btn6UXmtr2] && !buttonApressed) {

		buttonApressed = true;
 
		// Reverse motor state (! means NOT, as in opposite !true == false, !false == true)
	 	motorMoving = !motorMoving;

	} else {
		buttonApressed = false;
	}
 
	// Motor reversed toggle
	if(vexRT[Btn6DXmtr2] && !buttonBpressed) {
 
		buttonBpressed = true;
 
		// Reverse motor state (! means NOT, as in opposite !true == false, !false == true)
		motorReverse = !motorReverse;

	} else {
		buttonBpressed = false;
	}

	if(motorMoving) {

		if(motorReverse) {
			motor(leftflywheel) = -127;
			motor(rightflywheel) = -127;
		} else {
			motor(leftflywheel) = 127;
			motor(rightflywheel) = 127;
		}

	} else {
		motor(leftflywheel) = 0;
		motor(rightflywheel) = 0;
	}

	wait1MSec(20);

}

buttonApressed / buttonBpressed are states that get set when the button is pressed and get unset when the button is released. Combining these with the second condition I added to the conditional statements creates a latch that only fires ONCE per button press.

The two conditional statements at the end checks to see first should the motor move or stop? Then (if the motors should move) it checks which direction and sets the motors in motion accordingly.

This is all done by reading the state. We no longer care about what is actually going on with the button, that drives the state, this part reads just that state and acts accordingly.

If bool gives you trouble try boolean or char or byte, worst case use int.

-Cody

Thanks Cody!

So if I change the wait time at the end of the code to something like 120 ms or higher than the code would work? Also, how would the code function in real life, meaning would I press the 6U button over and over until it got up to full speed? Or would I press the button once and it would slowly get up to speed by itself? Or would I just hold down the button? Thank you very much Cody!!!:slight_smile:

As written you could (and should) leave the 20ms delay, pushing the button would make the motors go full speed.

If you want to increment the speed based on button presses that could definately be accomplished…

#define SPEED_INCREMENT 20

bool motorMoving = false;
bool motorReverse = false;
bool buttonApressed = false;
bool buttonBpressed = false;
bool buttonCpressed = false;
bool buttonDpressed = false;

int motorSpeed = 0;

while(true) {

	// Motor moving toggle
	if(vexRT[Btn6UXmtr2] && !buttonApressed) {

		buttonApressed = true;
 
		// Reverse motor state (! means NOT, as in opposite !true == false, !false == true)
	 	motorMoving = !motorMoving;

	} else {
		buttonApressed = false;
	}
 
	// Motor reversed toggle
	if(vexRT[Btn6DXmtr2] && !buttonBpressed) {
 
		buttonBpressed = true;
 
		// Reverse motor state (! means NOT, as in opposite !true == false, !false == true)
		motorReverse = !motorReverse;

	} else {
		buttonBpressed = false;
	}

	// Increase motor speed
	if(vexRT[SPEED_UP] && !buttonCpressed) {
 
		buttonCpressed = true;
 
		motorSpeed += (motorSpeed > 127) ? 0 : SPEED_INCREMENT;

	} else {
		buttonCpressed = false;
	}

	// Decrease motor speed
	if(vexRT[SPEED_DOWN] && !buttonDpressed) {
 
		buttonDpressed = true;
 
		motorSpeed -= (motorSpeed < -127) ? 0 : SPEED_INCREMENT;

	} else {
		buttonDpressed = false;
	}

	if(motorMoving) {

		if(motorReverse) {
			motor(leftflywheel) = -motorSpeed;
			motor(rightflywheel) = -motorSpeed;
		} else {
			motor(leftflywheel) = motorSpeed;
			motor(rightflywheel) = motorSpeed;
		}

	} else {
		motor(leftflywheel) = 0;
		motor(rightflywheel) = 0;
	}

	wait1MSec(20);

}

BTW I highly recommend the Forum Syntax Highlighter Google Chrome plugin for code reading pleasure.

Cody, I am not sure, but i think that the wait10Ms function doesn’t exist (it is wait1MSec), I just checked the docs.
I also recommend the Syntax Highlight. It makes reading code so much better.

ROBOTC had / has something like that…

Yeah it’s wait1MSec, I’ll fix the other posts.

It’s still available in V4.30 but is deprecated (ie. best not to use for new programs).