Help with PCM and Pneumatics

So I am starting to code pneumatics using PCM but the only thing is that this is my first year of Java. I’m reading the screenstep pages on coding the PCM but I’m really confuse. I’m using command-based project and I’m setting up the lift system to get up to the habitat. I have a piston on the front and a piston in the back. Using the xbox controller triggers for the lift. Press right trigger to get the front piston to go up and press it again to go down for the front piston. Press left trigger to get the back piston to go up and press it again to go down for the back piston. I really don’t understand the pneumatics and PCM part of FRC programming.

It will be helpful to see your code, but I assume that when you say you’re trying to use the PCM that you are using the WPILiB Solenoid (or DoubleSolenoid) class.

From their docs:
http://first.wpi.edu/FRC/roborio/release/docs/java/edu/wpi/first/wpilibj/Compressor.html

Important to note that this is true for both Solenoid, and DoubleSolenoid.

To easily get this going in the way I think you’re trying, you just want to toggle a simple DoubleSolenoid, with each trigger attached to one side of it.

Here is a snippet of code from our PCM stuff last year (and prior years):

DoubleSolenoid ds = new DoubleSolenoid(0, 1); // whatever matches your PCM connection

//==Solenoids=================
	public void toggleLowerIntakeArms() {
		DoubleSolenoid.Value val = ds.get();
		if(val == DoubleSolenoid.Value.kForward) {
			ds.set(DoubleSolenoid.Value.kReverse);
		} else {
			ds.set(DoubleSolenoid.Value.kForward);
		}

	}
	
	public void extendLowerIntake() {
		ds.set(DoubleSolenoid.Value.kReverse);
	}
	
	public void retractLowerIntake() {
		ds.set(DoubleSolenoid.Value.kForward);
	}
	
	public void raiseLowerIntake() {
		ds.set(DoubleSolenoid.Value.kReverse);
	}
	
	public void lowerLowerIntake() {
		ds.set(DoubleSolenoid.Value.kForward);
	}
	
	public boolean isExtended() {
		return ds.get() == DoubleSolenoid.Value.kForward;
	}
	
	public boolean isLowered() {
		return ds.get() == DoubleSolenoid.Value.kForward;
	}

Which is then assigned to a button in our OI via a Command class.

1 Like

Sorry I didn’t posted my code but here it is. We use command based.

RobotMap.java (we were messing around with the Solenoid methods so please ignore our solenoid port codes)
OI.java
ClimbSubsystem.java
Climb_Command

#1: in RobotMap.java, it would be clearer to label your [front|rear]piston[#]solenoid numbers with clearer “up” vs “down” rather than [0123] labels.
#2: You don’t seem to have any other executable lines code at all, and nothing linked to any keyboard or joystick inputs. What is it that you are actually expecting to accomplish?

I would re-architect this a bit differently were it me. I wouldn’t worry about having a default command running for the subsystem, unless there’s a compelling reason to do so. As of now, your code doesn’t have anything in it that I’d call compelling.

Since you want to map the commands to trigger (or multiple triggers), I would map this to some button press. Which it looks like you have started to do in your OI, but in the OI.java your never assign a command to the buttons.

So, you need a command that would look something like this:

```
package frc.robot.commands;

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

public class ExtendRearSolenoid extends Command {
   boolean bDone = false;
  public ExtendRearSolenoid() {
    // Use requires() here to declare subsystem dependencies
    requires(Robot.climbing_subsystem); // or however you've chose to encapsulate
  }

  // Called just before this Command runs the first time
  @Override
  protected void initialize() {
      bDone = false;
      // Toggle the Solenoid here
      Robot.climbing_subsystem.toggle_rear_solenoid(); // or whatever method you define in your subsystem
  }

  // Called repeatedly when this Command is scheduled to run
  @Override
  protected void execute() {
       // Extending solenoids in physical space takes some time before it's fully extended
       // you may need to increment a counter or something to delay the command return
       // a fraction of a second until it's actually out
       bDone = true;
  }

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

  // Called once after isFinished returns true
  @Override
  protected void end() {
  }

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

Then in your OI, you need to map that command to a button press:

button1.whenPressed(new ExtendRearSolenoid());

Or something like that…