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 }