private DhtMeasurement CalculateResult() { byte[] bits = new byte[40]; int[] bytes = new int[5]; string bitStream = ""; DhtMeasurement measurement = new DhtMeasurement(); // we expect at least 1 raise and fall for the ack-bit and and 40 raise-fall combinations if (_receivedSignal.Count >= 2 + 2 * 40) { Edge[] signals = _receivedSignal.Take(82).ToArray(); for (int bitNr = 0; bitNr < 40; bitNr++) { // substract the raise-time from the fall-time int highInMicros = signals[2 + bitNr * 2 + 1].MicrosFromStart - signals[2 + bitNr * 2].MicrosFromStart; bits[bitNr] = (highInMicros < OneBitHighTimeThresholdInMicros) ? (byte)0 : (byte)1; bitStream += bits[bitNr].ToString() + "|"; int byteNr = bitNr / 8; bytes[byteNr] = (bytes[byteNr] << 1) + bits[bitNr]; } int checkSum = (bytes[0] + bytes[1] + bytes[2] + bytes[3]) & 0xff; if (checkSum != bytes[4]) { measurement.IsValid = false; _errorMessage = string.Format("Checksum invalid. Expected: {0}, Calculated: {1}", bytes[4], checkSum); return(measurement); } measurement.Humidity = (double)(256 * bytes[0] + bytes[1]) / 10; measurement.Temperature = (double)((bytes[2] & 0x7f) * 256 + bytes[3]) / 10; if ((bytes[2] & 0x80) > 0) { measurement.Temperature *= -1; } // if first bit of MSB temperature then temp is negative measurement.IsValid = true; } else { _errorMessage = String.Format("Only {0} signal changes registered, 82 expected.", _receivedSignal.Count); } return(measurement); }
public DhtMeasurement GetMeasurement() { int maxRetries = 5; int retries = 0; DhtMeasurement measurement = new DhtMeasurement() { IsValid = false }; while (retries < maxRetries) { InitializeDataMeasurement(); SendStartToSensor(); ReadSignalFromSensor(); measurement = CalculateResult(); if (measurement.IsValid) { break; } else if (_receivedSignal.Count == 81) { Edge edge = _receivedSignal.FirstOrDefault(); // missed just one edge, might be the first one. Logging.LogMessage("Missed one edge from Dht22, first edge is {0} after micros: {1})", edge.NewValue.ToString(), edge.MicrosFromStart); } else if (retries > 0) // don't log first miss, happens more often { Logging.LogMessage("Invalid Dht22 sensor read, message: {0} (retryCount: {1})", ErrorMessage, retries); } // wait 2 seconds, so that sensor is able to recover... Task.Delay(TimeSpan.FromSeconds(2)).Wait(); retries++; } _dhtPin.SetDriveMode(GpioPinDriveMode.Input); return(measurement); }