in robotc I was wondering if it was possible to have a button toggle. for example, a button on the controller makes sets all the motors to 100, when released the motors are still at 100 but when the button is pressed again the motors are set to 0.
Easy, you need a placeholder variable …
bool state = true;
while(true) {
// If button pressed set state to NOT state (the opposite of state)
if( BUTTON PRESSED ) state = !state;
// If state, spin motors
if(state) {
// Do this stuff
}
wait1Msec(20);
}
In production code I would also make sure that the button cannot change the state again until a certain amount of time has passed. With this code if you press the button for too long you will engage the toggle more than once.
I invariably use the following block:
bool myButtonWasPressed = false;
while (true)
{
if (vexRT[myButton] && !myButtonWasPressed)
{
// Do Something
myButtonWasPressed = true;
}
else if (!vexRT[myButton])
myButtonWasPressed = false;
wait1Msec(20);
}
Runs the same, different syntax:
bool myButtonWasPressed = false;
while (true)
{
if (vexRT[myButton] == true && myButtonWasPressed == false)
{
// Do Something
myButtonWasPressed = true;
}
else if (vexRT[myButton] == false)
{
myButtonWasPressed = false;
}
wait1Msec(20);
}
I finally got to test the code to find that it doesn’t work. I know why it won’t work. I’m trying to make it where the way the analog sticks is manipulated.
task usercontrol()
{
startTask(Movement);
startTask(Arm);
startTask(ArmMove);
//thanks to Cody on vex forums for this great holonomic code!
#define C1LX vexRT[Ch4]
#define C1LY vexRT[Ch3]
#define C1RX vexRT[Ch1]
#define C1RY vexRT[Ch2]
#define C2LX vexRT[Ch4Xmtr2]
#define C2LY vexRT[Ch3Xmtr2]
#define C2RX vexRT[Ch1Xmtr2]
#define C2RY vexRT[Ch2Xmtr2]
bool myButtonWasPressed = false;
bool myButtonWasPressed2 = false;
while (true)
{
if (vexRT[Btn8U] && !myButtonWasPressed)
{
motor[LFmtr] = C1LY + C1LX + C1RX; // Front left wheel
motor[RFmtr] = C1LY - C1LX - C1RX; // Front right wheel
motor[RBmtr] = C1LY - C1LX + C1RX; // Back right wheel
motor[LBmtr] = C1LY + C1LX - C1RX; // Back left wheel
myButtonWasPressed = true;
}
else if (!vexRT[Btn8U])
myButtonWasPressed = false;
wait1Msec(20);
if (vexRT[Btn8L] && !myButtonWasPressed2)
{
motor[LFmtr] = -C1LY + C1LX + C1RX; // Front left wheel
motor[RFmtr] = C1LY - C1LX + C1RX; // Front right wheel
motor[RBmtr] = C1LY - C1LX + C1RX; // Back right wheel
motor[LBmtr]= C1LY + C1LX - C1RX; // Back left wheel
}
else if (!vexRT[Btn8L])
myButtonWasPressed2 = false;
what happens is when I press the button, and because it’s only setting the values for motors it goes strait to myButtonWasPressed2 = true; meaning that it sets the values to whatever I have it on the controller, then it gets stuck on that value until I press the button again then it does the same thing.
I’m probably not making any sense, it’s really hard to explain XD. and I’m not in a hurry so it can wait until after worlds.
It looks like you’re trying to create a driver control switching mode, right? You want to push a button and change how you control your holonomic control. The way the code snippet works is that the code inside
if(myButtonIsPressed && !myButtonWasPressed) {}
only runs once. So every time it detects a new button press, it runs that code. That means the motor setting only runs once every time you push that button.
To fix this issue, you can create a variable that holds what “state” the driver mode should be in. Then we can use a switch() on the variable to determine what state DriverMode is in and act accordingly. See below:
task usercontrol()
{
StartTask(Movement);
StartTask(Arm);
StartTask(ArmMove);
#define C1LX vexRT[Ch4]
#define C1LY vexRT[Ch3]
#define C1RX vexRT[Ch1]
#define C1RY vexRT[Ch2]
#define C2LX vexRT[Ch4Xmtr2]
#define C2LY vexRT[Ch3Xmtr2]
#define C2RX vexRT[Ch1Xmtr2]
#define C2RY vexRT[Ch2Xmtr2]
bool Btn8UWasPressed = false;
bool Btn8LWasPressed = false;
// True = First Mode (8U)
// False = Second Mode (8L)
bool DriverMode = true; // Change this to whatever you want default to be
while (true)
{
if (vexRT[Btn8U] && !Btn8UWasPressed)
{
DriverMode = true; // Change mode to 8U
Btn8UWasPressed = true;
}
else if (!vexRT[Btn8U])
Btn8UWasPressed = false;
if (vexRT[Btn8L] && !Btn8LWasPressed)
{
DriverMode = false; // Change mode to 8L
Btn8LWasPressed = true;
}
else if (!vexRT[Btn8L])
Btn8LWasPressed = false;
switch (DriverMode)
{
case true: // First Mode (8U)
motor[LFmtr] = C1LY + C1LX + C1RX; // Front left wheel
motor[RFmtr] = C1LY - C1LX - C1RX; // Front right wheel
motor[RBmtr] = C1LY - C1LX + C1RX; // Back right wheel
motor[LBmtr] = C1LY + C1LX - C1RX; // Back left wheel
break;
case false: // Second Mode (8L)
motor[LFmtr] = -C1LY + C1LX + C1RX; // Front left wheel
motor[RFmtr] = C1LY - C1LX + C1RX; // Front right wheel
motor[RBmtr] = C1LY - C1LX + C1RX; // Back right wheel
motor[LBmtr] = C1LY + C1LX - C1RX; // Back left wheel
break;
default: // If a boolean is not true or false (impossible code to reach)
break;
}
}
}
Let me know if any of that wasn’t making any sense. Also, if you have more than two modes, we can switch DriverMode to be an integer (or a char, or even better: an enum). Since a boolean is nice, simple, and perfectly fits your needs, I figured why not just that.
makes perfect sense! I do want to have more modes, I made DriveMode a integer. did I do it right?
task usercontrol()
{
startTask(Movement); //startTask not StartTask in 4.08 =)
startTask(Arm);
startTask(ArmMove);
#define C1LX vexRT[Ch4]
#define C1LY vexRT[Ch3]
#define C1RX vexRT[Ch1]
#define C1RY vexRT[Ch2]
#define C2LX vexRT[Ch4Xmtr2]
#define C2LY vexRT[Ch3Xmtr2]
#define C2RX vexRT[Ch1Xmtr2]
#define C2RY vexRT[Ch2Xmtr2]
bool Btn8UWasPressed = false;
bool Btn8LWasPressed = false;
// True = First Mode (8U)
// False = Second Mode (8L)
int DriverMode = 1; // Change this to whatever you want default to be
while (true)
{
if (vexRT[Btn8U] && !Btn8UWasPressed)
{
DriverMode = 1; // Change mode to 8U
Btn8UWasPressed = true;
}
else if (!vexRT[Btn8U])
Btn8UWasPressed = false;
if (vexRT[Btn8L] && !Btn8LWasPressed)
{
DriverMode = 2; // Change mode to 8L
Btn8LWasPressed = true;
}
else if (!vexRT[Btn8L])
Btn8LWasPressed = false;
switch (DriverMode)
{
case 1: // First Mode (8U)
motor[LFmtr] = C1LY + C1LX + C1RX; // Front left wheel
motor[RFmtr] = C1LY - C1LX - C1RX; // Front right wheel
motor[RBmtr] = C1LY - C1LX + C1RX; // Back right wheel
motor[LBmtr] = C1LY + C1LX - C1RX; // Back left wheel
break;
case 2: // Second Mode (8L)
motor[LFmtr] = -C1LY + C1LX + C1RX; // Front left wheel
motor[RFmtr] = C1LY - C1LX + C1RX; // Front right wheel
motor[RBmtr] = C1LY - C1LX + C1RX; // Back right wheel
motor[LBmtr] = C1LY + C1LX - C1RX; // Back left wheel
break;
default: // If a boolean is not true or false (impossible code to reach)
break;
}
}
}
Yes, that’s right. Just add more DriverModes as necessary.
wow, I didn’t even know about cases until this, thanks! can’t wait to test this. well see you at the Indiana qualifiers!
Switches are just an easier way to have if(variable == conditionA) {} else if(variable == conditionB){} else if (variable == conditionC) {} and so on.
What team number are you? See you in $MonthInFall for the first competition of $NextYearsGame!
We don’t have a number yet, but the team name will be ID:10TS.