Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions DHT_Sensor/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,34 @@
# DHT Sensor
# DHT Sensor Library

This project reads from a Digital humidity temperature sensor of type (DHT11/21/22)
Root mode should be enabled to get readings from sensor
A Raspberry Pi C++ based library for the series of low cost Digital humidity temperature sensors(DHT11/21/22)

## Usage

Root mode should be enabled to get readings from sensor. The GPIO pin must be given as a run parameter

Wrapper and Test driver already provided to run basic reading tests for convenience. To run:-

```
mkdir build
cd build
g++ -DPI_BUILD -o dht ../src/*.cpp -lwiringPi
./dht <GPIO_PIN_NUMBER>
```

Alternatively, to compile the library and run with your created main program(don't forget to setup the Pi in your program code):

```
mkdir build
cd build
g++ -DPI_BUILD -c ../src/DHT.cpp --lwiringPi
ar rvs DHT.a DHT.o
g++ <your_main_program.cpp> DHT.a
```

## Contributing

Pull requests are always welcome. For major changes, please open an issue first to discuss proposed changes.

## Licence

[MIT](https://choosealicense.com/licenses/mit/)
File renamed without changes
File renamed without changes
213 changes: 69 additions & 144 deletions DHT_Sensor/src/DHT.cpp
Original file line number Diff line number Diff line change
@@ -1,79 +1,59 @@
#include "DHT.h"
#include <math.h>

// global reference definition for the static variables
uint8_t DHT::data[5];
float DHT::t = 0.0;
float DHT::h = 0.0;
DHT *DHT::_instance = NULL;
uint16_t DHT::_pin;
#ifdef PI_BUILD

#include <wiringPi.h>
DHT::DHT(const uint16_t pin) : m_pin(pin)
{
}

// pointer constructor. Should be used in any class that calls needs a dht
// object
// e.g in main -> DHT * dhtobject = DHT::getInstance();
DHT *DHT::getInstance(uint16_t pin)
DHT& DHT::getInstance(const uint16_t pin)
{
if (_instance == NULL)
{
_instance = new DHT();
}
_pin = pin;
return _instance;
static DHT instance(pin);
return instance;
}

#ifdef PI_BUILD
#include <wiringPi.h>

bool DHT::pulse_setter()
{
int pulseCounts[DHT_PULSES * 2] = {0};
pinMode(_pin, OUTPUT);
uint16_t pulseCounts[DHT_PULSES * 2] = {0};
pinMode(m_pin, OUTPUT);

int priority = piHiPri(2);

digitalWrite(_pin, HIGH);
digitalWrite(m_pin, HIGH);
delay(500);

digitalWrite(_pin, LOW);
digitalWrite(m_pin, LOW);
delay(20);

pinMode(_pin, INPUT);
pullUpDnControl(_pin, PUD_UP);
for (volatile int i = 0; i < 50; ++i)
{
pinMode(m_pin, INPUT);
pullUpDnControl(m_pin, PUD_UP);
for (volatile int i = 0; i < 50; ++i) {
}

uint32_t count = 0;
uint8_t count = 0;
// wait for dht to pull pin low
while (digitalRead(_pin) == HIGH)
{
if (++count >= DHT_MAXCOUNT)
{
while (digitalRead(m_pin) == HIGH) {
if (++count >= DHT_MAXCOUNT) {
priority = piHiPri(0);
std::cout << "time out waiting for low" << std::endl;
return false;
}
}
// Record pulse widths for the expected result bits.
for (int i = 0; i < DHT_PULSES * 2; i += 2)
{
for (uint16_t i = 0; i < DHT_PULSES * 2; i += 2) {
// count how long pin is low and store in pulseCounts
while (digitalRead(_pin) == LOW)
{
if (++pulseCounts[i] >= DHT_MAXCOUNT)
{
while (digitalRead(m_pin) == LOW) {
if (++pulseCounts[i] >= DHT_MAXCOUNT) {
priority = piHiPri(0);
std::cout << "time out waiting for high" << std::endl;
return false;
}
}

// count how long pin is high and store in pulse counts
while (digitalRead(_pin) == HIGH)
{
if (++pulseCounts[i + 1] >= DHT_MAXCOUNT)
{
while (digitalRead(m_pin) == HIGH) {
if (++pulseCounts[i + 1] >= DHT_MAXCOUNT) {
priority = piHiPri(0);
std::cout << "time out waiting for low" << std::endl;
return false;
}
}
Expand All @@ -85,9 +65,8 @@ bool DHT::pulse_setter()
// threshold.
// Ignore the first two readings because they are a constant 80 microsecond
// pulse.
uint32_t threshold = 0;
for (int i = 2; i < DHT_PULSES * 2; i += 2)
{
uint16_t threshold = 0;
for (uint16_t i = 2; i < DHT_PULSES * 2; i += 2) {
threshold += pulseCounts[i];
}

Expand All @@ -98,146 +77,92 @@ bool DHT::pulse_setter()
// If the count is less than 50us it must be a ~28us 0 pulse, and if it's
// higher
// then it must be a ~70us 1 pulse.
data[5] = {0};
for (int i = 3; i < DHT_PULSES * 2; i += 2)
{
int index = (i - 3) / 16;
data[index] <<= 1;
if (pulseCounts[i] >= threshold)
{
for (uint16_t i = 3; i < DHT_PULSES * 2; i += 2) {
uint8_t index = (i - 3) / 16;
m_data[index] <<= 1;
if (pulseCounts[i] >= threshold) {
// One bit for long pulse.
data[index] |= 1;
m_data[index] |= 1;
}
// Else zero bit for short pulse.
}
// Verify checksum of received data.
if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF))
{
return true;
}
else
{
std::cout << "Check sum failure" << std::endl;
if (!(m_data[4] == ((m_data[0] + m_data[1] + m_data[2] + m_data[3]) & 0xFF))) {
return false;
}

return true;
}

void DHT::read_sensor()
{
float div;
if (pulse_setter() == true)
{
temperature = &t;
humidity = &h;
h = ((float)(data[0] * 256 + data[1])) / 10.0;
if (data[2] & 0x80)
{ // for minus temperature values
div = -10.0;
}
else
div = 10.0;
if (pulse_setter()) {
m_humidity = static_cast<float>((m_data[0] * 256 + m_data[1]) / 10.0);

t = ((float)((data[2] & 0x7F) * 256 + data[3])) / div;
const auto divisor = m_data[2] & 0x80 ? -10.0F : 10.0F; // -10 for negative temperature values
m_temperature = static_cast<float>(((m_data[2] & 0x7F) * 256 + m_data[3]) / divisor);
}
else if (!pulse_setter())
{
else {
std::cout << "bad data, last good read will be returned" << std::endl;
}
}

#else // empty implementation for build on windows
bool DHT::pulse_setter() { return false; }
void DHT::read_sensor() {}
#endif

float DHT::get_heatIndex()
{
float temperature;
float percentHumidity;
float hi;
temperature = *temperature;
percentHumidity = *humidity;
temperature = convertCtoF(temperature);
hi = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) +
(percentHumidity * 0.094));
if (hi > 79)
{
hi = -42.379 + 2.04901523 * temperature +
10.14333127 * percentHumidity +
-0.22475541 * temperature * percentHumidity +
-0.00683783 * pow(temperature, 2) +
const float hi = compute_heat_index();
return hi;
}

const float DHT::compute_heat_index()
{
float percentHumidity = m_humidity;
float temperature = convertCtoF(m_temperature);
float hi =
0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) + (percentHumidity * 0.094));
if (hi > 79) {
hi = -42.379 + 2.04901523 * temperature + 10.14333127 * percentHumidity +
-0.22475541 * temperature * percentHumidity + -0.00683783 * pow(temperature, 2) +
-0.05481717 * pow(percentHumidity, 2) +
0.00122874 * pow(temperature, 2) * percentHumidity +
0.00085282 * temperature * pow(percentHumidity, 2) +
-0.00000199 * pow(temperature, 2) * pow(percentHumidity, 2);

if ((percentHumidity < 13) && (temperature >= 80.0) &&
(temperature <= 112.0))
if ((percentHumidity < 13) && (temperature >= 80.0) && (temperature <= 112.0))
hi -= ((13.0 - percentHumidity) * 0.25) *
sqrt((17.0 - abs(temperature - 95.0)) * 0.05882);

else if ((percentHumidity > 85.0) && (temperature >= 80.0) &&
(temperature <= 87.0))
hi +=
((percentHumidity - 85.0) * 0.1) * ((87.0 - temperature) * 0.2);
else if ((percentHumidity > 85.0) && (temperature >= 80.0) && (temperature <= 87.0))
hi += ((percentHumidity - 85.0) * 0.1) * ((87.0 - temperature) * 0.2);
}

return convertFtoC(hi);
}

float DHT::convertCtoF(float c)
const float DHT::convertCtoF(const float c)
{
return c * 1.8 + 32;
}

float DHT::convertFtoC(float f)
const float DHT::convertFtoC(const float f)
{
return (f - 32) * 0.55555;
}

float DHT::get_temperature()
{
if (temperature == NULL)
read_sensor();
if (temperature != NULL)
return *temperature;
else
return 0.0;
read_sensor();
const float temperature = (m_temperature != 0.0F) ? m_temperature : 0.0F;
return temperature;
}

float DHT::get_humidity()
{
if (humidity == NULL)
read_sensor();
if (humidity != NULL)
return *humidity;
else
return 0.0;
}
#else
// empty implementation for build on windows
float DHT::convertCtoF(float c)
{
return -1;
read_sensor();
const float humidity = (m_humidity != 0.0F) ? m_humidity : 0.0F;
return humidity;
}
float DHT::convertFtoC(float f)
{
return -1;
}
bool DHT::pulse_setter()
{
return false;
}
DHT *DHT::getInstance(uint16_t pin)
{
return NULL;
}
float DHT::get_temperature()
{
return -1;
}
float DHT::get_humidity()
{
return -1;
}
float DHT::get_heatIndex()
{
return -1;
}

#endif
Loading