001// Copyright (c) FIRST and other WPILib contributors.
002// Open Source Software; you can modify and/or share it under the terms of
003// the WPILib BSD license file in the root directory of this project.
004
005package edu.wpi.first.wpilibj;
006
007import edu.wpi.first.hal.DutyCycleJNI;
008import edu.wpi.first.hal.HAL;
009import edu.wpi.first.util.sendable.Sendable;
010import edu.wpi.first.util.sendable.SendableBuilder;
011import edu.wpi.first.util.sendable.SendableRegistry;
012
013/**
014 * Class to read a duty cycle PWM input.
015 *
016 * <p>PWM input signals are specified with a frequency and a ratio of high to low in that frequency.
017 * There are 8 of these in the roboRIO, and they can be attached to any SmartIO Channel.
018 *
019 * <p>These can be combined as the input of an AnalogTrigger to a Counter in order to implement
020 * rollover checking.
021 */
022public class DutyCycle implements Sendable, AutoCloseable {
023  // Explicitly package private
024  final int m_handle;
025  private final int m_channel;
026
027  /**
028   * Constructs a DutyCycle input from a smartio channel.
029   *
030   * @param channel The channel to use.
031   */
032  @SuppressWarnings("this-escape")
033  public DutyCycle(int channel) {
034    m_handle = DutyCycleJNI.initialize(channel);
035
036    m_channel = channel;
037    HAL.reportUsage("IO", channel, "DutyCycle");
038    SendableRegistry.add(this, "Duty Cycle", channel);
039  }
040
041  /** Close the DutyCycle and free all resources. */
042  @Override
043  public void close() {
044    SendableRegistry.remove(this);
045    DutyCycleJNI.free(m_handle);
046  }
047
048  /**
049   * Get the frequency of the duty cycle signal.
050   *
051   * @return frequency in Hertz
052   */
053  public double getFrequency() {
054    return DutyCycleJNI.getFrequency(m_handle);
055  }
056
057  /**
058   * Get the output ratio of the duty cycle signal.
059   *
060   * <p>0 means always low, 1 means always high.
061   *
062   * @return output ratio between 0 and 1
063   */
064  public double getOutput() {
065    return DutyCycleJNI.getOutput(m_handle);
066  }
067
068  /**
069   * Get the raw high time of the duty cycle signal.
070   *
071   * @return high time of last pulse in nanoseconds
072   */
073  public int getHighTimeNanoseconds() {
074    return DutyCycleJNI.getHighTime(m_handle);
075  }
076
077  /**
078   * Get the channel of the source.
079   *
080   * @return the source channel
081   */
082  public int getSourceChannel() {
083    return m_channel;
084  }
085
086  @Override
087  public void initSendable(SendableBuilder builder) {
088    builder.setSmartDashboardType("Duty Cycle");
089    builder.addDoubleProperty("Frequency", this::getFrequency, null);
090    builder.addDoubleProperty("Output", this::getOutput, null);
091  }
092}