DHT11 Sensor and C#

userHead idreams 2016-09-19 16:12:33 3371 Views2 Replies
Hi
How do I use the DHT11 sensors in C#?
I wrote the following code:

Code: Select all

//An exact copy of the adafruit DTH-11 driver in C# using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; using LattePanda.Firmata; /// <summary> /// The Temperature namespace. /// Converted from Original code on GitHub: /// https://raw.githubusercontent.com/adafruit/DHT-sensor-library/master/DHT.cpp /// </summary> namespace Sensors.Temperature// { /// <summary> /// Class DHT11. /// </summary> public class DHT11 { static Arduino arduino = new Arduino(); /// <summary> /// The _data /// </summary> private UInt32[] _data; /// <summary> /// The _data pin /// </summary> private ushort _dataPin; /// <summary> /// The _first reading /// </summary> private bool _firstReading; /// <summary> /// The _last result /// </summary> private bool _lastResult; /// <summary> /// The _seconds since last read /// </summary> private double _secondsSinceLastRead; /// <summary> /// The _sensor type /// </summary> private string _sensorType; /// <summary> /// Initializes a new instance of the <see cref="DHT11"/> class. /// </summary> public DHT11() { } /// <summary> /// Initializes a new instance of the <see cref="DHT11"/> class. /// </summary> /// <param name="datatPin">The datat pin.</param> /// <param name="sensor">The sensor.</param> /// <exception cref="System.ArgumentException">Parameter cannot bet null.;dataPin</exception> public DHT11(ushort datatPin, string sensor) { if (datatPin !=0) { _dataPin = datatPin; _secondsSinceLastRead = 0D; _firstReading = true; _data = new UInt32[6]; _sensorType = sensor; //Init the data pin arduino.pinMode(_dataPin, Arduino.INPUT); arduino.digitalWrite(_dataPin, Arduino.HIGH); //_dataPin.SetDriveMode(GpioPinDriveMode.Input);// //_dataPin.Write(GpioPinValue.High);// _firstReading = true; _secondsSinceLastRead = 0; } else { throw new ArgumentException("Parameter cannot bet null.", "dataPin"); } } /// <summary> /// Reads the temperature. /// </summary> /// <param name="S">if set to <c>true</c> [s].</param> /// <returns>Task<System.Single>.</returns> public async Task<float> ReadTemperature(bool S) { return await Task.Run<float>(async () => { float f = 0; if (await Read()) { switch (_sensorType) { case "DHT11": f = _data[2]; if (S) { f = ConvertCtoF(f); } break; case "DHT22": case "DHT21": f = _data[2] & 0x7F; f *= 256; f += _data[3]; f /= 10; if ((_data[2] & 0x80) != 0) { f *= -1; } if (S) { f = ConvertCtoF(f); } break; } } return f; }); } /// <summary> /// Reads the humidity. /// </summary> /// <returns>Task<System.Single>.</returns> public async Task<float> ReadHumidity() { return await Task.Run(async () => { float f = 0; if (await Read()) { switch (_sensorType) { case "DHT11": f = _data[0]; break; case "DHT22": case "DHT21": f = _data[0]; f *= 256; f += _data[1]; f /= 10; break; } } return f; }); } /// <summary> /// Converts the cto f. /// </summary> /// <param name="c">The c.</param> /// <returns>System.Single.</returns> float ConvertCtoF(float c) { return c * 9 / 5 + 32; } /// <summary> /// Converts the fto c. /// </summary> /// <param name="f">The f.</param> /// <returns>System.Single.</returns> float ConvertFtoC(float f) { return (f - 32) * 5 / 9; } /// <summary> /// Computes the index of the heat. /// </summary> /// <param name="temperature">The temperature.</param> /// <param name="percentHumidity">The percent humidity.</param> /// <param name="isFahrenheit">if set to <c>true</c> [is fahrenheit].</param> /// <returns>Task<System.Double>.</returns> private async Task<double> ComputeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit) { return await Task.Run<double>(() => { // Adapted from equation at: https://github.com/adafruit/DHT-sensor-library/issues/9 and // Wikipedia: http://en.wikipedia.org/wiki/Heat_index if (!isFahrenheit) { // Celsius heat index calculation. return -8.784695 + 1.61139411 * temperature + 2.338549 * percentHumidity + -0.14611605 * temperature * percentHumidity + -0.01230809 * Math.Pow(temperature, 2) + -0.01642482 * Math.Pow(percentHumidity, 2) + 0.00221173 * Math.Pow(temperature, 2) * percentHumidity + 0.00072546 * temperature * Math.Pow(percentHumidity, 2) + -0.00000358 * Math.Pow(temperature, 2) * Math.Pow(percentHumidity, 2); } else { // Fahrenheit heat index calculation. return -42.379 + 2.04901523 * temperature + 10.14333127 * percentHumidity + -0.22475541 * temperature * percentHumidity + -0.00683783 * Math.Pow(temperature, 2) + -0.05481717 * Math.Pow(percentHumidity, 2) + 0.00122874 * Math.Pow(temperature, 2) * percentHumidity + 0.00085282 * temperature * Math.Pow(percentHumidity, 2) + -0.00000199 * Math.Pow(temperature, 2) * Math.Pow(percentHumidity, 2); } }); } /// <summary> /// Reads the sensor data. /// </summary> /// <returns>Task<System.Boolean>.</returns> private async Task<bool> Read() { var currentTimeSeconds = GetMSSinceEpoch(); if (currentTimeSeconds < _secondsSinceLastRead) { _secondsSinceLastRead = 0; } if (!_firstReading && ((currentTimeSeconds - _secondsSinceLastRead) < 2000)) { return _lastResult; } _firstReading = false; _secondsSinceLastRead = GetMSSinceEpoch(); _data[0] = _data[1] = _data[2] = _data[3] = _data[4] = 0; arduino.digitalWrite(_dataPin, Arduino.HIGH); //_dataPin.Write(GpioPinValue.High); // await Task.Delay(250); arduino.pinMode(_dataPin, Arduino.OUTPUT); arduino.digitalWrite(_dataPin, Arduino.LOW); //_dataPin.SetDriveMode(GpioPinDriveMode.Output);//pinMode(_pin, OUTPUT); //_dataPin.Write(GpioPinValue.Low);//digitalWrite(_pin, LOW); await Task.Delay(20); //TIME CRITICAL ############### arduino.digitalWrite(_dataPin, Arduino.HIGH); //_dataPin.Write(GpioPinValue.High);// //=> DELAY OF 40 microseconds needed here arduino.pinMode(_dataPin, Arduino.INPUT); //_dataPin.SetDriveMode(GpioPinDriveMode.Input);// //Delay of 10 microseconds needed here //bool LOW = false; if (await ExpectPulse(false) == 0)// { _lastResult = false; return _lastResult; } //bool HIGH = true; if (await ExpectPulse(true) == 0)// { _lastResult = false; return _lastResult; } // Now read the 40 bits sent by the sensor. Each bit is sent as a 50 // microsecond low pulse followed by a variable length high pulse. If the // high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds // then it's a 1. We measure the cycle count of the initial 50us low pulse // and use that to compare to the cycle count of the high pulse to determine // if the bit is a 0 (high state cycle count < low state cycle count), or a // 1 (high state cycle count > low state cycle count). for (int i = 0; i < 40; ++i) { UInt32 lowCycles = await ExpectPulse(false);// if (lowCycles == 0) { _lastResult = false; return _lastResult; } //bool HIGH2 = true; UInt32 highCycles = await ExpectPulse(true);// if (highCycles == 0) { _lastResult = false; return _lastResult; } _data[i / 8] <<= 1; // Now compare the low and high cycle times to see if the bit is a 0 or 1. if (highCycles > lowCycles) { // High cycles are greater than 50us low cycle count, must be a 1. _data[i / 8] |= 1; } // Else high cycles are less than (or equal to, a weird case) the 50us low // cycle count so this must be a zero. Nothing needs to be changed in the // stored data. } //TIME CRITICAL_END ############# // Check we read 40 bits and that the checksum matches. if (_data[4] == ((_data[0] + _data[1] + _data[2] + _data[3]) & 0xFF)) { _lastResult = true; return _lastResult; } else { //Checksum failure! _lastResult = false; return _lastResult; } } /// <summary> /// Expects the pulse. /// </summary> /// <param name="level">The level.</param> /// <returns>Task<UInt32>.</returns> //private async Task<UInt32> ExpectPulse(GpioPinValue level) private async Task<UInt32> ExpectPulse(bool level) { return await Task.Run<UInt32>(() => { UInt32 count = 0; ushort lev; if (level) { lev = 1; }else{ lev = 0; } //long end = DateTime.Now.AddMicroseconds(1000).Ticks; long end = DateTime.Now.Ticks; //while (_dataPin.Read() == level)// while (arduino.digitalRead(_dataPin) == lev) { count++; if (DateTime.Now.Ticks >= end) { return 0; } } return count; }); } /// <summary> /// Gets the ms since epoch. /// </summary> /// <returns>System.Double.</returns> private double GetMSSinceEpoch() { return (DateTime.Now - DateTime.MinValue).TotalMilliseconds; } } } But was not successful.