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.discrete;
006
007import org.wpilib.hardware.hal.AnalogInputJNI;
008import org.wpilib.hardware.hal.HAL;
009import org.wpilib.hardware.hal.SimDevice;
010import org.wpilib.util.sendable.Sendable;
011import org.wpilib.util.sendable.SendableBuilder;
012import org.wpilib.util.sendable.SendableRegistry;
013
014/**
015 * Analog channel class.
016 *
017 * <p>Each analog channel is read from hardware as a 12-bit number representing 0V to 3.3V.
018 */
019public class AnalogInput implements Sendable, AutoCloseable {
020  int m_port; // explicit no modifier, private and package accessible.
021  private int m_channel;
022
023  /**
024   * Construct an analog channel.
025   *
026   * @param channel The SmartIO channel for the analog input.
027   */
028  @SuppressWarnings("this-escape")
029  public AnalogInput(final int channel) {
030    AnalogInputJNI.checkAnalogInputChannel(channel);
031    m_channel = channel;
032
033    m_port = AnalogInputJNI.initializeAnalogInputPort(channel);
034
035    HAL.reportUsage("IO", channel, "AnalogInput");
036    SendableRegistry.add(this, "AnalogInput", channel);
037  }
038
039  @Override
040  public void close() {
041    SendableRegistry.remove(this);
042    AnalogInputJNI.freeAnalogInputPort(m_port);
043    m_port = 0;
044    m_channel = 0;
045  }
046
047  /**
048   * Get a sample straight from this channel. The sample is a 12-bit value representing the 0V to
049   * 3.3V range of the A/D converter. The units are in A/D converter codes. Use GetVoltage() to get
050   * the analog value in calibrated units.
051   *
052   * @return A sample straight from this channel.
053   */
054  public int getValue() {
055    return AnalogInputJNI.getAnalogValue(m_port);
056  }
057
058  /**
059   * Get a scaled sample straight from this channel. The value is scaled to units of Volts.
060   *
061   * @return A scaled sample straight from this channel.
062   */
063  public double getVoltage() {
064    return AnalogInputJNI.getAnalogVoltage(m_port);
065  }
066
067  /**
068   * Get the channel number.
069   *
070   * @return The channel number.
071   */
072  public int getChannel() {
073    return m_channel;
074  }
075
076  /**
077   * Indicates this input is used by a simulated device.
078   *
079   * @param device simulated device handle
080   */
081  public void setSimDevice(SimDevice device) {
082    AnalogInputJNI.setAnalogInputSimDevice(m_port, device.getNativeHandle());
083  }
084
085  @Override
086  public void initSendable(SendableBuilder builder) {
087    builder.setSmartDashboardType("Analog Input");
088    builder.addDoubleProperty("Value", this::getVoltage, null);
089  }
090}