Example #1
0
        /// <summary>
        /// Runs this instance.
        /// </summary>
        private void Run()
        {
            var timer           = new HighResolutionTimer();
            var lastElapsedTime = TimeSpan.FromSeconds(0);

            while (IsRunning)
            {
                if (lastElapsedTime < ReadTime)
                {
                    Thread.Sleep(ReadTime - lastElapsedTime);
                }

                timer.Start();

                var sensorData = RetrieveSensorData();
                lastElapsedTime = timer.Elapsed;

                if (IsRunning)
                {
                    DataAvailable?.Invoke(this, sensorData);
                }

                timer.Reset();
            }

            SetSleepMode(true);
        }
Example #2
0
        /// <summary>
        /// Performs the continuous reads of the sensor.
        /// This method represents the body of the worker.
        /// </summary>
        private void PerformContinuousReads()
        {
            var stopwatch       = new HighResolutionTimer();
            var lastElapsedTime = TimeSpan.FromSeconds(0);

            while (IsRunning)
            {
                try
                {
                    // Start to comunicate with sensor
                    // Inform sensor that must finish last execution and put it's state in idle
                    DataPin.PinMode = GpioPinDriveMode.Output;

                    // Waiting for sensor init
                    DataPin.Write(GpioPinValue.High);
                    if (lastElapsedTime < ReadInterval)
                    {
                        Thread.Sleep(ReadInterval - lastElapsedTime);
                    }

                    // Start to counter measure time
                    stopwatch.Start();

                    // Send request to trasmission from board to sensor
                    DataPin.Write(GpioPinValue.Low);
                    Pi.Timing.SleepMicroseconds(1000);
                    DataPin.Write(GpioPinValue.High);
                    Pi.Timing.SleepMicroseconds(20);
                    DataPin.Write(GpioPinValue.Low);

                    // Acquire measure
                    var sensorData = RetrieveSensorData();
                    OnDataAvailable?.Invoke(this, sensorData);
                }
                catch
                {
                    // swallow
                }

                lastElapsedTime = stopwatch.Elapsed;
                if (stopwatch.IsRunning)
                {
                    stopwatch.Stop();
                }

                stopwatch.Reset();
            }
        }
Example #3
0
        private void GetMeasure()
        {
            var hrt             = new HighResolutionTimer();
            var lastElapsedTime = TimeSpan.FromSeconds(0);

            while (_started)
            {
                try
                {
                    THData measure = null;
                    //Start to comunicate with sensor
                    //Inform sensor that must finish last execution and put it's state in idle
                    _pin.PinMode = GpioPinDriveMode.Output;

                    //Waiting for sensor init
                    _pin.Write(GpioPinValue.High);
                    if (lastElapsedTime < _measureTime)
                    {
                        Thread.Sleep(_measureTime - lastElapsedTime);
                    }

                    //Start to counter measure time
                    hrt.Start();
                    //Send request to trasmission from board to sensor
                    _pin.Write(GpioPinValue.Low);
                    _timing.SleepMicroseconds(1000);
                    _pin.Write(GpioPinValue.High);
                    _timing.SleepMicroseconds(20);
                    _pin.Write(GpioPinValue.Low);

                    //Acquire measure
                    measure = TryGetMeasure();
                    OnSensorRead(measure);
                }
                catch
                {
                    //ignored
                }
                lastElapsedTime = hrt.Elapsed;
                if (hrt.IsRunning)
                {
                    hrt.Stop();
                }
                hrt.Reset();
            }
        }
        private UltrasonicReadEventArgs RetrieveSensorData()
        {
            try
            {
                // Send trigger pulse
                TriggerPin.Write(GpioPinValue.Low);
                Pi.Timing.SleepMicroseconds(2);
                TriggerPin.Write(GpioPinValue.High);
                Pi.Timing.SleepMicroseconds(12);
                TriggerPin.Write(GpioPinValue.Low);

                if (!EchoPin.WaitForValue(GpioPinValue.High, 50))
                {
                    throw new TimeoutException();
                }

                measurementTimer.Start();
                if (!EchoPin.WaitForValue(GpioPinValue.Low, 50))
                {
                    throw new TimeoutException();
                }

                measurementTimer.Stop();
                var elapsedTime = measurementTimer.ElapsedMicroseconds;
                measurementTimer.Reset();

                var distance = elapsedTime / 58.0;
                if (elapsedTime > NoObstaclePulseMicroseconds)
                {
                    distance = NoObstacleDistance;
                }

                return(new UltrasonicReadEventArgs(distance));
            }
            catch
            {
                return(UltrasonicReadEventArgs.CreateInvalidReading());
            }
        }
Example #5
0
        /// <summary>
        /// Retrieves the sensor data.
        /// </summary>
        /// <returns>The event arguments that will be read from the sensor.</returns>
        private AM2302DataReadEventArgs RetrieveSensorData()
        {
            // Prepare buffer to store measure and checksum
            var data = new byte[5];

            for (var i = 0; i < 5; i++)
            {
                data[i] = 0;
            }

            // Wait for sensor response
            DataPin.PinMode = GpioPinDriveMode.Input;

            // Read acknowledgement from sensor
            DataPin.WaitForValue(GpioPinValue.High, 100);
            DataPin.WaitForValue(GpioPinValue.Low, 100);

            // Read 40 bits to acquire:
            //   16 bit -> Humidity
            //   16 bit -> Temperature
            //   8 bit -> Checksum
            var remainingBitCount = 7;
            var currentByteIndex  = 0;

            var stopwatch = new HighResolutionTimer();

            for (var i = 0; i < 40; i++)
            {
                stopwatch.Reset();
                DataPin.WaitForValue(GpioPinValue.High, 100);

                stopwatch.Start();
                DataPin.WaitForValue(GpioPinValue.Low, 100);

                stopwatch.Stop();

                // Check if signal is 1 or 0
                if (stopwatch.ElapsedMicroseconds > BitPulseMidMicroseconds)
                {
                    data[currentByteIndex] |= (byte)(1 << remainingBitCount);
                }

                if (remainingBitCount == 0)
                {
                    currentByteIndex++;

                    // restart the remaining count
                    // for the next incoming byte
                    remainingBitCount = 7;
                }
                else
                {
                    remainingBitCount--;
                }
            }

            // Compute the checksum
            var checkSum = data[0] + data[1] + data[2] + data[3];

            if ((checkSum & 0xff) != data[4])
            {
                return(null);
            }

            var sign = 1;

            // Check negative temperature
            if ((data[2] & 0x80) != 0)
            {
                data[2] = (byte)(data[2] & 0x7F);
                sign    = -1;
            }

            return(new AM2302DataReadEventArgs(
                       temperatureCelsius: (sign * ((data[2] << 8) + data[3])) / 10m,
                       humidityPercentage: ((data[0] << 8) + data[1]) / 10m));
        }
Example #6
0
 public void ResetTimer()
 {
     HighResolutionTimer.Reset();
 }
Example #7
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);
        }
Example #8
0
 /// <summary>
 /// Stops measurement and resets the timer to zero.
 /// </summary>
 public void Stop() => _timer.Reset();
Example #9
0
        /// <summary>
        /// Retrieves the sensor data.
        /// </summary>
        /// <returns>The event arguments that will be read from the sensor.</returns>
        private DhtReadEventArgs RetrieveSensorData()
        {
            // Prepare buffer to store measure and checksum
            var data = new byte[5];

            // Start to comunicate with sensor
            // Inform sensor that must finish last execution and put it's state in idle
            _dataPin.PinMode = GpioPinDriveMode.Output;

            // Send request to trasmission from board to sensor
            _dataPin.Write(GpioPinValue.Low);
            Pi.Timing.SleepMicroseconds(PullDownMicroseconds);
            _dataPin.Write(GpioPinValue.High);

            // Wait for sensor response
            _dataPin.PinMode = GpioPinDriveMode.Input;

            try
            {
                // Read acknowledgement from sensor
                if (!_dataPin.WaitForValue(GpioPinValue.Low, 50))
                {
                    throw new TimeoutException();
                }

                if (!_dataPin.WaitForValue(GpioPinValue.High, 50))
                {
                    throw new TimeoutException();
                }

                // Begins data transmission
                if (!_dataPin.WaitForValue(GpioPinValue.Low, 50))
                {
                    throw new TimeoutException();
                }

                // Read 40 bits to acquire:
                //   16 bit -> Humidity
                //   16 bit -> Temperature
                //   8 bit -> Checksum
                var stopwatch = new HighResolutionTimer();

                for (var i = 0; i < 40; i++)
                {
                    stopwatch.Reset();
                    if (!_dataPin.WaitForValue(GpioPinValue.High, 50))
                    {
                        throw new TimeoutException();
                    }

                    stopwatch.Start();
                    if (!_dataPin.WaitForValue(GpioPinValue.Low, 50))
                    {
                        throw new TimeoutException();
                    }

                    stopwatch.Stop();

                    data[i / 8] <<= 1;

                    // Check if signal is 1 or 0
                    if (stopwatch.ElapsedMicroseconds > BitPulseMidMicroseconds)
                    {
                        data[i / 8] |= 1;
                    }
                }

                // End transmission
                if (!_dataPin.WaitForValue(GpioPinValue.High, 50))
                {
                    throw new TimeoutException();
                }

                // Compute the checksum
                return(IsDataValid(data) ?
                       new DhtReadEventArgs(
                           humidityPercentage: DecodeHumidity(data),
                           temperatureCelsius: DecodeTemperature(data)) :
                       DhtReadEventArgs.CreateInvalidReading());
            }
            catch
            {
                return(DhtReadEventArgs.CreateInvalidReading());
            }
        }
Example #10
0
        /// <summary>
        /// Retrieves the sensor data.
        /// </summary>
        /// <returns>The event arguments that will be read from the sensor.</returns>
        public DHT11Data RetrieveSensorData()
        {
            // Prepare buffer to store measure and checksum
            var data = new byte[5];

            // Start to communicate with sensor
            // Inform sensor that must finish last execution and put it's state in idle
            _dataPin.PinMode = GpioPinDriveMode.Output;

            // Send request to transmission from board to sensor
            _dataPin.Write(GpioPinValue.Low);
            Pi.Timing.SleepMicroseconds(PullDownMicroseconds);
            _dataPin.Write(GpioPinValue.High);

            // Wait for sensor response
            _dataPin.PinMode = GpioPinDriveMode.Input;

            try
            {
                // Read acknowledgement from sensor
                _dataPin.WaitForValue(GpioPinValue.Low, 50);

                _dataPin.WaitForValue(GpioPinValue.High, 50);

                // Begins data transmission
                _dataPin.WaitForValue(GpioPinValue.Low, 50);


                // Read 40 bits to acquire:
                //   16 bit -> Humidity
                //   16 bit -> Temperature
                //   8 bit -> Checksum
                var stopwatch = new HighResolutionTimer();

                for (var i = 0; i < 40; i++)
                {
                    stopwatch.Reset();
                    _dataPin.WaitForValue(GpioPinValue.High, 50);

                    stopwatch.Start();
                    _dataPin.WaitForValue(GpioPinValue.Low, 50);

                    stopwatch.Stop();

                    data[i / 8] <<= 1;

                    // Check if signal is 1 or 0
                    if (stopwatch.ElapsedMicroseconds > BitPulseMidMicroseconds)
                    {
                        data[i / 8] |= 1;
                    }
                }

                // End transmission
                _dataPin.WaitForValue(GpioPinValue.High, 50);
                var _validData = IsDataValid(data)
                    ? new DHT11Data(_humid: ((data[0] + (data[1] * 0.1)) / 100.0), _temp: (data[2] + ((data[3] & 0x0f) * 0.1)))
                    : new DHT11Data();

                if (_validData.IsInitialized)
                {
                    _lastResult = _validData;
                }

                // Compute the checksum
                return(_lastResult);
            }
            catch
            {
                return(new DHT11Data()
                {
                    Humidity = 0.0, Temperature = 0.0
                });
            }
        }
Example #11
0
        /// <summary>
        /// 返回传感器数据.
        /// </summary>
        /// <returns>从传感器读取的事件参数.</returns>
        private DhtReadEventArgs RetrieveSensorData()
        {
            // 准备缓冲区以存储度量和校验和
            var data = new byte[5];

            // 开始与传感器通信
            // 通知传感器必须完成最后一次执行并将其状态置于空闲状态
            _dataPin.PinMode = GpioPinDriveMode.Output;

            // 发送请求以将传输从板传输到传感器
            _dataPin.Write(GpioPinValue.Low);
            Pi.Timing.SleepMicroseconds(PullDownMicroseconds);
            _dataPin.Write(GpioPinValue.High);

            // 等待传感器响应
            _dataPin.PinMode = GpioPinDriveMode.Input;

            try
            {
                // 读取传感器的确认
                if (!_dataPin.WaitForValue(GpioPinValue.Low, 50))
                {
                    throw new TimeoutException();
                }

                if (!_dataPin.WaitForValue(GpioPinValue.High, 50))
                {
                    throw new TimeoutException();
                }

                // 开始数据传输
                if (!_dataPin.WaitForValue(GpioPinValue.Low, 50))
                {
                    throw new TimeoutException();
                }

                // 读取40位以获取:
                //   16 bit -> Humidity (湿度)
                //   16 bit -> Temperature (温度)
                //   8 bit -> Checksum (校验和)
                var stopwatch = new HighResolutionTimer();

                for (var i = 0; i < 40; i++)
                {
                    stopwatch.Reset();
                    if (!_dataPin.WaitForValue(GpioPinValue.High, 50))
                    {
                        throw new TimeoutException();
                    }

                    stopwatch.Start();
                    if (!_dataPin.WaitForValue(GpioPinValue.Low, 50))
                    {
                        throw new TimeoutException();
                    }

                    stopwatch.Stop();

                    data[i / 8] <<= 1;

                    // 检查信号是1还是0
                    if (stopwatch.ElapsedMicroseconds > BitPulseMidMicroseconds)
                    {
                        data[i / 8] |= 1;
                    }
                }

                // 结束传输数据
                if (!_dataPin.WaitForValue(GpioPinValue.High, 50))
                {
                    throw new TimeoutException();
                }

                // 完成校验
                return(IsDataValid(data) ?
                       new DhtReadEventArgs(
                           humidityPercentage: DecodeHumidity(data),
                           temperatureCelsius: DecodeTemperature(data)) :
                       DhtReadEventArgs.CreateInvalidReading());
            }
            catch
            {
                return(DhtReadEventArgs.CreateInvalidReading());
            }
        }
Example #12
0
        private THData TryGetMeasure()
        {
            //Prepare buffer to store measure and checksum
            var data = new byte[5];

            for (var i = 0; i < 5; i++)
            {
                data[i] = 0;
            }

            //Wait for sensor response
            _pin.PinMode = GpioPinDriveMode.Input;
            //Read acknowledgement from sensor
            _pin.WaitForValue(GpioPinValue.High, 100);
            _pin.WaitForValue(GpioPinValue.Low, 100);

            //Read 40 bits to acquire:
            //16 bit -> Humidity
            //16 bit -> Temperature
            //8 bit -> Checksum
            var cnt = 7; //bit counter
            var idx = 0; //bit index
            var hrt = new HighResolutionTimer();

            for (var i = 0; i < 40; i++)
            {
                hrt.Reset();
                _pin.WaitForValue(GpioPinValue.High, 100);
                hrt.Start();
                _pin.WaitForValue(GpioPinValue.Low, 100);
                hrt.Stop();
                //Check if signal is 1 or 0
                if (hrt.Elapsed > _bitDataTime)
                {
                    data[idx] |= (byte)(1 << cnt);
                }
                if (cnt == 0)
                {
                    idx++;   //next bit
                    cnt = 7; //restart with next byte
                }
                else
                {
                    cnt--;
                }
            }

            var checkSum = data[0] + data[1] + data[2] + data[3];

            if ((checkSum & 0xff) != data[4])
            {
                return(null);
            }

            var sign = 1;

            //Check negative temperature
            if ((data[2] & 0x80) != 0)
            {
                data[2] = (byte)(data[2] & 0x7F);
                sign    = -1;
            }

            return(new THData
            {
                HumidityPercentage = ((data[0] << 8) + data[1]) / 10,
                TemperatureCelsius = (sign * ((data[2] << 8) + data[3])) / 10
            });
        }