Example #1
0
 /// <summary>
 /// Called when a single infrared sensor pulse becomes available.
 /// </summary>
 /// <param name="pulse">The pulse.</param>
 private void OnInfraredSensorPulseAvailable(InfraRedPulse pulse)
 {
     PulseAvailable?.Invoke(this, new InfraRedSensorPulseEventArgs(pulse));
 }
Example #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="InfraRedSensorPulseEventArgs" /> class.
 /// </summary>
 /// <param name="pulse">The pulse.</param>
 internal InfraRedSensorPulseEventArgs(InfraRedPulse pulse)
     : base()
 {
     Value         = pulse.Value;
     DurationUsecs = pulse.DurationUsecs;
 }
Example #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 Native.HighResolutionTimer();
            var idleTimer  = new Native.HighResolutionTimer();

            var pulseBuffer = new List <InfraRedPulse>(MaxPulseCount);
            var syncLock    = new object();

            var idleChecker = default(Timer);

            idleChecker = new Timer((s) =>
            {
                if (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.RisingAndFallingEdges, () =>
            {
                IsInReadInterrupt = true;

                lock (syncLock)
                {
                    idleTimer.Restart();
                    idleChecker.Change(IdleCheckIntervalMilliSecs, IdleCheckIntervalMilliSecs);

                    var currentLength = pulseTimer.ElapsedMicroseconds;
                    var currentValue  = InputPin.Read();
                    var pulse         = new InfraRedPulse(currentValue, currentLength.Clamp(MinElapsedMicroseconds, MaxElapsedMicroseconds));

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

                    // 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);
        }