001 /*----------------------------------------------------------------------------*/
002 /* Copyright (c) FIRST 2008-2012. 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 /*----------------------------------------------------------------------------*/
007
008 package edu.wpi.first.wpilibj;
009
010 import edu.wpi.first.wpilibj.communication.UsageReporting;
011 import edu.wpi.first.wpilibj.livewindow.LiveWindow;
012 import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
013 import edu.wpi.first.wpilibj.tables.ITable;
014 import edu.wpi.first.wpilibj.tables.ITableListener;
015 import edu.wpi.first.wpilibj.util.AllocationException;
016 import edu.wpi.first.wpilibj.util.CheckedAllocationException;
017
018 /**
019 * Solenoid class for running high voltage Digital Output (9472 module).
020 *
021 * The Solenoid class is typically used for pneumatics solenoids, but could be used
022 * for any device within the current spec of the 9472 module.
023 */
024 public class Solenoid extends SolenoidBase implements LiveWindowSendable {
025
026 private int m_channel; ///< The channel on the module to control.
027
028 /**
029 * Common function to implement constructor behavior.
030 */
031 private synchronized void initSolenoid() {
032 checkSolenoidModule(m_moduleNumber);
033 checkSolenoidChannel(m_channel);
034
035 try {
036 m_allocated.allocate((m_moduleNumber - 1) * kSolenoidChannels + m_channel - 1);
037 } catch (CheckedAllocationException e) {
038 throw new AllocationException(
039 "Solenoid channel " + m_channel + " on module " + m_moduleNumber + " is already allocated");
040 }
041
042 LiveWindow.addActuator("Solenoid", m_moduleNumber, m_channel, this);
043 UsageReporting.report(UsageReporting.kResourceType_Solenoid, m_channel, m_moduleNumber - 1);
044 }
045
046 /**
047 * Constructor.
048 *
049 * @param channel The channel on the module to control.
050 */
051 public Solenoid(final int channel) {
052 super(getDefaultSolenoidModule());
053 m_channel = channel;
054 initSolenoid();
055 }
056
057 /**
058 * Constructor.
059 *
060 * @param moduleNumber The module number of the solenoid module to use.
061 * @param channel The channel on the module to control.
062 */
063 public Solenoid(final int moduleNumber, final int channel) {
064 super(moduleNumber);
065 m_channel = channel;
066 initSolenoid();
067 }
068
069 /**
070 * Destructor.
071 */
072 public synchronized void free() {
073 m_allocated.free((m_moduleNumber - 1) * kSolenoidChannels + m_channel - 1);
074 }
075
076 /**
077 * Set the value of a solenoid.
078 *
079 * @param on Turn the solenoid output off or on.
080 */
081 public void set(boolean on) {
082 byte value = (byte)(on ? 0xFF : 0x00);
083 byte mask = (byte)(1 << (m_channel - 1));
084
085 set(value, mask);
086 }
087
088 /**
089 * Read the current value of the solenoid.
090 *
091 * @return The current value of the solenoid.
092 */
093 public boolean get() {
094 int value = getAll() & ( 1 << (m_channel - 1));
095 return (value != 0);
096 }
097
098 /*
099 * Live Window code, only does anything if live window is activated.
100 */
101 public String getSmartDashboardType(){
102 return "Solenoid";
103 }
104 private ITable m_table;
105 private ITableListener m_table_listener;
106
107 /**
108 * {@inheritDoc}
109 */
110 public void initTable(ITable subtable) {
111 m_table = subtable;
112 updateTable();
113 }
114
115 /**
116 * {@inheritDoc}
117 */
118 public ITable getTable(){
119 return m_table;
120 }
121
122 /**
123 * {@inheritDoc}
124 */
125 public void updateTable() {
126 if (m_table != null) {
127 m_table.putBoolean("Value", get());
128 }
129 }
130
131
132 /**
133 * {@inheritDoc}
134 */
135 public void startLiveWindowMode() {
136 set(false); // Stop for safety
137 m_table_listener = new ITableListener() {
138 public void valueChanged(ITable itable, String key, Object value, boolean bln) {
139 set(((Boolean) value).booleanValue());
140 }
141 };
142 m_table.addTableListener("Value", m_table_listener, true);
143 }
144
145 /**
146 * {@inheritDoc}
147 */
148 public void stopLiveWindowMode() {
149 set(false); // Stop for safety
150 // TODO: Broken, should only remove the listener from "Value" only.
151 m_table.removeTableListener(m_table_listener);
152 }
153 }