001/*----------------------------------------------------------------------------*/ 002/* Copyright (c) FIRST 2008-2017. 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 008package edu.wpi.first.wpilibj; 009 010import edu.wpi.first.wpilibj.hal.FRCNetComm.tResourceType; 011import edu.wpi.first.wpilibj.hal.HAL; 012import edu.wpi.first.wpilibj.hal.SolenoidJNI; 013import edu.wpi.first.wpilibj.livewindow.LiveWindow; 014import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable; 015import edu.wpi.first.wpilibj.tables.ITable; 016import edu.wpi.first.wpilibj.tables.ITableListener; 017 018/** 019 * Solenoid class for running high voltage Digital Output on the PCM. 020 * 021 * <p>The Solenoid class is typically used for pneumatic solenoids, but could be used for any 022 * device within the current spec of the PCM. 023 */ 024public class Solenoid extends SolenoidBase implements LiveWindowSendable { 025 026 private final int m_channel; // The channel to control. 027 private int m_solenoidHandle; 028 029 /** 030 * Constructor using the default PCM ID (defaults to 0). 031 * 032 * @param channel The channel on the PCM to control (0..7). 033 */ 034 public Solenoid(final int channel) { 035 this(getDefaultSolenoidModule(), channel); 036 } 037 038 /** 039 * Constructor. 040 * 041 * @param moduleNumber The CAN ID of the PCM the solenoid is attached to. 042 * @param channel The channel on the PCM to control (0..7). 043 */ 044 public Solenoid(final int moduleNumber, final int channel) { 045 super(moduleNumber); 046 m_channel = channel; 047 048 checkSolenoidModule(m_moduleNumber); 049 checkSolenoidChannel(m_channel); 050 051 int portHandle = SolenoidJNI.getPortWithModule((byte) m_moduleNumber, (byte) m_channel); 052 m_solenoidHandle = SolenoidJNI.initializeSolenoidPort(portHandle); 053 054 LiveWindow.addActuator("Solenoid", m_moduleNumber, m_channel, this); 055 HAL.report(tResourceType.kResourceType_Solenoid, m_channel, m_moduleNumber); 056 } 057 058 /** 059 * Destructor. 060 */ 061 public synchronized void free() { 062 SolenoidJNI.freeSolenoidPort(m_solenoidHandle); 063 m_solenoidHandle = 0; 064 if (m_table != null) { 065 m_table.removeTableListener(m_tableListener); 066 } 067 super.free(); 068 } 069 070 /** 071 * Set the value of a solenoid. 072 * 073 * @param on True will turn the solenoid output on. False will turn the solenoid output off. 074 */ 075 public void set(boolean on) { 076 SolenoidJNI.setSolenoid(m_solenoidHandle, on); 077 } 078 079 /** 080 * Read the current value of the solenoid. 081 * 082 * @return True if the solenoid output is on or false if the solenoid output is off. 083 */ 084 public boolean get() { 085 return SolenoidJNI.getSolenoid(m_solenoidHandle); 086 } 087 088 /** 089 * Check if solenoid is blacklisted. If a solenoid is shorted, it is added to the blacklist and 090 * disabled until power cycle, or until faults are cleared. 091 * 092 * @return If solenoid is disabled due to short. 093 * @see #clearAllPCMStickyFaults() 094 */ 095 public boolean isBlackListed() { 096 int value = getPCMSolenoidBlackList() & (1 << m_channel); 097 return value != 0; 098 } 099 100 /* 101 * Live Window code, only does anything if live window is activated. 102 */ 103 public String getSmartDashboardType() { 104 return "Solenoid"; 105 } 106 107 private ITable m_table; 108 private ITableListener m_tableListener; 109 110 @Override 111 public void initTable(ITable subtable) { 112 m_table = subtable; 113 updateTable(); 114 } 115 116 @Override 117 public ITable getTable() { 118 return m_table; 119 } 120 121 @Override 122 public void updateTable() { 123 if (m_table != null) { 124 m_table.putBoolean("Value", get()); 125 } 126 } 127 128 @Override 129 public void startLiveWindowMode() { 130 set(false); // Stop for safety 131 m_tableListener = (source, key, value, isNew) -> set((Boolean) value); 132 m_table.addTableListener("Value", m_tableListener, true); 133 } 134 135 @Override 136 public void stopLiveWindowMode() { 137 set(false); // Stop for safety 138 // TODO: Broken, should only remove the listener from "Value" only. 139 m_table.removeTableListener(m_tableListener); 140 } 141}