Pneumatics Programming Issue

I was just working on programming the several pneumatics on our robot. These include two for our two intakes, one for our conveyor, and one for the two climb pistons. The code I used for all of these is the same with small changes for the different buttons we are using and the names of the different pistons. For some reason, only the pneumatics for the two intakes are working, even though all of the pneumatics worked when we tested it without code. Here is a video of it as well as screenshots of the code. Any help would be greatly appreciated!

Video of the Issue

Here are some bits and pieces of the code for the three pistons I was working on:
//Functions
void LeftMotorsSpeed(double speed) {
LeftMotorOne.Set(ControlMode::PercentOutput, -speed);
LeftMotorTwo.Set(ControlMode::PercentOutput, -speed);
LeftMotorThree.Set(ControlMode::PercentOutput, -speed);
}
void RightMotorsSpeed(double speed) {
RightMotorOne.Set(ControlMode::PercentOutput, speed);
RightMotorTwo.Set(ControlMode::PercentOutput, speed);
RightMotorThree.Set(ControlMode::PercentOutput, speed);
}
void Shooter(double speed){
LeftShooter.Set(ControlMode::PercentOutput, -(speed * speed));
RightShooter.Set(ControlMode::PercentOutput, (speed * speed));
}
void Conveyor(double leftSpeed, double rightSpeed){
LeftConveyor.Set(ControlMode::PercentOutput, leftSpeed);
RightConveyor.Set(ControlMode::PercentOutput, rightSpeed);
}

//Code for shooting (piston does not work properly)
if (Xbox.GetRawButton(3)) {
Shooter(0.2); //if we increase shooter speed, remember to also increase speed average motor speed has to be greater than
//ConveyorPiston.Set(!ConveyorPiston.Get());
if ((fabs(LeftShooter.GetMotorOutputPercent()) + fabs(RightShooter.GetMotorOutputPercent()) / 2) > 0.5) {
Conveyor(-0.1, -0.1);
//ConveyorPiston.Set(true);
}
} else {
Shooter(0);
Conveyor(0, 0);
ConveyorPiston.Set(false);
}
//Code for intake pistons (works)
if (Xbox.GetRawButtonPressed(5)) {
BackIntakePiston.Set(!BackIntakePiston.Get());
}
if (Xbox.GetRawButtonPressed(6)){
FrontIntakePiston.Set(!FrontIntakePiston.Get());
}

Your ConveyorPiston.set methods aren’t commented out in the code that you’ve compiled onto the robot, right?

Yes, it was just for the purpose of testing the other pneumatics, but it was uncommented when I was testing it.

I’m a bit confused what is wrong here. Maybe you can go into more detail of what you expect to happen vs. what is (or isn’t happening).

One thing to check is the PCM in code and on the robot. If your code is working properly, when you press your buttons, the lights on the ports of the VRM should change corresponding to which ports you activated. If that isn’t working as you expect, it’s likely software. Make sure that you have each DoubleSolenoid defined properly with the correct ports in the contructor.

Most pneumatics issues I have seen were caused by the wrong solenoid - check the solenoids first, if you have 12v and 24v solenoids then they wouldn’t fire.

It seems like your code will rapidly toggle (on/off/on/off/on/etc) the solenoids as long as the xbox button is pressed. It’s constantly countermanding the last order, because the code cycles far too fast.
That won’t give the solenoids enough time to actually visibly change any state.
It means that while the button is held nothing may seem to happen, but when the button is released it’ll be arbitrary as to what state the solenoid is left in.

P,S. These seem to de defined as single solenoids, i.e., only one set of wires come from the solenoid and attach to the PCM. Just make sure they don’t have two sets of wires (double solenoid), because the controls are different.

4 Likes

Were you able to activate it by moving ConveyorPiston.Set(true) out of the if statement?

But most of our solenoid issues tend to be hardware or wiring.

Edit: Check Mark’s post. That’s a likely issue.

I have definitely seen many of the issues mentioned above. It would be most effective if we could see all of the code, or at least all of the pneumatics code - including where the various actuators are created, and constants defined, and how things are called by the UI and how they call each other. Do you have the code on github or another public site?

I will double check the solenoids with our Electrical lead, but I believe they are correct. Thank you for your reply!

That does make sense; how would I put in a delay so it doesn’t toggle between the different states so quickly? I also think these are single solenoids, but I will also double check that, thanks!

Yes, the code is on the FRC Team 5458: Digital Minds Github page! I believe all of the repositories are public.

You add a logic check so that the action will only occur once when the button changes from false (not pressed) to true (pressed).
e.g.,

if (Xbox.GetRawButton(3) > LastButton3) {
    ConveyorPiston.Set(!ConveyorPiston.Get());
} 
LastButton3 = Xbox.GetRawButton(3);

// Where the button press is going to equal either 0 or 1 (false or true)
// The if action will only occur the one time the button becomes true after previously being false.

P.S. Corrected this example per Peter’s subsequent comment. Original example used the wrong section of code.

1 Like

Thank you! I will try that and update you as to how it ends up working.

GetRawButtonPressed() only returns true when the button changes from not pressed to pressed. GetRawButton() returns true simply when the button is down. So you don’t need to store LastButton, you can just do:

if (Xbox.GetRawButtonPressed(5)) {
  BackIntakePiston.Set(!BackIntakePiston.Get());
}
1 Like

So in the OP’s particular case a check around the Conveyor Piston toggle is needed to avoid constant toggling.
e.g.,
if (Xbox.GetRawButtonPressed(3)) {
ConveyorPiston.Set(!ConveyorPiston.Get());
}

I assume that you intended your shooter to only run as long as the button was held down.
But I’m not sure what you intend happening with ConveyorPiston.Set(true):, perhaps you mean to explicitly set it false rather than toggling with the earlier Set call?

For instance, if you wanted the ConveyorPiston to let a stream of balls through only after the shooter has reached full speed , then you might only have to set ConveyorPiston to false in the else where you set Shooter(0). That would leave the Piston = false before and after pressing and letting go of button 3.

Alternatively, if you want the Piston to index the balls, i.e., only let a ball through only when the shooter is spinning fast enough, then (in addition to setting ConveyorPiston =false where Shooter(0) is also set) you could add an else to your speed check that also sets ConveyorPiston =false. That would close the Piston each time a ball hits the shooter wheels and subsequently slows them down preventing a second ball until the shooter gets back up to speed.