/// <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); }
/// <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(); } }
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()); } }
/// <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)); }
public void ResetTimer() { HighResolutionTimer.Reset(); }
/// <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); }
/// <summary> /// Stops measurement and resets the timer to zero. /// </summary> public void Stop() => _timer.Reset();
/// <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()); } }
/// <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 }); } }
/// <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()); } }
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 }); }