001/*----------------------------------------------------------------------------*/ 002/* Copyright (c) 2008-2018 FIRST. 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.smartdashboard.SendableBuilder; 014 015/** 016 * Solenoid class for running high voltage Digital Output on the PCM. 017 * 018 * <p>The Solenoid class is typically used for pneumatic solenoids, but could be used for any 019 * device within the current spec of the PCM. 020 */ 021public class Solenoid extends SolenoidBase implements Sendable { 022 private final int m_channel; // The channel to control. 023 private int m_solenoidHandle; 024 025 /** 026 * Constructor using the default PCM ID (defaults to 0). 027 * 028 * @param channel The channel on the PCM to control (0..7). 029 */ 030 public Solenoid(final int channel) { 031 this(SensorBase.getDefaultSolenoidModule(), channel); 032 } 033 034 /** 035 * Constructor. 036 * 037 * @param moduleNumber The CAN ID of the PCM the solenoid is attached to. 038 * @param channel The channel on the PCM to control (0..7). 039 */ 040 public Solenoid(final int moduleNumber, final int channel) { 041 super(moduleNumber); 042 m_channel = channel; 043 044 SensorBase.checkSolenoidModule(m_moduleNumber); 045 SensorBase.checkSolenoidChannel(m_channel); 046 047 int portHandle = SolenoidJNI.getPortWithModule((byte) m_moduleNumber, (byte) m_channel); 048 m_solenoidHandle = SolenoidJNI.initializeSolenoidPort(portHandle); 049 050 HAL.report(tResourceType.kResourceType_Solenoid, m_channel, m_moduleNumber); 051 setName("Solenoid", m_moduleNumber, m_channel); 052 } 053 054 /** 055 * Destructor. 056 */ 057 @Override 058 public synchronized void free() { 059 super.free(); 060 SolenoidJNI.freeSolenoidPort(m_solenoidHandle); 061 m_solenoidHandle = 0; 062 } 063 064 /** 065 * Set the value of a solenoid. 066 * 067 * @param on True will turn the solenoid output on. False will turn the solenoid output off. 068 */ 069 public void set(boolean on) { 070 SolenoidJNI.setSolenoid(m_solenoidHandle, on); 071 } 072 073 /** 074 * Read the current value of the solenoid. 075 * 076 * @return True if the solenoid output is on or false if the solenoid output is off. 077 */ 078 public boolean get() { 079 return SolenoidJNI.getSolenoid(m_solenoidHandle); 080 } 081 082 /** 083 * Check if solenoid is blacklisted. If a solenoid is shorted, it is added to the blacklist and 084 * disabled until power cycle, or until faults are cleared. 085 * 086 * @return If solenoid is disabled due to short. 087 * @see #clearAllPCMStickyFaults() 088 */ 089 public boolean isBlackListed() { 090 int value = getPCMSolenoidBlackList() & (1 << m_channel); 091 return value != 0; 092 } 093 094 /** 095 * Set the pulse duration in the PCM. This is used in conjunction with 096 * the startPulse method to allow the PCM to control the timing of a pulse. 097 * The timing can be controlled in 0.01 second increments. 098 * 099 * @param durationSeconds The duration of the pulse, from 0.01 to 2.55 seconds. 100 * 101 * @see #startPulse() 102 */ 103 public void setPulseDuration(double durationSeconds) { 104 long durationMS = (long) (durationSeconds * 1000); 105 SolenoidJNI.setOneShotDuration(m_solenoidHandle, durationMS); 106 } 107 108 /** 109 * Trigger the PCM to generate a pulse of the duration set in 110 * setPulseDuration. 111 * 112 * @see #setPulseDuration(double) 113 */ 114 public void startPulse() { 115 SolenoidJNI.fireOneShot(m_solenoidHandle); 116 } 117 118 @Override 119 public void initSendable(SendableBuilder builder) { 120 builder.setSmartDashboardType("Solenoid"); 121 builder.setSafeState(() -> set(false)); 122 builder.addBooleanProperty("Value", this::get, this::set); 123 } 124}