Accessor Method for DigitalInput Always Returns False

We are using an adafruit beam break. In our code, we created an accessor method to get the value of the sensor, and this method always returns false no matter the value of the sensor. If we don’t use an accessor method but directly get the value from the sensor when needed, it works. We can also see in the NetworkTables that the DigitalInput is acting correctly. I have included the snippets of code from our project that demonstrate our problem. Any ideas why we can’t use an accessor method?

public class TestCode extends SubsystemBase {
private DigitalInput upperSensor = new DigitalInput(Constants.UPPER_SENSOR_PORT_INPUT);

public TestCode() {
}

public boolean isBallHereUpper() {
  return upperSensor.get();
}

public boolean  testBeamBreak()    {

  // This does not work. Returns FALSE every time
  if (isBallHereUpper())
  {
    // Code here...
  }

  // This works
  if (upperSensor.get())
  {
    // Code here...
  }
}

}

Could you share the entire code? You left out the most important parts

Here are the two .java files. The first is the subsystem, and the second is the command that uses the subsystem. My apologies that these files are not formatted more easily to read. I couldn’t find info on how to format them without being a link from github. I’m happy to change them if someone can point me in the direction of how to do this. (That is why I originally only included a snippet of the code.)

package frc.robot.subsystems;

import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import com.revrobotics.CANSparkMax;
import com.revrobotics.CANSparkMax.IdleMode;
import com.revrobotics.CANSparkMaxLowLevel.MotorType;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.wpilibj.DigitalInput;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
import frc.robot.Constants;
import frc.robot.ShuffleboardInfo;

public class Tower extends SubsystemBase {

private final NetworkTableEntry towerUpperMotorEntry, towerLowerMotorEntry, towerLowerSensorEntry, towerUpperSensorEntry;

private final CANSparkMax lowerMotor = new CANSparkMax(Constants.LOWER_TOWER_MOTOR,MotorType.kBrushless);

private final CANSparkMax upperMotor = new CANSparkMax(Constants.UPPER_TOWER_MOTOR,MotorType.kBrushless);

private DigitalInput lowerSensor = new DigitalInput(Constants.LOWER_SENSOR_PORT_INPUT);

private DigitalInput upperSensor = new DigitalInput(Constants.UPPER_SENSOR_PORT_INPUT);

public Tower() {

lowerMotor.restoreFactoryDefaults();
upperMotor.restoreFactoryDefaults();
lowerMotor.setInverted(true);
upperMotor.setInverted(true);
lowerMotor.setIdleMode(IdleMode.kBrake);
upperMotor.setIdleMode(IdleMode.kBrake);

towerUpperMotorEntry = ShuffleboardInfo.getInstance().getTowerUpperMotorEntry();
towerLowerMotorEntry = ShuffleboardInfo.getInstance().getTowerLowerMotorEntry();
towerUpperSensorEntry = ShuffleboardInfo.getInstance().getTowerUpperMotorEntry();
towerLowerSensorEntry = ShuffleboardInfo.getInstance().getTowerLowerMotorEntry();

}

/** Sets the upper motor speed for the tower. */
public void setSpeedUpper(double speed) {
upperMotor.set(speed);
}

/** Returns the set speed of the upper motor. */
public double getSpeedUpper() {
return upperMotor.get();
}

/** Sets the speed of the lower tower motor. */
public void setSpeedLower(double speed) {
lowerMotor.set(speed);
}

/** Returns the set speed of the lower motor */
public double getSpeedLower() {
return lowerMotor.get();
}

public boolean isBallHereUpper() {
return upperSensor.get();
}

public boolean isBallHereLower() {
return lowerSensor.get();
}

public void stop() {
lowerMotor.set(0);
upperMotor.set(0);
}

@Override
public void periodic() {
towerUpperMotorEntry.setDouble(getSpeedUpper());
towerLowerMotorEntry.setDouble(getSpeedLower());

// This does not correctly show the status of the beam break
towerUpperSensorEntry.setBoolean(isBallHereUpper());
towerLowerSensorEntry.setBoolean(isBallHereLower());
}

}

package frc.robot.commands;

import edu.wpi.first.wpilibj2.command.CommandBase;
import frc.robot.Constants;
import frc.robot.subsystems.Tower;
public class LoadTower extends CommandBase {

private Tower tower;

//checks if command should end
private boolean finished;
/** Creates a new ToggleTower. /
/

Both tower motors will spin until sensor is set to false(the laser is tripped)
subsequent presses will turn the motors on and off, respectively
*/

public LoadTower(Tower tower) {
addRequirements(tower);
this.tower = tower;
}

// Called when the command is initially scheduled.
@Override
public void initialize() {

tower.setSpeedLower(Constants.TOWER_SPEED);
tower.setSpeedUpper(Constants.TOWER_SPEED);
finished = false;

}

// Called every time the scheduler runs while the command is scheduled.
@Override
public void execute() {

//sensor to check if balls are in stored position
if(tower.isBallHereUpper()){
  tower.setSpeedUpper(0);
}
  if(tower.isBallHereLower() && tower.isBallHereUpper()){
    tower.setSpeedLower(0);
    finished = true;
  }

}

// Called once the command ends or is interrupted.
@Override

public void end(boolean interrupted) {
tower.setSpeedUpper(0);
tower.setSpeedLower(0);
}

// Returns true when the command should end.
@Override
public boolean isFinished() {
//ends the command if the corresponding main is finished
return finished;
}
}

You are not comparing the value returned to anything.

You need to do… All you did is get the Boolean, but didn’t compare it to anything

if (tower.isBallHereUpper == false){
do this
}

In order to enter the if command you need a condition… is ball here returns the boolean and == “is equal to” true or false based on what you need…

See our interuppted code here…

No, you can use booleans directly as is. A comparison operator just returns Boolean so true ==true is redundant.

2 Likes

Ok, that makes sense… never done it that way, but I see what you mean now there… Guess that is what I get for thinking that I am starting to understand this whole programming thing :wink:

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.