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.AnalogJNI; 008import edu.wpi.first.hal.HAL; 009import edu.wpi.first.hal.SimDevice; 010import edu.wpi.first.util.sendable.Sendable; 011import edu.wpi.first.util.sendable.SendableBuilder; 012import edu.wpi.first.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 * 019 * <p>Connected to each analog channel is an averaging and oversampling engine. This engine 020 * accumulates the specified ( by setAverageBits() and setOversampleBits() ) number of samples 021 * before returning a new value. This is not a sliding window average. The only difference between 022 * the oversampled samples and the averaged samples is that the oversampled samples are simply 023 * accumulated effectively increasing the resolution, while the averaged samples are divided by the 024 * number of samples to retain the resolution, but get more stable values. 025 */ 026public class AnalogInput implements Sendable, AutoCloseable { 027 int m_port; // explicit no modifier, private and package accessible. 028 private int m_channel; 029 030 /** 031 * Construct an analog channel. 032 * 033 * @param channel The channel number to represent. 0-3 are on-board 4-7 are on the MXP port. 034 */ 035 @SuppressWarnings("this-escape") 036 public AnalogInput(final int channel) { 037 AnalogJNI.checkAnalogInputChannel(channel); 038 m_channel = channel; 039 040 m_port = AnalogJNI.initializeAnalogInputPort(channel); 041 042 HAL.reportUsage("IO", channel, "AnalogInput"); 043 SendableRegistry.add(this, "AnalogInput", channel); 044 } 045 046 @Override 047 public void close() { 048 SendableRegistry.remove(this); 049 AnalogJNI.freeAnalogInputPort(m_port); 050 m_port = 0; 051 m_channel = 0; 052 } 053 054 /** 055 * Get a sample straight from this channel. The sample is a 12-bit value representing the 0V to 056 * 3.3V range of the A/D converter. The units are in A/D converter codes. Use GetVoltage() to get 057 * the analog value in calibrated units. 058 * 059 * @return A sample straight from this channel. 060 */ 061 public int getValue() { 062 return AnalogJNI.getAnalogValue(m_port); 063 } 064 065 /** 066 * Get a sample from the output of the oversample and average engine for this channel. The sample 067 * is 12-bit + the bits configured in SetOversampleBits(). The value configured in 068 * setAverageBits() will cause this value to be averaged 2^bits number of samples. This is not a 069 * sliding window. The sample will not change until 2^(OversampleBits + AverageBits) samples have 070 * been acquired from this channel. Use getAverageVoltage() to get the analog value in calibrated 071 * units. 072 * 073 * @return A sample from the oversample and average engine for this channel. 074 */ 075 public int getAverageValue() { 076 return AnalogJNI.getAnalogAverageValue(m_port); 077 } 078 079 /** 080 * Get a scaled sample straight from this channel. The value is scaled to units of Volts using the 081 * calibrated scaling data from getLSBWeight() and getOffset(). 082 * 083 * @return A scaled sample straight from this channel. 084 */ 085 public double getVoltage() { 086 return AnalogJNI.getAnalogVoltage(m_port); 087 } 088 089 /** 090 * Get a scaled sample from the output of the oversample and average engine for this channel. The 091 * value is scaled to units of Volts using the calibrated scaling data from getLSBWeight() and 092 * getOffset(). Using oversampling will cause this value to be higher resolution, but it will 093 * update more slowly. Using averaging will cause this value to be more stable, but it will update 094 * more slowly. 095 * 096 * @return A scaled sample from the output of the oversample and average engine for this channel. 097 */ 098 public double getAverageVoltage() { 099 return AnalogJNI.getAnalogAverageVoltage(m_port); 100 } 101 102 /** 103 * Get the factory scaling the least significant bit weight constant. The least significant bit 104 * weight constant for the channel that was calibrated in manufacturing and stored in an eeprom. 105 * 106 * <p>Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9) 107 * 108 * @return Least significant bit weight. 109 */ 110 public long getLSBWeight() { 111 return AnalogJNI.getAnalogLSBWeight(m_port); 112 } 113 114 /** 115 * Get the factory scaling offset constant. The offset constant for the channel that was 116 * calibrated in manufacturing and stored in an eeprom. 117 * 118 * <p>Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9) 119 * 120 * @return Offset constant. 121 */ 122 public int getOffset() { 123 return AnalogJNI.getAnalogOffset(m_port); 124 } 125 126 /** 127 * Get the channel number. 128 * 129 * @return The channel number. 130 */ 131 public int getChannel() { 132 return m_channel; 133 } 134 135 /** 136 * Set the number of averaging bits. This sets the number of averaging bits. The actual number of 137 * averaged samples is 2^bits. The averaging is done automatically in the FPGA. 138 * 139 * @param bits The number of averaging bits. 140 */ 141 public void setAverageBits(final int bits) { 142 AnalogJNI.setAnalogAverageBits(m_port, bits); 143 } 144 145 /** 146 * Get the number of averaging bits. This gets the number of averaging bits from the FPGA. The 147 * actual number of averaged samples is 2^bits. The averaging is done automatically in the FPGA. 148 * 149 * @return The number of averaging bits. 150 */ 151 public int getAverageBits() { 152 return AnalogJNI.getAnalogAverageBits(m_port); 153 } 154 155 /** 156 * Set the number of oversample bits. This sets the number of oversample bits. The actual number 157 * of oversampled values is 2^bits. The oversampling is done automatically in the FPGA. 158 * 159 * @param bits The number of oversample bits. 160 */ 161 public void setOversampleBits(final int bits) { 162 AnalogJNI.setAnalogOversampleBits(m_port, bits); 163 } 164 165 /** 166 * Get the number of oversample bits. This gets the number of oversample bits from the FPGA. The 167 * actual number of oversampled values is 2^bits. The oversampling is done automatically in the 168 * FPGA. 169 * 170 * @return The number of oversample bits. 171 */ 172 public int getOversampleBits() { 173 return AnalogJNI.getAnalogOversampleBits(m_port); 174 } 175 176 /** 177 * Set the sample rate per channel. 178 * 179 * <p>This is a global setting for all channels. The maximum rate is 500kS/s divided by the number 180 * of channels in use. This is 62500 samples/s per channel if all 8 channels are used. 181 * 182 * @param samplesPerSecond The number of samples per second. 183 */ 184 public static void setGlobalSampleRate(final double samplesPerSecond) { 185 AnalogJNI.setAnalogSampleRate(samplesPerSecond); 186 } 187 188 /** 189 * Get the current sample rate. 190 * 191 * <p>This assumes one entry in the scan list. This is a global setting for all channels. 192 * 193 * @return Sample rate. 194 */ 195 public static double getGlobalSampleRate() { 196 return AnalogJNI.getAnalogSampleRate(); 197 } 198 199 /** 200 * Indicates this input is used by a simulated device. 201 * 202 * @param device simulated device handle 203 */ 204 public void setSimDevice(SimDevice device) { 205 AnalogJNI.setAnalogInputSimDevice(m_port, device.getNativeHandle()); 206 } 207 208 @Override 209 public void initSendable(SendableBuilder builder) { 210 builder.setSmartDashboardType("Analog Input"); 211 builder.addDoubleProperty("Value", this::getAverageVoltage, null); 212 } 213}