/// <summary>
        /// Creates and initializes an instance.
        /// </summary>
        public NavioRCInputDevice()
        {
            // Initialize buffers
            _valueBuffer = new ConcurrentQueue<PwmValue>();
            _valueTrigger = new AutoResetEvent(false);
            _frameBuffer = new ConcurrentQueue<PwmFrame>();
            _frameTrigger = new AutoResetEvent(false);

            // Configure GPIO
            _inputPin = NavioHardwareProvider.ConnectGpio(0, GpioInputPinNumber);
            if (_inputPin == null)
            {
                // Initialization error
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,
                    Resources.Strings.GpioErrorDeviceNotFound, GpioInputPinNumber, GpioControllerIndex));
            }
            if (_inputPin.DebounceTimeout != TimeSpan.Zero)
                _inputPin.DebounceTimeout = TimeSpan.Zero;

            // Create decoder thread (CPPM only to start with, SBus desired)
            _decoder = new CppmDecoder();
            _stop = new CancellationTokenSource();
            _channels = new int[_decoder.MaximumChannels];
            Channels = new ReadOnlyCollection<int>(_channels);
            _decoderTask = Task.Factory.StartNew(() => { _decoder.DecodePulse(_valueBuffer, _valueTrigger, _frameBuffer, _frameTrigger, _stop.Token); });

            // Create receiver thread
            _receiverTask = Task.Factory.StartNew(() => { Receiver(); });

            // Hook events
            _inputPin.ValueChanged += OnInputPinValueChanged;
        }
        /// <summary>
        /// Creates and initializes an instance.
        /// </summary>
        public NavioRCInputDevice()
        {
            // Initialize buffers and events
            _valueBuffer = new ConcurrentQueue<PwmValue>();
            _valueTrigger = new AutoResetEvent(false);
            _frameBuffer = new ConcurrentQueue<PwmFrame>();
            _frameTrigger = new AutoResetEvent(false);

            // Configure GPIO
            _inputPin = GpioController.GetDefault().OpenPin(InputPinNumber);
            if (_inputPin.GetDriveMode() != GpioPinDriveMode.Input)
                _inputPin.SetDriveMode(GpioPinDriveMode.Input);
            _inputPin.DebounceTimeout = TimeSpan.Zero;
            _inputPin.ValueChanged += OnInputPinValueChanged;

            // Create decoder thread (CPPM only to start with, SBus desired)
            _decoder = new CppmDecoder();
            _stop = new CancellationTokenSource();
            _channels = new int[_decoder.MaximumChannels];
            Channels = new ReadOnlyCollection<int>(_channels);
            _decoderTask = Task.Factory.StartNew(() => { _decoder.Decode(_valueBuffer, _valueTrigger, _frameBuffer, _frameTrigger, _stop.Token); });

            // Create receiver thread
            _receiverTask = Task.Factory.StartNew(() => { Receiver(); });
        }