/// <summary> /// Sets the state of the specified pin. /// </summary> /// <param name="pin"> /// The pin to alter. /// </param> /// <param name="state"> /// The state of the pin to set. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="pin"/> cannot be null. /// </exception> /// <exception cref="ObjectDisposedException"> /// This instance has been disposed and can no longer be used. /// </exception> /// <exception cref="ArgumentException"> /// The specified pin does not exist in the pin cache. /// </exception> /// <exception cref="System.IO.IOException"> /// Failed to write the new state to the device. /// </exception> public void SetPinState(IPCF8574Pin pin, PinState state) { if (pin == null) { throw new ArgumentNullException("pin"); } if (this._isDisposed) { throw new ObjectDisposedException("CyrusBuilt.MonoPi.IO.PCF.PCF8574GpioProvider"); } if (!this._pinCache.Contains(pin)) { throw new ArgumentException("Cannot set the state of a pin that does not exist in the pin cache.", "pin"); } // We only do this if the state is actually changing. PinState cstate = this._pinCache[this._pinCache.IndexOf(pin)].State; if (cstate != state) { Byte stateVal = this._currentStates.Empty ? (Byte)0 : this._currentStates.ToByteArray()[0]; this._currentStates.Set(pin.Address, (state == PinState.High)); this._device.WriteByte(this._busAddress, stateVal); this.OnPinStateChanged(new PinStateChangeEventArgs(pin.Address, cstate, state)); } }
/// <summary> /// Polls all the pins on the PCF8574 every ~50ms and refreshes their states. /// This will fire a state change event for any and all pins that have changed /// state since the last check. This will also fire a failure event if any /// exceptions are thrown. /// </summary> private void ExecutePoll() { while (!this._pollAbort) { try { // Read device pin states. Byte[] buffer = this._device.ReadBytes(this._busAddress, 1); BitSet pinStates = BitSet.ValueOf(buffer); // Determine if there is a pin state difference. IPCF8574Pin pin = null; PinState newState = PinState.Low; PinState oldState = PinState.Low; for (Int32 index = 0; index < pinStates.Size; index++) { if (pinStates.Get(index) != this._currentStates.Get(index)) { pin = PCF8574Pin.ALL[index]; // Is the state actually changing? newState = pinStates.Get(index) ? PinState.High : PinState.Low; oldState = this._pinCache[this._pinCache.IndexOf(pin)].State; if (newState != oldState) { // Cache the new state. this._pinCache[this._pinCache.IndexOf(pin)].SetState(newState); this._currentStates.Set(index, pinStates.Get(index)); // Only dispatch events for input pins. if (this.GetPinMode(pin) == PinMode.IN) { this.OnPinStateChanged(new PinStateChangeEventArgs(pin.Address, oldState, newState)); } } } } Thread.Sleep(50); } catch (Exception ex) { // If we failed (likely due to an I/O error), then // fire the failure event and gracefully abort the // the poll thread. this.OnPinPollFailed(new PinPollFailEventArgs(ex)); lock (_syncLock) { this._pollAbort = true; } } } }
/// <summary> /// Gets the current state of the specified pin in the pin cache. /// </summary> /// <param name="pin"> /// The pin to get the state from. /// </param> /// <returns> /// The state of the pin. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="pin"/> cannot be null. /// </exception> /// <exception cref="ObjectDisposedException"> /// This instance has been disposed and can no longer be used. /// </exception> /// <exception cref="ArgumentException"> /// The specified pin does not exist in the pin cache. /// </exception> public PinState GetPinState(IPCF8574Pin pin) { if (pin == null) { throw new ArgumentNullException("pin"); } if (this._isDisposed) { throw new ObjectDisposedException("CyrusBuilt.MonoPi.IO.PCF.PCF8574GpioProvider"); } if (!this._pinCache.Contains(pin)) { throw new ArgumentException("The specified pin does not exist in the pin cache.", "pin"); } return(this._pinCache[this._pinCache.IndexOf(pin)].State); }
/// <summary> /// Sets the mode of the specified pin. /// </summary> /// <param name="pin"> /// The pin to alter. /// </param> /// <param name="mode"> /// The mode to set. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="pin"/> cannot be null. /// </exception> /// <exception cref="ObjectDisposedException"> /// This instance has been disposed and can no longer be used. /// </exception> /// <exception cref="ArgumentException"> /// The specified pin does not exist in the pin cache. /// </exception> public void SetPinMode(IPCF8574Pin pin, PinMode mode) { if (pin == null) { throw new ArgumentNullException("pin"); } if (this._isDisposed) { throw new ObjectDisposedException("CyrusBuilt.MonoPi.IO.PCF.PCF8574GpioProvider"); } if (!this._pinCache.Contains(pin)) { throw new ArgumentException("Cannot set the mode of a pin that does not exist in the pin cache.", "pin"); } this._pinCache[this._pinCache.IndexOf(pin)].SetMode(mode); }
/// <summary> /// Gets the current state of the specified pin in the pin cache. /// </summary> /// <param name="pin"> /// The pin to get the state from. /// </param> /// <returns> /// The state of the pin. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="pin"/> cannot be null. /// </exception> /// <exception cref="ObjectDisposedException"> /// This instance has been disposed and can no longer be used. /// </exception> /// <exception cref="ArgumentException"> /// The specified pin does not exist in the pin cache. /// </exception> public PinState GetPinState(IPCF8574Pin pin) { if (pin == null) { throw new ArgumentNullException("pin"); } if (this._isDisposed) { throw new ObjectDisposedException("CyrusBuilt.MonoPi.IO.PCF.PCF8574GpioProvider"); } if (!this._pinCache.Contains(pin)) { throw new ArgumentException("The specified pin does not exist in the pin cache.", "pin"); } return this._pinCache[this._pinCache.IndexOf(pin)].State; }