/// <summary> /// Writes the "on" and "off" values of a channel together, and updates it in <see cref="Channels"/>. /// </summary> /// <param name="index">Zero based channel number (0-15) or 16 for the "all call" channel.</param> /// <param name="value"><see cref="NxpPca9685ChannelValue"/> to write.</param> /// <returns> /// Updated channel value or null when all channels were updated. /// </returns> public NxpPca9685Channel WriteChannel(int index, NxpPca9685ChannelValue value) { // Validate if (index <0 | index> ChannelCount) { throw new ArgumentOutOfRangeException(nameof(index)); } // Validate if (value.On > NxpPca9685ChannelValue.Maximum + 1 || value.Off > NxpPca9685ChannelValue.Maximum + 1) { throw new ArgumentOutOfRangeException(nameof(value)); } // Calculate register address var register = GetChannelAddress(index); // Convert and write value var bytes = value.ToByteArray(); Hardware.WriteJoinBytes(register, bytes); // Read and return result if (index < ChannelCount) { return(ReadChannel(index)); } ReadAllChannels(); return(null); }
/// <summary> /// Calculates the "on" and "off" values of a channel from milliseconds (and optional delay), /// then writes them together, and updates it in <see cref="Channels"/>. /// </summary> /// <param name="index">Zero based channel number (0-15) or 16 for the "all call" channel.</param> /// <param name="length"> /// Pulse length in milliseconds. Cannot be greater than one clock interval (1000 / frequency). /// </param> /// <param name="delay">Optional delay in milliseconds. Cannot be greater than one clock interval (1000 / frequency).</param> /// <returns> /// Updated channel value or null when all channels were updated. /// </returns> public NxpPca9685Channel WriteChannelMilliseconds(int index, float length, float delay = 0) { // Read current frequency var frequency = ReadFrequency(); // Call overloaded method return(WriteChannel(index, NxpPca9685ChannelValue.FromMilliseconds(length, frequency, delay))); }
/// <summary> /// Reads the pre-scale register and calculates the <see cref="Frequency"/> (and related properties) /// based on <see cref="ClockSpeed"/>. /// </summary> /// <returns> /// Frequency in Hz. Related properties are also udpated. /// </returns> public float ReadFrequency() { // Read pre-scale register var preScale = Hardware.WriteReadByte((byte)NxpPca9685Register.PreScale); // Calculate frequency var frequency = CalculateFrequency(preScale, ClockSpeed); // Update related properties Frequency = frequency; PwmMsMinimum = NxpPca9685ChannelValue.CalculateMilliseconds(Frequency, 0); PwmMsMaximum = NxpPca9685ChannelValue.CalculateMilliseconds(Frequency, NxpPca9685ChannelValue.Maximum); // Return result return(frequency); }
/// <summary> /// Sets RGB values of the high intensity LED together (in one operation). /// </summary> /// <remarks> /// Automatically inverts the value, providing a natural behaviour where a higher number /// produces a higher LED intensity. Normally, when written as raw PWM values, the output /// is inverted due to common anode. /// </remarks> /// <param name="red">Red value in the range 0-<see cref="NxpPca9685ChannelValue.Maximum"/>.</param> /// <param name="green">Green value in the range 0-<see cref="NxpPca9685ChannelValue.Maximum"/>.</param> /// <param name="blue">Blue value in the range 0-<see cref="NxpPca9685ChannelValue.Maximum"/>.</param> public void SetLed(int red, int green, int blue) { // Validate if (red < 0 || red > NxpPca9685ChannelValue.Maximum) { throw new ArgumentOutOfRangeException(nameof(red)); } if (green < 0 || green > NxpPca9685ChannelValue.Maximum) { throw new ArgumentOutOfRangeException(nameof(green)); } if (blue < 0 || blue > NxpPca9685ChannelValue.Maximum) { throw new ArgumentOutOfRangeException(nameof(blue)); } // Invert values var inverseRed = ~red & 0x0fff; var inverseGreen = ~green & 0x0fff; var inverseBlue = ~blue & 0x0fff; // Build block of data which sets all three register high and low values var redBytes = NxpPca9685ChannelValue.FromLength(inverseRed).ToByteArray(); var greenBytes = NxpPca9685ChannelValue.FromLength(inverseGreen).ToByteArray(); var blueBytes = NxpPca9685ChannelValue.FromLength(inverseBlue).ToByteArray(); var data = new byte[1 + ChannelSize * 3]; data[0] = ChannelStartAddress; Array.ConstrainedCopy(blueBytes, 0, data, 1, ChannelSize); Array.ConstrainedCopy(greenBytes, 0, data, 1 + ChannelSize, ChannelSize); Array.ConstrainedCopy(redBytes, 0, data, 1 + ChannelSize * 2, ChannelSize); // Set new value Hardware.Write(data); // Update properties ReadLed(); }
/// <summary> /// Writes the "on" and "off" values of a channel together, and updates it in <see cref="Channels"/>. /// </summary> /// <param name="index">Zero based channel number (0-15) or 16 for the "all call" channel.</param> /// <param name="value"><see cref="NxpPca9685ChannelValue"/> to write.</param> /// <returns> /// Updated channel value or null when all channels were updated. /// </returns> public NxpPca9685Channel WriteChannel(int index, NxpPca9685ChannelValue value) { // Validate if (index < 0 | index > ChannelCount) throw new ArgumentOutOfRangeException(nameof(index)); // Validate if (value.On > NxpPca9685ChannelValue.Maximum + 1 || value.Off > NxpPca9685ChannelValue.Maximum + 1) throw new ArgumentOutOfRangeException(nameof(value)); // Calculate register address var register = GetChannelAddress(index); // Convert and write value var bytes = value.ToByteArray(); Hardware.WriteJoinBytes(register, bytes); // Read and return result if (index < ChannelCount) return ReadChannel(index); ReadAllChannels(); return null; }
/// <summary> /// Calculates the "on" and "off" values of a channel from length (and optional delay), /// then writes them together, and updates it in <see cref="Channels"/>. /// </summary> /// <param name="index">Zero based channel number (0-15) or 16 for the "all call" channel.</param> /// <param name="length">Pulse length in clock ticks.</param> /// <param name="delay">Optional delay in clock ticks.</param> /// <returns> /// Updated channel value or null when all channels were updated. /// </returns> public NxpPca9685Channel WriteChannelLength(int index, int length, int delay = 0) { // Call overloaded method return(WriteChannel(index, NxpPca9685ChannelValue.FromLength(length, delay))); }
/// <summary> /// Creates an instance with the specified values. /// </summary> public NxpPca9685Channel(int index, NxpPca9685ChannelValue value) { Index = index; Value = value; Value.Changed += OnValueChanged; }