001/*----------------------------------------------------------------------------*/ 002/* Copyright (c) FIRST 2008-2014. All Rights Reserved. */ 003/* Open Source Software - may be modified and shared by FRC teams. The code */ 004/* must be accompanied by the FIRST BSD license file in the root directory of */ 005/* the project. */ 006/*----------------------------------------------------------------------------*/ 007package edu.wpi.first.wpilibj; 008import java.nio.ByteBuffer; 009import java.nio.IntBuffer; 010 011import edu.wpi.first.wpilibj.hal.HALUtil; 012import edu.wpi.first.wpilibj.hal.PowerJNI; 013import edu.wpi.first.wpilibj.interfaces.Potentiometer; 014import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable; 015import edu.wpi.first.wpilibj.tables.ITable; 016 017/** 018 * Class for reading analog potentiometers. Analog potentiometers read 019 * in an analog voltage that corresponds to a position. The position is 020 * in whichever units you choose, by way of the scaling and offset 021 * constants passed to the constructor. 022 * 023 * @author Alex Henning 024 * @author Colby Skeggs (rail voltage) 025 */ 026public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable { 027 private double m_fullRange, m_offset; 028 private AnalogInput m_analog_input; 029 private boolean m_init_analog_input; 030 031 /** 032 * Common initialization code called by all constructors. 033 * @param input The {@link AnalogInput} this potentiometer is plugged into. 034 * @param fullRange The scaling to multiply the voltage by to get a meaningful unit. 035 * @param offset The offset to add to the scaled value for controlling the zero value 036 */ 037 private void initPot(final AnalogInput input, double fullRange, double offset) { 038 this.m_fullRange = fullRange; 039 this.m_offset = offset; 040 m_analog_input = input; 041 } 042 043 /** 044 * AnalogPotentiometer constructor. 045 * 046 * Use the fullRange and offset values so that the output produces 047 * meaningful values. I.E: you have a 270 degree potentiometer and 048 * you want the output to be degrees with the halfway point as 0 049 * degrees. The fullRange value is 270.0(degrees) and the offset is 050 * -135.0 since the halfway point after scaling is 135 degrees. 051 * 052 * This will calculate the result from the fullRange times the 053 * fraction of the supply voltage, plus the offset. 054 * 055 * @param channel The analog channel this potentiometer is plugged into. 056 * @param fullRange The scaling to multiply the fraction by to get a meaningful unit. 057 * @param offset The offset to add to the scaled value for controlling the zero value 058 */ 059 public AnalogPotentiometer(final int channel, double fullRange, double offset) { 060 AnalogInput input = new AnalogInput(channel); 061 m_init_analog_input = true; 062 initPot(input, fullRange, offset); 063 } 064 065 /** 066 * AnalogPotentiometer constructor. 067 * 068 * Use the fullRange and offset values so that the output produces 069 * meaningful values. I.E: you have a 270 degree potentiometer and 070 * you want the output to be degrees with the halfway point as 0 071 * degrees. The fullRange value is 270.0(degrees) and the offset is 072 * -135.0 since the halfway point after scaling is 135 degrees. 073 * 074 * This will calculate the result from the fullRange times the 075 * fraction of the supply voltage, plus the offset. 076 * 077 * @param input The {@link AnalogInput} this potentiometer is plugged into. 078 * @param fullRange The scaling to multiply the fraction by to get a meaningful unit. 079 * @param offset The offset to add to the scaled value for controlling the zero value 080 */ 081 public AnalogPotentiometer(final AnalogInput input, double fullRange, double offset) { 082 m_init_analog_input = false; 083 initPot(input, fullRange, offset); 084 } 085 086 /** 087 * AnalogPotentiometer constructor. 088 * 089 * Use the fullRange and offset values so that the output produces 090 * meaningful values. I.E: you have a 270 degree potentiometer and 091 * you want the output to be degrees with the halfway point as 0 092 * degrees. The fullRange value is 270.0(degrees) and the offset is 093 * -135.0 since the halfway point after scaling is 135 degrees. 094 * 095 * @param channel The analog channel this potentiometer is plugged into. 096 * @param scale The scaling to multiply the voltage by to get a meaningful unit. 097 */ 098 public AnalogPotentiometer(final int channel, double scale) { 099 this(channel, scale, 0); 100 } 101 102 /** 103 * AnalogPotentiometer constructor. 104 * 105 * Use the fullRange and offset values so that the output produces 106 * meaningful values. I.E: you have a 270 degree potentiometer and 107 * you want the output to be degrees with the halfway point as 0 108 * degrees. The fullRange value is 270.0(degrees) and the offset is 109 * -135.0 since the halfway point after scaling is 135 degrees. 110 * 111 * @param input The {@link AnalogInput} this potentiometer is plugged into. 112 * @param scale The scaling to multiply the voltage by to get a meaningful unit. 113 */ 114 public AnalogPotentiometer(final AnalogInput input, double scale) { 115 this(input, scale, 0); 116 } 117 118 /** 119 * AnalogPotentiometer constructor. 120 * 121 * @param channel The analog channel this potentiometer is plugged into. 122 */ 123 public AnalogPotentiometer(final int channel) { 124 this(channel, 1, 0); 125 } 126 127 /** 128 * AnalogPotentiometer constructor. 129 * 130 * @param input The {@link AnalogInput} this potentiometer is plugged into. 131 */ 132 public AnalogPotentiometer(final AnalogInput input) { 133 this(input, 1, 0); 134 } 135 136 /** 137 * Get the current reading of the potentiometer. 138 * 139 * @return The current position of the potentiometer. 140 */ 141 public double get() { 142 return (m_analog_input.getVoltage() / ControllerPower.getVoltage5V()) * m_fullRange + m_offset; 143 } 144 145 /** 146 * Implement the PIDSource interface. 147 * 148 * @return The current reading. 149 */ 150 public double pidGet() { 151 return get(); 152 } 153 154 155 /** 156 * Live Window code, only does anything if live window is activated. 157 */ 158 public String getSmartDashboardType(){ 159 return "Analog Input"; 160 } 161 private ITable m_table; 162 163 /** 164 * {@inheritDoc} 165 */ 166 public void initTable(ITable subtable) { 167 m_table = subtable; 168 updateTable(); 169 } 170 171 /** 172 * {@inheritDoc} 173 */ 174 public void updateTable() { 175 if (m_table != null) { 176 m_table.putNumber("Value", get()); 177 } 178 } 179 180 /** 181 * {@inheritDoc} 182 */ 183 public ITable getTable(){ 184 return m_table; 185 } 186 187 public void free(){ 188 if(m_init_analog_input){ 189 m_analog_input.free(); 190 m_analog_input = null; 191 m_init_analog_input = false; 192 } 193 } 194 195 /** 196 * Analog Channels don't have to do anything special when entering the LiveWindow. 197 * {@inheritDoc} 198 */ 199 public void startLiveWindowMode() {} 200 201 /** 202 * Analog Channels don't have to do anything special when exiting the LiveWindow. 203 * {@inheritDoc} 204 */ 205 public void stopLiveWindowMode() {} 206}