Пример #1
0
        /// <summary>
        /// Displays nodes in their current configuration for the specified duration.
        /// </summary>
        /// <param name="duration">Time to display segment.</param>
        public void DisplaySegment(TimeSpan duration)
        {
            /*
             *  Cases to consider
             *  node.Cathode == _lastNode.Cathode
             *  node.Cathode == _lastNode.Anode -- drop low
             *  node.Anode == _lastNode.Cathode
             *  node.Anode == _lastNode.Anode
             *  node.Anode != _lastNode.Cathode | _lastNode.Anode
             *  node.Cathode != _lastNode.Cathode | _lastNode.Anode
             */

            Stopwatch watch = Stopwatch.StartNew();

            do
            {
                for (int i = 0; i < _nodes.Length; i++)
                {
                    CharlieplexSegmentNode node = _nodes[i];

                    // skip updating pinmode when possible
                    if (_lastNode.Anode != node.Anode && _lastNode.Anode != node.Cathode)
                    {
                        _gpioController.SetPinMode(_lastNode.Anode, PinMode.Input);
                    }

                    if (_lastNode.Cathode != node.Anode && _lastNode.Cathode != node.Cathode)
                    {
                        _gpioController.SetPinMode(_lastNode.Cathode, PinMode.Input);
                    }

                    if (node.Cathode != _lastNode.Anode && node.Cathode != _lastNode.Cathode)
                    {
                        _gpioController.SetPinMode(node.Cathode, PinMode.Output);
                    }

                    if (node.Anode != _lastNode.Anode && node.Anode != _lastNode.Cathode)
                    {
                        _gpioController.SetPinMode(node.Anode, PinMode.Output);
                    }

                    _gpioController.Write(node.Anode, node.Value);
                    // It is necessary to sleep for the LED to be seen with full brightness
                    // It may be possible to sleep less than 1ms -- this API has ms granularity
                    Thread.Sleep(1);
                    _gpioController.Write(node.Anode, 0);
                    _lastNode.Anode   = node.Anode;
                    _lastNode.Cathode = node.Cathode;
                }
            }while (watch.Elapsed < duration);
        }
Пример #2
0
        /// <summary>
        /// Displays nodes in their current configuration for the specified duration.
        /// </summary>
        /// <param name="token">CancellationToken used to signal when method should exit.</param>
        public void Display(CancellationToken token)
        {
            /*
             *  Cases to consider
             *  node.Cathode == _lastNode.Cathode
             *  node.Cathode == _lastNode.Anode -- drop low
             *  node.Anode == _lastNode.Cathode
             *  node.Anode == _lastNode.Anode
             *  node.Anode != _lastNode.Cathode | _lastNode.Anode
             *  node.Cathode != _lastNode.Cathode | _lastNode.Anode
             */

            while (!token.IsCancellationRequested)
            {
                for (int i = 0; i < _nodes.Length; i++)
                {
                    CharlieplexSegmentNode node = _nodes[i];

                    // skip updating pinmode when possible
                    if (_lastNode.Anode != node.Anode && _lastNode.Anode != node.Cathode)
                    {
                        _gpioController.SetPinMode(_lastNode.Anode, PinMode.Input);
                    }

                    if (_lastNode.Cathode != node.Anode && _lastNode.Cathode != node.Cathode)
                    {
                        _gpioController.SetPinMode(_lastNode.Cathode, PinMode.Input);
                    }

                    if (node.Cathode != _lastNode.Anode && node.Cathode != _lastNode.Cathode)
                    {
                        _gpioController.SetPinMode(node.Cathode, PinMode.Output);
                    }

                    if (node.Anode != _lastNode.Anode && node.Anode != _lastNode.Cathode)
                    {
                        _gpioController.SetPinMode(node.Anode, PinMode.Output);
                    }

                    _gpioController.Write(node.Anode, node.Value);
                    // It is necessary to sleep for the LED to be seen with full brightness
                    Thread.SpinWait(1);
                    _gpioController.Write(node.Anode, 0);
                    _lastNode.Anode   = node.Anode;
                    _lastNode.Cathode = node.Cathode;
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Initializes a new Charlieplex type that can be use for multiplex over a relatively small number of GPIO pins.
        /// </summary>
        /// <param name="pins">The set of pins to use.</param>
        /// <param name="nodeCount">The count of nodes (like LEDs) that will be addressable. If 0, then the Charlieplex maximum is used for the pins provided (n^2-n).</param>
        /// <param name="gpioController">The GPIO Controller used for interrupt handling.</param>
        /// <param name="shouldDispose">True (the default) if the GPIO controller shall be disposed when disposing this instance.</param>
        public CharlieplexSegment(int[] pins, int nodeCount = 0, GpioController?gpioController = null, bool shouldDispose = true)
        {
            if (pins.Length < 2)
            {
                throw new ArgumentException($"{nameof(CharlieplexSegment)}: 2 or more pins must be provided.");
            }

            int charlieCount = (int)Math.Pow(pins.Length, 2) - pins.Length;

            if (nodeCount > charlieCount)
            {
                throw new ArgumentException($"{nameof(CharlieplexSegment)}: maximum count is {charlieCount} based on {pins.Length} pins. {nodeCount} was specified as the count.");
            }

            if (nodeCount == 0)
            {
                nodeCount = charlieCount;
            }

            if (gpioController is null)
            {
                gpioController = new GpioController();
            }

            // first two pins will be needed as Output.
            gpioController.OpenPin(pins[0], PinMode.Output);
            gpioController.OpenPin(pins[1], PinMode.Output);

            // remaining pins should be input type
            // prevents participating in the circuit until needed
            for (int i = 2; i < pins.Length; i++)
            {
                gpioController.OpenPin(pins[i], PinMode.Input);
            }

            _lastNode = new CharlieplexSegmentNode()
            {
                Anode   = pins[1],
                Cathode = pins[0]
            };
            _controller    = gpioController;
            _shouldDispose = shouldDispose;
            _pins          = pins;
            _nodeCount     = nodeCount;
            _nodes         = GetNodes(pins, nodeCount);
        }
Пример #4
0
        /// <summary>
        /// Provides the set of Charlie nodes given the set of pins and the count provided.
        /// If count = 0, then the Charlieplex maximum is used for the pins provided (n^2-n).
        /// </summary>
        /// <param name="pins">The pins to use for the segment.</param>
        /// <param name="nodeCount">The number of nodes to use. Default is the Charlieplex maximum.</param>
        public static CharlieplexSegmentNode[] GetNodes(int[] pins, int nodeCount = 0)
        {
            int pinCount = pins.Length;

            if (nodeCount == 0)
            {
                nodeCount = (int)Math.Pow(pinCount, 2) - pinCount;
            }

            CharlieplexSegmentNode[] nodes = new CharlieplexSegmentNode[nodeCount];

            int  pin        = 0;
            int  pinJump    = 1;
            int  resetCount = pinCount - 1;
            bool firstLeg   = false;

            for (int i = 0; i < nodeCount; i++)
            {
                if ((pin > 0 && pin % resetCount == 0) || pin + pinJump > resetCount)
                {
                    pin = 0;
                    pinJump++;
                }

                CharlieplexSegmentNode node = new CharlieplexSegmentNode();

                if (!firstLeg)
                {
                    node.Anode   = pins[pin];
                    node.Cathode = pins[pin + pinJump];
                    firstLeg     = true;
                }
                else
                {
                    node.Anode   = pins[pin + pinJump];
                    node.Cathode = pins[pin];
                    firstLeg     = false;
                    pin++;
                }

                nodes[i] = node;
            }

            return(nodes);
        }