RobotC "run until done" button with override

We are trying to make a code for our puncher where the following happens:

  • press 6u 1 time and release it and both puncher motors run at full speed until they reach a point just before the gear slips, where they stop moving and a ratchet holds
    (we originally tried to do this time based but when that wasn’t working we added a limit switch and tried to do it with that with the same bad results)
  • press 6u again 1 time (after puncher is primed) and it launches ball then returns to the same place again (limit switch may be pressed still, as it has to go back a bit more to release)
  • press 6d and the motors run only while 6d is pressed, stopping when it is no longer pressed (this is for a manual override in case of issues where resetting or overruling other may be needed, and we want it to take precedence over 6u)

We can’t seem to get anything working together as planned, even after researching and testing various options. Most often, 6u runs the motors only when it is actually being pressed (instead of being able to just press once and have it run until pulled back) just like 6d. Some cause the motors to run without ever stopping. The limit switch rarely works, although in some tests if you are pressing 6u AND the switch it does stop motors.

We have this running as a separate task to make sure the rest of the robot functions even while the puncher is pulling back.

We thought maybe MoveMotor for a certain time could work, but couldn’t figure out how to get it for 2 motors together.

Here are some of the attempts we’ve made (we were just commenting out and in various ones for testing with misc changes as new ideas came up, didn’t save them all):


/*
task Punchertask()
{
	while (true)
  {
  	
	if (vexRT[Btn6D] == 1)
	{
		motor[Puncher1] = 127;
		motor[Puncher2]  = 127;
	}
	else
		{
		motor[Puncher1] = 0;
 	  motor[Puncher2] = 0;
		}

	if(vexRT[Btn6U] == 1)
		{
		motor[Puncher1] = 127;
		motor[Puncher2]  = 127;
		if(SensorValue(limitswitch) == 1)		// Loop while robot's bumper/touch sensor is pressed in
	{

	 	motor[Puncher1] = 0;
 		motor[Puncher2] = 0;
	}
	wait1Msec(25);
}
*/
/*
task Punchertask()
{
	while (true)
  {
    motor[Puncher1] = 0;
		motor[Puncher2]  = 0;
	if (vexRT[Btn6D] == 1)
	{
		motor[Puncher1] = 127;
		motor[Puncher2]  = 127;
	}

	if(vexRT[Btn6U] == 1)
		{
		motor[Puncher1] = 127;
		motor[Puncher2]  = 127;
		if(SensorValue(limitswitch) == 1)		// Loop while robot's bumper/touch sensor is pressed in
	{
	 	motor[Puncher1] = 0;
 		motor[Puncher2] = 0;
	}
	wait1Msec(25);
}
*/


/*	
task Punchertask()
{
	while (true)
  {

	if (vexRT[Btn6D] == 1)
	{
		motor[Puncher1] = 127;
		motor[Puncher2]  = 127;
	}

	else if((vexRT[Btn6U] == 1) && (SensorValue(limitswitch) == 0))
		{
		motor[Puncher1] = 127;
		motor[Puncher2]  = 127;
	}
	else
	{
	 	motor[Puncher1] = 0;
 		motor[Puncher2] = 0;
	}
	wait1Msec(25);
}
*/

	/*
task Punchertask()
{
	while (true)
  {

	if (vexRT[Btn6D] == 1)
	{
		motor[Puncher1] = 127;
		motor[Puncher2]  = 127;
	}

	else if(vexRT[Btn6U] == 1)
		{
		motor[Puncher1] = 127;
		motor[Puncher2]  = 127;
		wait1Msec(800);
	}
	else
	{
	 	motor[Puncher1] = 0;
 		motor[Puncher2] = 0;
	}
	wait1Msec(25);
}
*/

You if statements don’t loop. Use a while loop instead.

When we tried using “while” it wouldn’t let us do “else” (kept throwing compile error). Is there some way to use those together?

Is there one of the 4 possibilities above that you maybe think is closest to correct and should be focused on?

Probably having the limit switch is best so it’s always the same spot. Maybe a separate button that emergency stops the puncher pull-back?

Thanks!

if you add a wait1msec(25) to the end of the while loops, it allows other while loops to run at the same time, letting the CPU focus on something for the other 25 ms

This is closest, but needs some work to make 6U act like a toggle. Trying to do it on the two buttons and not setting variables… maybe try:


{
	while (true)
  {

	if (vexRT[Btn6D] == 1)
	{
		motor[Puncher1] = 127;
		motor[Puncher2]  = 127;
	}

	else if( vexRT[Btn6U] == 1 && SensorValue(limitswitch) == 0 )
	{
               while (SensorValue(limitswitch) == 0)
               {
   		     motor[Puncher1] = 127;
		     motor[Puncher2]  = 127;
                     wait1Msec(10);
                }
	 	motor[Puncher1] = 0;
 		motor[Puncher2] = 0;
	}
	else if( vexRT[Btn6U] == 1 && SensorValue(limitswitch) == 1 )
	{
   		     motor[Puncher1] = 127;
		     motor[Puncher2]  = 127;
	}
	else
	{
	 	motor[Puncher1] = 0;
 		motor[Puncher2] = 0;
	}
	wait1Msec(25);
}

edit to make toggle actually work?

Playing around with input so far, we ran the below and it worked finally (mostly)! A } had been dropped, which was apparently why the else wasn’t working.

@Doug Moyers, I’m assuming the last else if is to allow it to run even while the limit switch is pressed so it can get to the slip step? I assume you’d then have to push the button again for it to come back?

The only thing that doesn’t work now is getting it to override stop; we’re thinking a separate emergency stop task may be needed? We’re going to look into a timer to maybe bypass the need for this (and because the limit switch keeps breaking!).


task Punchertask()
{
	while (true)
  {
	if (vexRT[Btn6D] == 1)
	{
		motor[Puncher1] = 127;
		motor[Puncher2]  = 127;
	}
	else if(vexRT[Btn6U] == 1)
		{
			while(SensorValue(limitswitch) == 0)
			{
		motor[Puncher1] = 127;
		motor[Puncher2]  = 127;
	}
}
	else
	{
	 	motor[Puncher1] = 0;
 		motor[Puncher2] = 0;
	}
	wait1Msec(25);
}
}

Right. Press 6U and let go and the puncher advances to just before release. Press 6U again and the 2nd else if is true, motors run, puncher fires, limit switch is again 0 and the first else if is true (assuming you are still pressing 6U). So if you linger just a moment on that press of 6U to fire, it will also initiate the reset. Your code should work fine, with 6U being the reset button, and 6D being the fire button. (That was not what you described in the OP tho.)

You should add some small sleep in your while statement so other tasks can take place.

As for limit switch damage, quite common. Install it better :slight_smile: There are sometimes advantages to triggering them indirectly. Rather than a powered structural member touching the switch, have the member stretch a rubber band that presses the switch, etc. The point of failure is typically one of the very small perpendicular tabs at the connection end of the arm. You can flatten them back and sneak the arm back in (until the tabs break.)