Programming Limit Switches

Limit switches are often used to control mechanisms on robots. While limit switches are simple to use, they only can sense a single position of a moving part. This makes them ideal for ensuring that movement doesn’t exceed some limit but not so good at controlling the speed of the movement as it approaches the limit. For example, a rotational shoulder joint on a robot arm would best be controlled using a potentiometer or an absolute encoder. A limit switch could make sure that if the potentiometer ever failed, the limit switch would stop the robot from going too far and causing damage.

Limit switches can have “normally open” or “normally closed” outputs. This will control if a high signal means the switch is opened or closed. To learn more about limit switch hardware see this article.

Controlling a Motor with Two Limit Switches

  DigitalInput m_toplimitSwitch = new DigitalInput(0);
  DigitalInput m_bottomlimitSwitch = new DigitalInput(1);
  PWMVictorSPX m_motor = new PWMVictorSPX(0);
  Joystick m_joystick = new Joystick(0);

  @Override
  public void teleopPeriodic() {
    setMotorSpeed(m_joystick.getRawAxis(2));
  }

  /**
   * Sets the motor speed based on joystick input while respecting limit switches.
   *
   * @param speed the desired speed of the motor, positive for up and negative for down
   */
  public void setMotorSpeed(double speed) {
    if (speed > 0) {
      if (m_toplimitSwitch.get()) {
        // We are going up and top limit is tripped so stop
        m_motor.set(0);
      } else {
        // We are going up but top limit is not tripped so go at commanded speed
        m_motor.set(speed);
      }
    } else {
      if (m_bottomlimitSwitch.get()) {
        // We are going down and bottom limit is tripped so stop
        m_motor.set(0);
      } else {
        // We are going down but bottom limit is not tripped so go at commanded speed
        m_motor.set(speed);
      }
    }
  }
  frc::DigitalInput m_toplimitSwitch{0};
  frc::DigitalInput m_bottomlimitSwitch{1};
  frc::PWMVictorSPX m_motor{0};
  frc::Joystick m_joystick{0};
  void TeleopPeriodic() override { SetMotorSpeed(m_joystick.GetRawAxis(2)); }
  void SetMotorSpeed(double speed) {
    if (speed > 0) {
      if (m_toplimitSwitch.Get()) {
        // We are going up and top limit is tripped so stop
        m_motor.Set(0);
      } else {
        // We are going up but top limit is not tripped so go at commanded speed
        m_motor.Set(speed);
      }
    } else {
      if (m_bottomlimitSwitch.Get()) {
        // We are going down and bottom limit is tripped so stop
        m_motor.Set(0);
      } else {
        // We are going down but bottom limit is not tripped so go at commanded
        // speed
        m_motor.Set(speed);
      }
    }
  }