Exemplo n.º 1
0
 /// <summary>
 /// Copies values from another instance.
 /// </summary>
 /// <param name="source">Source from which to copy values.</param>
 public void Copy(PpmCycle source)
 {
     LowTime    = source.LowTime;
     LowLength  = source.LowLength;
     HighTime   = source.HighTime;
     HighLength = source.HighLength;
 }
Exemplo n.º 2
0
        /// <summary>
        /// Runs the decoder thread.
        /// </summary>
        /// <param name="inputBuffer">Buffer from which new PPM values are read.</param>
        /// <param name="inputTrigger">Trigger which is fired by the caller when new data arrives.</param>
        /// <param name="outputBuffer">Buffer into which decoded PPM frames are written.</param>
        /// <param name="outputTrigger">Trigger which is fired by this decoder when new data has been decoded.</param>
        /// <param name="stop">Signals when the decoder should stop.</param>
        public void DecodePulse(ConcurrentQueue <PpmPulse> inputBuffer, AutoResetEvent inputTrigger,
                                ConcurrentQueue <PpmFrame> outputBuffer, AutoResetEvent outputTrigger, CancellationToken stop)
        {
            // Validate
            if (inputBuffer == null)
            {
                throw new ArgumentNullException(nameof(inputBuffer));
            }
            if (inputTrigger == null)
            {
                throw new ArgumentNullException(nameof(inputTrigger));
            }
            if (outputBuffer == null)
            {
                throw new ArgumentNullException(nameof(outputBuffer));
            }
            if (outputTrigger == null)
            {
                throw new ArgumentNullException(nameof(outputTrigger));
            }

            // Decode until stopped...
            while (!stop.IsCancellationRequested)
            {
                // Wait for value in queue...
                if (!inputBuffer.TryDequeue(out PpmPulse value))
                {
                    inputTrigger.WaitOne(SyncLengthMinimum * 2);
                    continue;
                }

                // Decode values into cycles...
                var time = value.Time;
                if (value.Level)
                {
                    // Low -> high (mid-cycle)
                    _cycle.HighTime  = time;
                    _cycle.LowLength = time - _cycle.LowTime;
                }
                else
                {
                    // High -> low (end of cycle)
                    _cycle.HighLength = time - _cycle.HighTime;

                    // Prepare next value
                    var cycle = _cycle;
                    _cycle = new PpmCycle(time);

                    // Decode cycles into frames...
                    var frame = DecodeCycle(cycle);
                    if (frame != null)
                    {
                        // Output frame when decoding complete
                        outputBuffer.Enqueue(frame);
                        outputTrigger.Set();
                    }
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Decodes the incoming PPM signal (each complete cycle) using the CPPM protocol.
        /// </summary>
        /// <param name="cycle">PPM cycle to decode.</param>
        /// <returns>
        /// <see cref="PpmFrame"/> when complete else null whilst decoding or skipping invalid cycles.
        /// </returns>
        private PpmFrame DecodeCycle(PpmCycle cycle)
        {
            // Validate
            if (!cycle.IsValid() || cycle.LowLength >= LowLimit)
            {
                // Discard frame
                _channel = null;
                return(null);
            }

            // Detect start frame
            if (cycle.HighLength >= SyncLengthMinimum)
            {
                // Start decoding from channel 0 at next pulse
                _channel = 0;
                _frame   = new PpmFrame(cycle.LowTime, new int[ChannelCount]);
                return(null);
            }

            // Do nothing when not decoding
            if (!_channel.HasValue)
            {
                return(null);
            }
            var decodeIndex = _channel.Value;

            // Store channel value whilst decoding
            if (decodeIndex < ChannelCount)
            {
                // Store channel value
                _frame.Channels[decodeIndex] = (int)cycle.Length;

                // Wait for next channel...
                _channel = decodeIndex + 1;

                // Complete frame when all channels decoded...
                if (decodeIndex == ChannelCount - 1)
                {
                    var frame = _frame;
                    _frame = null;
                    return(frame);
                }
            }

            // Continue...
            return(null);
        }
Exemplo n.º 4
0
 /// <summary>
 /// Creates an instance.
 /// </summary>
 public CppmDecoder()
 {
     _frame = new PpmFrame();
     _cycle = new PpmCycle();
 }