/// <summary> /// Gets the specified pin from the pin cache. If the specified pin /// does not already exist in the cache, it will be cached first, /// then returned to the caller. /// </summary> /// <param name="pin"> /// The pin to get from the cache. /// </param> /// <returns> /// The cached instance of the specified pin. /// </returns> public IPCA9685Pin GetPin(IPCA9685Pin pin) { if (!this._pinCache.Contains(pin)) { this._pinCache.Add(pin); } return(this._pinCache[this._pinCache.IndexOf(pin)]); }
/// <summary> /// Gets the PWM on/off values for the specified pin. /// </summary> /// <param name="pin"> /// The pin to get the on/off values for (Channel 0 .. 15). /// </param> /// <returns> /// A tuple containing the on/off PWM values where Item1 contains the /// "on" value and Item2 contains the "Off" value. /// </returns> public Tuple <Int32, Int32> GetPwmOnOffValues(IPCA9685Pin pin) { if (!this.HasPin(pin)) { throw new ArgumentException("The specified pin does not exist in the pin cache."); } return(new Tuple <Int32, Int32>( this.GetPin(pin).PwmOnValue, this.GetPin(pin).PwmOffValue )); }
/// <summary> /// Initializes a new instance of the <see cref="CyrusBuilt.MonoPi.Components.Servos.PCA9685GpioServoDriver"/> /// class with a PCA9685 GPIO provider and pin. /// </summary> /// <param name="provider"> /// The PCA9685 GPIO provider. /// </param> /// <param name="pin"> /// The PCA9685 pin (channel) the servo is attached to. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="provider"/> cannot be null. - or - /// <paramref name="pin"/> cannot be null. /// </exception> public PCA9685GpioServoDriver(PCA9685GpioProvider provider, IPCA9685Pin pin) { if (provider == null) { throw new ArgumentNullException("provider"); } if (pin == null) { throw new ArgumentNullException("pin"); } this._provider = provider; this._pin = pin; this.UpdateResolution(); }
/// <summary> /// Sets the always off. /// </summary> /// <param name="pin"> /// The pin to set always off (Channel 0 .. 15). /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="pin"/> cannot be null. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="pin"/> does not exist in the pin cache. /// </exception> /// <exception cref="InvalidPinModeException"> /// The specified pin is not in PWM mode. /// </exception> /// <exception cref="IOException"> /// Unable to write to the specified channel (pin address). /// </exception> public void SetAlwaysOff(IPCA9685Pin pin) { this.ValidatePin(pin, 1, 0); Int32 chan = pin.Address; try { this._busDevice.WriteBytes(this._busAddr, new Byte[] { (Byte)(PCA9685_LED0_ON_L + 4 * chan), (Byte)0x00 }); this._busDevice.WriteBytes(this._busAddr, new Byte[] { (Byte)(PCA9685_LED0_ON_H + 4 * chan), (Byte)0x00 }); this._busDevice.WriteBytes(this._busAddr, new Byte[] { (Byte)(PCA9685_LED0_OFF_L + 4 * chan), (Byte)0x00 }); this._busDevice.WriteBytes(this._busAddr, new Byte[] { (Byte)(PCA9685_LED0_OFF_H + 4 * chan), (Byte)0x10 }); } catch (IOException ioEx) { throw new IOException("Error while trying to write to channel: " + chan.ToString(), ioEx); } this.CachePinValues(pin, 1, 0); }
/// <summary> /// Validates the specified pin and throws an exception if invalid. /// </summary> /// <param name="pin"> /// The pin to validate. /// </param> /// <param name="onPosition"> /// The PWM value to be considered in an "on" state. /// </param> /// <param name="offPosition"> /// The PWM value to be considered in an "off" state. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="pin"/> cannot be null. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="pin"/> does not exist in the pin cache. /// </exception> /// <exception cref="InvalidPinModeException"> /// The specified pin is not in PWM mode. /// </exception> private void ValidatePin(IPCA9685Pin pin, Int32 onPosition, Int32 offPosition) { if (pin == null) { throw new ArgumentNullException("pin"); } if (!this.HasPin(pin)) { throw new ArgumentException("The specified pin does not exist in the pin cache."); } if (pin.Mode != PinMode.PWM) { String errMsg = "Invalid pin mode [" + Enum.GetName(typeof(PinMode), pin.Mode) + "]; Unable to set PWM value " + onPosition.ToString() + ", " + offPosition.ToString(); throw new InvalidPinModeException(pin, errMsg); } }
/// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> /// <filterpriority>2</filterpriority> /// <remarks>Call <see cref="Dispose"/> when you are finished using the /// <see cref="CyrusBuilt.MonoPi.Components.Servos.PCA9685GpioServoDriver"/>. The <see cref="Dispose"/> method leaves /// the <see cref="CyrusBuilt.MonoPi.Components.Servos.PCA9685GpioServoDriver"/> in an unusable state. After calling /// <see cref="Dispose"/>, you must release all references to the /// <see cref="CyrusBuilt.MonoPi.Components.Servos.PCA9685GpioServoDriver"/> so the garbage collector can reclaim the /// memory that the <see cref="CyrusBuilt.MonoPi.Components.Servos.PCA9685GpioServoDriver"/> was occupying.</remarks> public void Dispose() { if (this._isDisposed) { return; } if (this._provider != null) { this._provider.Dispose(); this._provider = null; } if (this._pin != null) { this._pin.Dispose(); this._pin = null; } this._pos = 0; this._res = 0; this._isDisposed = true; }
/// <summary> /// Sets the PWM values for the specified pin. The LEDn_ON and LEDn_OFF /// counts can vary from 0 to 4095 max.<br/> /// The LEDn_ON and LEDn_OFF count registers should never be programmed /// with the same values.<br/><br/> /// Because the loading of the LEDn_ON and LEDn_OFF registers is via I2C-bus, /// and asynchronous to the internal oscillator, it is best to ensure that /// there are no visual artifacts of changing the ON and OFF values. This /// is achieved by updating the changes at the end of the LOW cycle. /// </summary> /// <param name="pin"> /// The pin to set the PWM values for (Channel 0 .. 15). /// </param> /// <param name="onPos"> /// The PWM threshold to consider the pin "on" (value between 0 and 4095). /// </param> /// <param name="offPos"> /// The PWM threshold to consider the pin "off" (value between 0 and 4095). /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="pin"/> cannot be null. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="pin"/> does not exist in the pin cache. - or - /// <paramref name="onPos"/> and <paramref name="offPos"/> are equal. /// </exception> /// <exception cref="InvalidPinModeException"> /// The specified pin is not in PWM mode. /// </exception> /// <exception cref="IOException"> /// Unable to write to the specified channel (pin address). /// </exception> public void SetPWM(IPCA9685Pin pin, Int32 onPos, Int32 offPos) { this.ValidatePin(pin, onPos, offPos); this.ValidatePwmValueInRange(onPos); this.ValidatePwmValueInRange(offPos); if (onPos == offPos) { throw new ArgumentException("ON [" + onPos.ToString() + "] and OFF [" + offPos.ToString() + "] values must be different."); } Int32 chan = pin.Address; try { this._busDevice.WriteBytes(this._busAddr, new Byte[] { (Byte)(PCA9685_LED0_ON_L + 4 * chan), (Byte)((Byte)onPos & 0xFF) }); this._busDevice.WriteBytes(this._busAddr, new Byte[] { (Byte)(PCA9685_LED0_ON_H + 4 * chan), (Byte)((Byte)onPos >> 8) }); this._busDevice.WriteBytes(this._busAddr, new Byte[] { (Byte)(PCA9685_LED0_OFF_L + 4 * chan), (Byte)((Byte)offPos & 0xFF) }); this._busDevice.WriteBytes(this._busAddr, new Byte[] { (Byte)(PCA9685_LED0_OFF_H + 4 * chan), (Byte)((Byte)offPos >> 8) }); } catch (IOException ioEx) { throw new IOException("Unable to write to channel: " + chan.ToString(), ioEx); } this.CachePinValues(pin, onPos, offPos); }
/// <summary> /// Sets the pulse duration in microseconds.<br/> /// Make sure duration doesn't exceed period time (1,000,000/freq)! /// </summary> /// <param name="pin"> /// The pin to set the pulse duration for (Channel 0 .. 15). /// </param> /// <param name="duration"> /// Pulse duration in microseconds. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="pin"/> cannot be null. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="pin"/> does not exist in the pin cache. /// </exception> /// <exception cref="InvalidPinModeException"> /// The specified pin is not in PWM mode. /// </exception> /// <exception cref="IOException"> /// Unable to write to the specified channel (pin address). /// </exception> public void SetPWM(IPCA9685Pin pin, Int32 duration) { Int32 offPos = this.CalcOffPosForPulseDuration(duration); this.SetPWM(pin, duration); }
/// <summary> /// Caches the pin values. /// </summary> /// <param name="pin"> /// The pin to cache the on/off values for. /// </param> /// <param name="onPosition"> /// The PWM threshold to consider the pin "on". /// </param> /// <param name="offPosition"> /// The PWM threshold to consider the pin "off". /// </param> private void CachePinValues(IPCA9685Pin pin, Int32 onPosition, Int32 offPosition) { this.GetPin(pin).PwmOnValue = onPosition; this.GetPin(pin).PwmOffValue = offPosition; }
/// <summary> /// Determines whether this instance has pin the specified pin /// in the internal pin cache. /// </summary> /// <param name="pin"> /// The pin to check for. /// </param> /// <returns> /// <c>true</c> if this instance has pin the specified pin; otherwise, <c>false</c>. /// </returns> public Boolean HasPin(IPCA9685Pin pin) { return(this._pinCache.Contains(pin)); }
/// <summary> /// Gets the PWM on/off values for the specified pin. /// </summary> /// <param name="pin"> /// The pin to get the on/off values for (Channel 0 .. 15). /// </param> /// <returns> /// A tuple containing the on/off PWM values where Item1 contains the /// "on" value and Item2 contains the "Off" value. /// </returns> public Tuple<Int32, Int32> GetPwmOnOffValues(IPCA9685Pin pin) { if (!this.HasPin(pin)) { throw new ArgumentException("The specified pin does not exist in the pin cache."); } return new Tuple<Int32, Int32>( this.GetPin(pin).PwmOnValue, this.GetPin(pin).PwmOffValue ); }
/// <summary> /// Determines whether this instance has pin the specified pin /// in the internal pin cache. /// </summary> /// <param name="pin"> /// The pin to check for. /// </param> /// <returns> /// <c>true</c> if this instance has pin the specified pin; otherwise, <c>false</c>. /// </returns> public Boolean HasPin(IPCA9685Pin pin) { return this._pinCache.Contains(pin); }
/// <summary> /// Gets the specified pin from the pin cache. If the specified pin /// does not already exist in the cache, it will be cached first, /// then returned to the caller. /// </summary> /// <param name="pin"> /// The pin to get from the cache. /// </param> /// <returns> /// The cached instance of the specified pin. /// </returns> public IPCA9685Pin GetPin(IPCA9685Pin pin) { if (!this._pinCache.Contains(pin)) { this._pinCache.Add(pin); } return this._pinCache[this._pinCache.IndexOf(pin)]; }