Exemple #1
0
        /// <summary>
        /// Called when a single infrared sensor pulse becomes available.
        /// </summary>
        /// <param name="pulse">The pulse.</param>
        private void OnInfraredSensorPulseAvailable(InfraredPulse pulse)
        {
            if (_isDisposed || PulseAvailable == null)
            {
                return;
            }

            var args = new InfraredSensorPulseEventArgs(pulse);

            ThreadPool.QueueUserWorkItem(a =>
            {
                PulseAvailable?.Invoke(this, a as InfraredSensorPulseEventArgs);
            },
                                         args);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="InfraredSensorPulseEventArgs" /> class.
 /// </summary>
 /// <param name="pulse">The pulse.</param>
 internal InfraredSensorPulseEventArgs(InfraredPulse pulse)
 {
     Value         = pulse.Value;
     DurationUsecs = pulse.DurationUsecs;
 }
Exemple #3
0
        /// <summary>
        /// Reads the interrupt do work.
        /// </summary>
        private void ReadInterruptDoWork()
        {
            // Define some constants
            const long gapUsecs = 5000;
            const long maxElapsedMicroseconds     = 250000;
            const long minElapsedMicroseconds     = 50;
            const int  idleCheckIntervalMilliSecs = 32;
            const int  maxPulseCount = 128;

            // Setup the input pin
            InputPin.PinMode       = GpioPinDriveMode.Input;
            InputPin.InputPullMode = GpioPinResistorPullMode.PullUp;

            // Get the timers started!
            var pulseTimer = new HighResolutionTimer();
            var idleTimer  = new HighResolutionTimer();

            var pulseBuffer = new List <InfraredPulse>(maxPulseCount);
            var syncLock    = new object();

            _idleChecker = new Timer(s =>
            {
                if (_isDisposed || _isInReadInterrupt)
                {
                    return;
                }

                lock (syncLock)
                {
                    if (idleTimer.ElapsedMicroseconds < gapUsecs || idleTimer.IsRunning == false || pulseBuffer.Count <= 0)
                    {
                        return;
                    }

                    OnInfraredSensorRawDataAvailable(pulseBuffer.ToArray(), ReceiverFlushReason.Idle);
                    pulseBuffer.Clear();
                    idleTimer.Reset();
                }
            });

            InputPin.RegisterInterruptCallback(EdgeDetection.FallingAndRisingEdge, () =>
            {
                if (_isDisposed)
                {
                    return;
                }

                _isInReadInterrupt = true;

                lock (syncLock)
                {
                    idleTimer.Restart();
                    _idleChecker.Change(idleCheckIntervalMilliSecs, idleCheckIntervalMilliSecs);

                    var currentLength = pulseTimer.ElapsedMicroseconds;
                    var pulse         = new InfraredPulse(
                        IsActiveLow ? !_currentValue : _currentValue,
                        currentLength.Clamp(minElapsedMicroseconds, maxElapsedMicroseconds));

                    // Restart for the next bit coming in
                    pulseTimer.Restart();

                    // For the next value
                    _currentValue = InputPin.Read();

                    // Do not add an idling pulse
                    if (pulse.DurationUsecs < maxElapsedMicroseconds)
                    {
                        pulseBuffer.Add(pulse);
                        OnInfraredSensorPulseAvailable(pulse);
                    }

                    if (pulseBuffer.Count >= maxPulseCount)
                    {
                        OnInfraredSensorRawDataAvailable(pulseBuffer.ToArray(), ReceiverFlushReason.Overflow);
                        pulseBuffer.Clear();
                    }
                }

                _isInReadInterrupt = false;
            });

            // Get the timers started
            pulseTimer.Start();
            idleTimer.Start();
            _idleChecker.Change(0, idleCheckIntervalMilliSecs);
        }