/// <summary> /// Writes multiple channels together (both "on" and "off" values), 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="values">Collection of <see cref="Pca9685ChannelValue"/>s to write.</param> public void WriteChannels(int index, IList <Pca9685ChannelValue> values) { // Validate if (index <0 | index> ChannelCount) { throw new ArgumentOutOfRangeException(nameof(index)); } if (values == null || values.Count == 0) { throw new ArgumentNullException(nameof(values)); } var count = values.Count; if (index + count > ChannelCount) { throw new ArgumentOutOfRangeException(nameof(values)); } // Build I2C packet var data = new byte[1 + ChannelSize * count]; // Calculate first register address var register = GetChannelAddress(index); data[0] = register; // Write channels and update properties for (int dataIndex = 0, dataOffset = 1; dataIndex < count; dataIndex++, dataOffset += ChannelSize) { // Get channel data var channelData = values[dataIndex].ToByteArray(); // Copy to buffer Array.ConstrainedCopy(channelData, 0, data, dataOffset, ChannelSize); // Update property _channels[index + dataIndex] = Pca9685ChannelValue.FromByteArray(channelData); } // Send packet I2cExtensions.WriteBytes(_hardware, data); }