Example #1
0
        /// <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);
        }