Pressing a switch for a certain time

Hello! I have a robotics competition in a few days, and so I was wondering if someone could help me out with a tiny problem. In my program, a servo is set to a certain position every time a switch is pressed for 3 seconds, but when this same switch is pressed for 5 seconds, the servo is supposed to go to its neutral position and not move anymore (even if the switch is pressed again). How can I make the program stop running once the switch is pressed for 5 seconds (instead of 3)?

Some code would help. Based on how the problem sounds though, you could put your function in a task, and start/stop it when needed.

Thanks for answering, but how do we do that? Do you mind sending me a simple example?

I’m not 100% sure how servo positioning works, but If I were to guess, something like this would probably work:

float time;
if(vexRT[INSERT_BUTTON]) {
	clearTimer(T1);
	while(vexRT[INSERT_BUTTON]) {
		time = time1[T1];
        wait1MSec(10); //Just to buffer
	}
}
if(time > 5000) {
	//Set servo thingy
}
else if(time > 3000) {
    //Other servo setting thingy
}

Just as a note, this should probably be used in a task so that you can do other things for the 3-5 seconds while you’re holding down this button.

No tasks needed here.

Click to expand example timing code

Assuming Btn5U:

//Either the time at which the button was first pressed
//Or 0 if the button was not pressed the last time we checked
long btn5UPressedStart = 0;

task main() {
  while(1) {

    //When we first press the button
    //vexRT[Btn5U] will be true because the button is pressed
    //btn5UPressedStart will be 0 because the button wasn't pressed before
    if(vexRT[Btn5U] && btn5UPressedStart == 0) {

      //Set btn5UPressedStart to the current (system) time (in milliseconds)
      btn5UPressedStart = nSysTime;

    }

    //When we release the button
    //vexRT[Btn5U] will be false because the button isn't pressed
    //btn5UPressedStart will be nonzero because the button was pressed before
    if(!vexRT[Btn5U] && btn5UPressedStart != 0) {

      //Have we held the button for at least 5 seconds?
      //Is the current (system) time at least 5000 ms greater than
      //the time at which we first pressed the button?
      if(nSysTime - btn5UPressedStart >= 5000) {

        //Do something

      }

      //Have we held the button for at least 3 seconds, but not quite 5 seconds?
      //Is the current (system) time at least 3000 ms greater than the time at
      //which we first pressed the button (but not 5000 ms greater)?
      else if(nSysTime - btn5UPressedStart >= 3000) {

        //Do something else

      }

      //Reset btn5UPressedStart to 0 to signify that the button isn't pressed anymore
      btn5UPressedStart = 0;

    }

  }
}

Disclaimer: I did not check to see if this code compiles.


As for the disabling of the servo, all you would need to do is create a boolean variable to represent whether your servo should be enabled (true) or disabled (false). You would initialize the variable to true, since the servo should be enabled when your program starts. In the appropriate place in my timing code template, you would then set the variable to false, meaning the servo shouldn’t move anymore. Then you can use an if statement, detecting the value of your variable, to enable/disable your servo movement code.

Thank you so much! But I actually use a limit switch (dgtl) instead of a button from the joystick, and, basically, the servo is supposed to follow a loop that will be interrupted if time=5000. So when I tried your recommendation it didn’t quite do the job. Do you mind telling me how to incorporate it in this case?

Thank you for your help! I’m actually pretty new to programming so I don’t fully understand some of the features you used (even after doing research), but I’ll keep trying!

So, first of all, you can directly substitute your limit switch SensorValue[] command in place of the vexRT[Btn5U].


Now, my code fundamentally has 3 parts:

First, it will determine when the limit switch is first depressed. To do this, you have to think verbosely, like a computer. The value of the limit switch will be 0 during one iteration of the infinite while(1) loop. Then, the next time through, the value will be 1. Obviously, we can detect the sensor value in the current loop iteration with just SensorValue[], but we also need to know the sensor value from the last time through the loop in order to determine if the limit switch started being depressed or is continuing to be depressed. That’s where the variable btn5UPressedStart (you probably want to rename that) comes in. Notice that that variable starts as 0 and will only ever become nonzero during the first time through the loop with the limit switch depressed, making the first if() statement you see in my code. When that circumstance happens, the variable takes on the value nSysTime, which is nothing more than the timecode for the current time (as in, the instant when that line of code is executed).

The next part, detecting when the limit switch is released, operates with nearly identical logic. Just like before, but inverted, the limit switch must have been depressed the last time through the loop, and it must not be depressed during the current iteration of the loop. btn5UPressedStart != 0 takes care of the former, since the variable was set to nSysTime when the limit switch was first pressed but would be reset to 0 as soon as the limit switch is released (we will come back to this). And, obviously, we could detect the current status of the limit switch by SensorValue[] (in place of the vexRT[Btn5U]).

The last part of my code is what’s inside the when-we-release-the-button if() block. All we do here is compare the current time, nSysTime, to the time when the limit switch started being depressed, btn5UPressedStart. The time difference between these two events, determined by the subtraction, can be compared to 5000 and 3000 milliseconds, respectively, as your task requires. Regardless of the result of those comparisons, though, we always want to finally reset btn5UPressedStart to 0 to signify that the limit switch is no longer pressed.