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 org.wpilib.hardware.rotation;
006
007import org.wpilib.hardware.hal.DutyCycleJNI;
008import org.wpilib.hardware.hal.HAL;
009import org.wpilib.util.sendable.Sendable;
010import org.wpilib.util.sendable.SendableBuilder;
011import org.wpilib.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 * These can be attached to any SmartIO.
018 */
019public class DutyCycle implements Sendable, AutoCloseable {
020  // Explicitly package private
021  final int m_handle;
022  private final int m_channel;
023
024  /**
025   * Constructs a DutyCycle input from a smartio channel.
026   *
027   * @param channel The channel to use.
028   */
029  @SuppressWarnings("this-escape")
030  public DutyCycle(int channel) {
031    m_handle = DutyCycleJNI.initialize(channel);
032
033    m_channel = channel;
034    HAL.reportUsage("IO", channel, "DutyCycle");
035    SendableRegistry.add(this, "Duty Cycle", channel);
036  }
037
038  /** Close the DutyCycle and free all resources. */
039  @Override
040  public void close() {
041    SendableRegistry.remove(this);
042    DutyCycleJNI.free(m_handle);
043  }
044
045  /**
046   * Get the frequency of the duty cycle signal.
047   *
048   * @return frequency in Hertz
049   */
050  public double getFrequency() {
051    return DutyCycleJNI.getFrequency(m_handle);
052  }
053
054  /**
055   * Get the output ratio of the duty cycle signal.
056   *
057   * <p>0 means always low, 1 means always high.
058   *
059   * @return output ratio between 0 and 1
060   */
061  public double getOutput() {
062    return DutyCycleJNI.getOutput(m_handle);
063  }
064
065  /**
066   * Get the raw high time of the duty cycle signal.
067   *
068   * @return high time of last pulse in nanoseconds
069   */
070  public int getHighTimeNanoseconds() {
071    return DutyCycleJNI.getHighTime(m_handle);
072  }
073
074  /**
075   * Get the channel of the source.
076   *
077   * @return the source channel
078   */
079  public int getSourceChannel() {
080    return m_channel;
081  }
082
083  @Override
084  public void initSendable(SendableBuilder builder) {
085    builder.setSmartDashboardType("Duty Cycle");
086    builder.addDoubleProperty("Frequency", this::getFrequency, null);
087    builder.addDoubleProperty("Output", this::getOutput, null);
088  }
089}