RobotC Button Toggles

Howdy I was wondering how you would make a toggle button in RobotC. By toggle I mean press a button once and it runs, instead of having to keep holding down a button to make it run. I tried making a toggle program today and it worked but once put in a driver code the program gets stuck in a while loop, here’s part of what i wrote

if(vexRT[Btn7U])
{
  count = 1;

while(count == 1)
{
  if((vexRT[Btn7L]) || (vexRT[Btn7D]))
  {
    break;
  }
  else
  {
     if((SensorValue[potright]) && (SensorValue[potleft] < 1500))
  {
    motor[toprightlift] = 127;
    motor[lowerrightlift] = 127;
     motor[topleftlift] = 127;
    motor[lowerleftlift] = 127;
}
  else
  {
    motor[topleftlift] = 0;
    motor[lowerleftlift] = 0;
    motor[toprightlift] = 0;
    motor[lowerrightlift] = 0;
  }
  }

}
}
Another quick question is how can you run something parallel in RobotC, like driving and lifting(with this toggle) at the same time?

1 Like

One reason that it may be getting stuck ing the while loop is because you have nothing to update your variable, “count” inside the loop. In other words, when you press the button the first time, the program sets count to one, enters the loop but no longer checks the button so it never leaves to fix this, you could put another if statement, similar to your first one in the while

if ( vexRT[Btn7U] == 1 )
{
count ++;
}

Here is a simplistic version of what our team did to accomplish the button toggle.

boolean liftUp = false;
while(true){ //this is the robot loop

if(vexRT[Btn7U]){
liftUp = true;
}
if(vexRT[Btn7D]){
liftUp == false;

if(SensorValue[potleft] < 1500 && liftUp){
motor[lift] = 127;
}else{
motor[lift] = 0;
liftUp = false;
}

}

In this loop, if 7U is pressed, the lift will run up until either 7D is pressed or the pot reaches 1500, and liftUp will equal false.
I assume what you are trying to do is have each individual button make the arm raise up to a certain height.
If you want to make the arm go down, you can have the same type of logic added on in reverse.
Having a single running loop, and no other loops within that loop allows you to do things such as (like you mentioned) having the robot be able to drive forward while the lift is raising.

So for example:

boolean liftUp = false;
while(true){ //this is the robot loop

motor[driveRight] = Ch2;
motor[driveLeft] = Ch3;

if(vexRT[Btn7U]){
liftUp = true;
}
if(vexRT[Btn7D]){
liftUp == false;

if(SensorValue[potleft] < 1500 && liftUp){
motor[lift] = 127;
}else{
motor[lift] = 0;
liftUp = false;
}

}

Since there are no other loops within the main loop, the robot will continue checking the different conditions over and over. Thus, the robot in this code will be able to drive and lift at the same time.

You can modify the code to add more motors and sensors and such, and sorry if some syntax is wrong, this code was created off the top of my head.

There are several ways to create a toggle button. The general idea is to detect the button “push” and then change the state of another variable that holds the button’s toggle status. Once the button has been pressed you can either wait for it to be released or remember that it is pushed and ignore it until it has been released.

Here is code that will toggle a LED in digital port 9 by using the 8R button.

#pragma config(UART_Usage, UART1, VEX_2x16_LCD, baudRate19200, IOPins, None, None)
#pragma config(Sensor, dgtl9,  led,            sensorLEDtoVCC)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

task main()
{
    int buttonToggleState = 0;
    int buttonPressed = 0;
    
    while(1)
        {
        // check for a button press only if we are not already pressed.
        if( vexRT Btn8R ] == 1 )
            {
            if( ! buttonPressed )
              {
              // change the toggle state
              buttonToggleState = 1 - buttonToggleState;

              // Note the button is pressed
              buttonPressed = 1;
              }
            }
        else
            {
            // the button is not pressed
            buttonPressed = 0;
            }
        
            
        // Now do something with our toggle flag
        if( buttonToggleState )
            SensorValue led ] = 1;
        else
            SensorValue led ] = 0;  
        }

}

If you are new to ROBOTC then there are lots of samples included with the software you should take a look at as well as many tips in this thread.

Cool thanks guys for the help

one way to get stuff to run in parallel in RobotC is to run it as a seperate task by declaring the task at the beginning of the code before pre auto by typing task (whatever task);

and then to write the code under

task (whatever task)()
{
(code goes here)
}

and the starting the task in your main user control by saying

starttask (whatever task);

or something like that i dont have my code on hand to look at it but it idea is the same the starttask thing is wrong i think but i cant remember what it is, but a problem with this is it takes up a lot more processing power and memory on the microcrontroler to the point where if you have to many task running at the same time your drive might not get enough time and your robot will basically lag

There is a fairly comprehensive series of posts I made last year in the ROBOTC programming tips thread.

https://vexforum.com/showpost.php?p=225688&postcount=23
https://vexforum.com/showpost.php?p=225727&postcount=25
https://vexforum.com/showpost.php?p=226282&postcount=28
https://vexforum.com/showpost.php?p=226297&postcount=29
https://vexforum.com/showpost.php?p=227764&postcount=30

Using tasks really does not take much more processing power or memory, however, if used incorrectly they can cause the task scheduler to spend more time switching between them than is necessary. The biggest error I see many new programmers make when using tasks (well really ROBOTC in general) is not understanding the “real time” nature of what they are trying to achieve. For example;


task main()
{
    while(1)
        {
        motor leftDrive ]  = vexRT Ch3 ];
        motor rightDrive ] = vexRT Ch2 ];
        }
}

A simple tank controller, this while loop will run constantly as fast as the task scheduler will allow, practically that means at least 1000 times per second. If you think about this you will realize that it’s completely unnecessary to try and update the drive motors that fast (and due to other factors not even possible for most motors), the missing line of code is one that tells the task scheduler how often this should run, a revised version would be as follows.


task main()
{
    while(1)
        {
        motor leftDrive ]  = vexRT Ch3 ];
        motor rightDrive ] = vexRT Ch2 ];

        // Run at 50Hz
        wait1Msec( 25 );
        }
}

The wait1Msec( 25 ); causes the loop to be put to sleep until 25mS have passed. Every task you create should use this call with an appropriate delay (well there are one or two exceptions) otherwise the task is going to monopolize the cpu and run too often.

Pushbutton dgtl10
LED dgtl5

task main()
{
while(2<3)
{
while(SensorValue(dgtl10)==1 && SensorValue(dgtl5)==1)
{
SensorValue(dgtl5)=0;
wait(0.2);
}
while(SensorValue(dgtl10)==1 && SensorValue(dgtl5)==0)
{
SensorValue(dgtl5)=1;
wait(0.2);
}
while(SensorValue(dgtl10)==0 && SensorValue(dgtl5)==1)
{
motor[port1] = 127;
motor[port10] = 127;
}
while(SensorValue(dgtl10)==0 && SensorValue(dgtl5)==0)
{
motor[port1] = 0;
motor[port10] = 0;
}
}
}

while 1 continues to check state of LED and button
whiles 2-3 turn LED on/off with button – wait allows time to take finger off button
whiles 4-5 turns motors on and off depending on state of LED

Either I am missing something or you are. This thread is almost 4 years old and the question was answered. Is this an answer to the question or an additional question?

I don’t know about you but I use this forum as a resource - not just a chat board. I am sure other do also. I felt a more general answer to how to create a toggle button would be helpful for anyone looking. Thanks for the spam though.

Tabor does too, however the thread already has a good way to toggle something in RobotC.
If you want to know about pneumatics, @Ruiqi Mao wrote a pretty nice piece of code, I can’t find the thread, but here’s the code:

In this case, this is for pneumatics.


boolean actuate = false;
while(true){
        if(vexRT[Btn8D] != actuate){
	        actuate = !actuate;
		if(actuate) SensorValue[s_intClaw] = !SensorValue[s_intClaw];
	}
}