Pnuematics Toggle Code Issue

Okay so when I press the button associated with the toggleSolenoid command the cylinder occasionally actually toggles back and forth at the touch of the button - but more often than not it just spazzes back and forth repeatedly.

What is wrong??

Pnuematics Subsystem:

package org.usfirst.frc.team4623.robot.subsystems;

import edu.wpi.first.wpilibj.Compressor;
import edu.wpi.first.wpilibj.DoubleSolenoid;
import edu.wpi.first.wpilibj.command.Subsystem;

/**
 *
 */
public class Pnuematics extends Subsystem {
    
    // Put methods for controlling this subsystem
    // here. Call these from Commands.
	
	Compressor comp = new Compressor(0);

       DoubleSolenoid ds1 = new DoubleSolenoid(0, 1);
	
	public Pnuematics() {
		
		comp.setClosedLoopControl(true);
		
	}

    public void initDefaultCommand() {
        // Set the default command for a subsystem here.
        //setDefaultCommand(new MySpecialCommand());
    }
    
    public void toggleSolenoid() {
    	
       if(ds1.get() == DoubleSolenoid.Value.kForward) {
    	   ds1.set(DoubleSolenoid.Value.kReverse);
       }
       
       else {
    	   ds1.set(DoubleSolenoid.Value.kForward);
       }
    	
    }
    
    public void stop1() {
    	
    	ds1.set(DoubleSolenoid.Value.kOff);
    	
    }

}

toggleSolenoid Command:

package org.usfirst.frc.team4623.robot.commands;

import org.usfirst.frc.team4623.robot.Robot;

import edu.wpi.first.wpilibj.command.Command;

/**
 *
 */
public class toggleSolenoid extends Command {

    public toggleSolenoid() {
        // Use requires() here to declare subsystem dependencies
        // eg. requires(chassis);
    	
    	requires(Robot.pnue);
    	
    }

    // Called just before this Command runs the first time
    protected void initialize() {
    }

    // Called repeatedly when this Command is scheduled to run
    protected void execute() {
    	Robot.pnue.toggleSolenoid();
    }

    // Make this return true when this Command no longer needs to run execute()
    protected boolean isFinished() {
        return isTimedOut();
    }

    // Called once after isFinished returns true
    protected void end() {
    	Robot.pnue.stop1();
    }

    // Called when another command which requires one or more of the same
    // subsystems is scheduled to run
    protected void interrupted() {
    	end();
    }
}

Connection between Button and Command:

toggleSolenoid.whileActive(new toggleSolenoid());

Thanks so much for the help!

My team has just switched over to Java from C++ this year, so I’m a little unsure of myself, but I think I know what your issue is. Using whileActive to toggle your solenoid will result in the toggleSolenoid() function running repeatedly as long as the button is held (assuming I’m understanding this right). If there’s a function you can use that will only run once when the button is pressed instead of whileActive, that would be best. Otherwise, you can look into using a timer to run the function at most once every half second or so, which would keep it from freaking out.

Hey there, try adding or modifying your subsystem to this


public class Pnuematics extends Subsystem {

public boolean toggle;
	
    public void solenoidIn() {
    	   ds1.set(DoubleSolenoid.Value.kReverse);
	toggle = true;
    }
       
    public void solenoidOut(){
    	   ds1.set(DoubleSolenoid.Value.kForward);
toggle = false;
       }
    	
}


these are two methods which when called will set the solenoid in a direction then flip the state of the boolean

then your Command to this


public class toggleSolenoid extends Command {

    public toggleSolenoid() {	
    	requires(Robot.pnue);    	
    }

protected void initialize() {
	if (Robot.pnue.toggle == true)
    	{
    	Robot.pnue.solenoidOut();
    	}
    	else if(Robot.pnue.toggle == false){
    	Robot.pnue.solenoidIn();
    	}
    }

    // Called repeatedly when this Command is scheduled to run
    protected void execute() {
}

    // Make this return true when this Command no longer needs to run execute()
    protected boolean isFinished() {
return true;
}

    // Called once after isFinished returns true
    protected void end() {
    
    }
protected void interrupted() {
    	end();
    }
}


since solenoids retain their “state” when switched, they do not need to be told continuously what do do. they are set to forward or reverse one time in the “initialize” part of the command depending on the state of the boolean. Then the command finishes immediately.

the OI should be


toggleSolenoid.whenPressed(new toggleSolenoid());

Best of luck, hope this helps. Once mastered, command based is the way to go!

Also there may be other ways to acheive a “toggle” but this has worked for us in the past. I did see a “toggle option” in the OI this year but have yet to test it.

Okay using your code I got it to work - thanks so much!:slight_smile: