GY-63_MS5611/libraries/DHTINT/dhtint.cpp

394 lines
8.4 KiB
C++
Raw Normal View History

2022-05-08 07:05:13 -04:00
//
// FILE: dhtint.cpp
// AUTHOR: Rob.Tillaart
2023-10-25 11:21:50 -04:00
// VERSION: 0.1.4
2022-05-08 07:05:13 -04:00
// PURPOSE: Arduino library for DHT sensors - integer only
// URL: https://github.com/RobTillaart/DHTINT
//
2022-11-02 06:22:23 -04:00
// HISTORY: see changelog.md
2022-05-08 07:05:13 -04:00
#include "dhtint.h"
#include <stdint.h>
2023-10-25 11:21:50 -04:00
// these defines are not for user to adjust
2022-05-08 07:05:13 -04:00
#define DHTLIB_DHT11_WAKEUP 18
#define DHTLIB_DHT_WAKEUP 1
2023-10-25 11:21:50 -04:00
// READ_DELAY for blocking read
// datasheet: DHT11 = 1000 and DHT22 = 2000
// use setReadDelay() to overrule (at own risk)
// as individual sensors can be read faster.
// see example DHTnew_setReadDelay.ino
2022-05-08 07:05:13 -04:00
#define DHTLIB_DHT11_READ_DELAY 1000
#define DHTLIB_DHT22_READ_DELAY 2000
/////////////////////////////////////////////////////
//
2023-10-25 11:21:50 -04:00
// PUBLIC
2022-05-08 07:05:13 -04:00
//
DHTINT::DHTINT(uint8_t pin)
{
_dataPin = pin;
reset();
};
void DHTINT::reset()
{
2023-10-25 11:21:50 -04:00
// Data-bus's free status is high voltage level.
2022-05-08 07:05:13 -04:00
pinMode(_dataPin, OUTPUT);
digitalWrite(_dataPin, HIGH);
_wakeupDelay = 0;
_type = 0;
_humOffset = 0;
_tempOffset = 0;
_humidity = 0;
_temperature = 0;
_lastRead = 0;
_disableIRQ = true;
_waitForRead = false;
_suppressError = false;
_readDelay = 0;
#if defined(__AVR__)
_disableIRQ = false;
#endif
2023-10-25 11:21:50 -04:00
// #if defined(MKR1010) // TODO find out real define
// _disableIRQ = false;
// #endif
2022-05-08 07:05:13 -04:00
}
uint8_t DHTINT::getType()
{
if (_type == 0) read();
return _type;
}
void DHTINT::setType(uint8_t type)
{
if ((type == 0) || (type == 11))
{
_type = type;
_wakeupDelay = DHTLIB_DHT11_WAKEUP;
}
if (type == 22)
{
_type = type;
_wakeupDelay = DHTLIB_DHT_WAKEUP;
}
}
2023-10-25 11:21:50 -04:00
// return values:
// DHTLIB_OK
// DHTLIB_WAITING_FOR_READ
// DHTLIB_ERROR_CHECKSUM
// DHTLIB_ERROR_BIT_SHIFT
// DHTLIB_ERROR_SENSOR_NOT_READY
// DHTLIB_ERROR_TIMEOUT_A
// DHTLIB_ERROR_TIMEOUT_B
// DHTLIB_ERROR_TIMEOUT_C
// DHTLIB_ERROR_TIMEOUT_D
2022-05-08 07:05:13 -04:00
int DHTINT::read()
{
if (_readDelay == 0)
{
_readDelay = DHTLIB_DHT22_READ_DELAY;
if (_type == 11) _readDelay = DHTLIB_DHT11_READ_DELAY;
}
if (_type != 0)
{
while (millis() - _lastRead < _readDelay)
{
if (!_waitForRead) return DHTLIB_WAITING_FOR_READ;
yield();
}
return _read();
}
_type = 22;
_wakeupDelay = DHTLIB_DHT_WAKEUP;
int rv = _read();
if (rv == DHTLIB_OK) return rv;
_type = 11;
_wakeupDelay = DHTLIB_DHT11_WAKEUP;
rv = _read();
if (rv == DHTLIB_OK) return rv;
2023-10-25 11:21:50 -04:00
_type = 0; // retry next time
2022-05-08 07:05:13 -04:00
return rv;
}
2022-05-16 14:05:48 -04:00
int DHTINT::getHumidity()
{
2023-10-25 11:21:50 -04:00
return (_humidity + _humOffset + 5) / 10;
2022-05-16 14:05:48 -04:00
};
int DHTINT::getTemperature()
{
2023-10-25 11:21:50 -04:00
return (_temperature + _tempOffset + 5) / 10;
2022-05-16 14:05:48 -04:00
};
2023-10-25 11:21:50 -04:00
// return values:
// DHTLIB_OK
// DHTLIB_ERROR_CHECKSUM
// DHTLIB_ERROR_BIT_SHIFT
// DHTLIB_ERROR_SENSOR_NOT_READY
// DHTLIB_ERROR_TIMEOUT_A
// DHTLIB_ERROR_TIMEOUT_B
// DHTLIB_ERROR_TIMEOUT_C
// DHTLIB_ERROR_TIMEOUT_D
2022-05-08 07:05:13 -04:00
int DHTINT::_read()
{
2023-10-25 11:21:50 -04:00
// READ VALUES
2022-05-08 07:05:13 -04:00
int rv = _readSensor();
interrupts();
2023-10-25 11:21:50 -04:00
// Data-bus's free status is high voltage level.
2022-05-08 07:05:13 -04:00
pinMode(_dataPin, OUTPUT);
digitalWrite(_dataPin, HIGH);
_lastRead = millis();
if (rv != DHTLIB_OK)
{
if (_suppressError == false)
{
_humidity = DHTLIB_INVALID_VALUE;
_temperature = DHTLIB_INVALID_VALUE;
}
2023-10-25 11:21:50 -04:00
return rv; // propagate error value
2022-05-08 07:05:13 -04:00
}
2023-10-25 11:21:50 -04:00
if (_type == 22) // DHT22, DHT33, DHT44, compatible
2022-05-08 07:05:13 -04:00
{
2022-05-16 14:05:48 -04:00
_humidity = _bits[0] * 256 + _bits[1];
_temperature = (_bits[2] & 0x7F) * 256 + _bits[3];
2022-05-12 09:07:38 -04:00
if((_bits[2] & 0x80) == 0x80 )
2022-05-08 07:05:13 -04:00
{
2022-05-12 09:07:38 -04:00
_temperature = -_temperature;
2022-05-08 07:05:13 -04:00
}
}
2023-10-25 11:21:50 -04:00
else // if (_type == 11) // DHT11, DH12, compatible
2022-05-08 07:05:13 -04:00
{
2022-05-16 14:05:48 -04:00
_humidity = _bits[0] * 10 + _bits[1];
_temperature = _bits[2] * 10 + _bits[3];
2022-05-08 07:05:13 -04:00
}
2023-10-25 11:21:50 -04:00
// HEXDUMP DEBUG
2022-05-08 07:05:13 -04:00
/*
Serial.println();
// CHECKSUM
if (_bits[4] < 0x10) Serial.print(0);
Serial.print(_bits[4], HEX);
Serial.print(" ");
// TEMPERATURE
if (_bits[2] < 0x10) Serial.print(0);
Serial.print(_bits[2], HEX);
if (_bits[3] < 0x10) Serial.print(0);
Serial.print(_bits[3], HEX);
Serial.print(" ");
Serial.print(_temperature, 1);
Serial.print(" ");
// HUMIDITY
if (_bits[0] < 0x10) Serial.print(0);
Serial.print(_bits[0], HEX);
if (_bits[1] < 0x10) Serial.print(0);
Serial.print(_bits[1], HEX);
Serial.print(" ");
Serial.print(_humidity, 1);
*/
2023-10-25 11:21:50 -04:00
// TEST OUT OF RANGE
2022-05-08 07:05:13 -04:00
#ifdef DHTLIB_VALUE_OUT_OF_RANGE
2022-05-16 14:05:48 -04:00
if (_humidity > 1000)
2022-05-08 07:05:13 -04:00
{
return DHTLIB_HUMIDITY_OUT_OF_RANGE;
}
2022-05-16 14:05:48 -04:00
if ((_temperature < -400) || (_temperature > 800))
2022-05-08 07:05:13 -04:00
{
return DHTLIB_TEMPERATURE_OUT_OF_RANGE;
}
#endif
2023-10-25 11:21:50 -04:00
// TEST CHECKSUM
2022-05-08 07:05:13 -04:00
uint8_t sum = _bits[0] + _bits[1] + _bits[2] + _bits[3];
if (_bits[4] != sum)
{
return DHTLIB_ERROR_CHECKSUM;
}
return DHTLIB_OK;
}
void DHTINT::powerUp()
{
digitalWrite(_dataPin, HIGH);
2023-10-25 11:21:50 -04:00
// do a dummy read to sync the sensor
2022-05-08 07:05:13 -04:00
read();
};
void DHTINT::powerDown()
{
digitalWrite(_dataPin, LOW);
}
2022-05-12 09:07:38 -04:00
uint16_t DHTINT::getRawTemperature()
{
uint16_t raw = _bits[2] * 256 + _bits[3];
return raw;
};
uint16_t DHTINT::getRawHumidity()
{
uint16_t raw = _bits[0] * 256 + _bits[1];
return raw;
}
2022-05-08 07:05:13 -04:00
/////////////////////////////////////////////////////
//
2023-10-25 11:21:50 -04:00
// PRIVATE
2022-05-08 07:05:13 -04:00
//
2023-10-25 11:21:50 -04:00
// return values:
// DHTLIB_OK
// DHTLIB_ERROR_CHECKSUM
// DHTLIB_ERROR_BIT_SHIFT
// DHTLIB_ERROR_SENSOR_NOT_READY
// DHTLIB_ERROR_TIMEOUT_A
// DHTLIB_ERROR_TIMEOUT_B
// DHTLIB_ERROR_TIMEOUT_C
// DHTLIB_ERROR_TIMEOUT_D
2022-05-08 07:05:13 -04:00
int DHTINT::_readSensor()
{
2023-10-25 11:21:50 -04:00
// INIT BUFFERVAR TO RECEIVE DATA
2022-05-08 07:05:13 -04:00
uint8_t mask = 0x80;
uint8_t idx = 0;
// EMPTY BUFFER
for (uint8_t i = 0; i < 5; i++) _bits[i] = 0;
2023-10-25 11:21:50 -04:00
// REQUEST SAMPLE - SEND WAKEUP TO SENSOR
2022-05-08 07:05:13 -04:00
pinMode(_dataPin, OUTPUT);
digitalWrite(_dataPin, LOW);
2023-10-25 11:21:50 -04:00
// WAKE UP - add 10% extra for timing inaccuracies in sensor.
2022-05-08 07:05:13 -04:00
uint32_t startWakeup = micros();
do
{
2023-10-25 11:21:50 -04:00
// HANDLE PENDING IRQ
2022-05-08 07:05:13 -04:00
yield();
2023-10-25 11:21:50 -04:00
// 180 gives good wakeup delay on UNO for DHT22 / DHT11 (issue #72)
delayMicroseconds(180UL);
2022-05-08 07:05:13 -04:00
}
while((micros() - startWakeup) < (_wakeupDelay * 1100UL));
2023-10-25 11:21:50 -04:00
// HOST GIVES CONTROL TO SENSOR
2022-05-08 07:05:13 -04:00
digitalWrite(_dataPin, HIGH);
delayMicroseconds(2);
pinMode(_dataPin, INPUT_PULLUP);
2023-10-25 11:21:50 -04:00
// DISABLE INTERRUPTS when clock in the bits
2022-05-08 07:05:13 -04:00
if (_disableIRQ) { noInterrupts(); }
2023-10-25 11:21:50 -04:00
// DHT22
// SENSOR PULLS LOW after 20-40 us => if stays HIGH ==> device not ready
// timeout is 20 us less due to delay() above
// DHT11
// SENSOR PULLS LOW after 6000-10000 us
2022-05-08 07:05:13 -04:00
uint32_t WAITFORSENSOR = 50;
if (_type == 11) WAITFORSENSOR = 15000UL;
if (_waitFor(LOW, WAITFORSENSOR)) return DHTLIB_ERROR_SENSOR_NOT_READY;
2023-10-25 11:21:50 -04:00
// SENSOR STAYS LOW for ~80 us => or TIMEOUT
2022-05-08 07:05:13 -04:00
if (_waitFor(HIGH, 90)) return DHTLIB_ERROR_TIMEOUT_A;
2023-10-25 11:21:50 -04:00
// SENSOR STAYS HIGH for ~80 us => or TIMEOUT
2022-05-08 07:05:13 -04:00
if (_waitFor(LOW, 90)) return DHTLIB_ERROR_TIMEOUT_B;
2023-10-25 11:21:50 -04:00
// SENSOR HAS NOW SEND ACKNOWLEDGE ON WAKEUP
// NOW IT SENDS THE BITS
2022-05-08 07:05:13 -04:00
2023-10-25 11:21:50 -04:00
// READ THE OUTPUT - 40 BITS => 5 BYTES
2022-05-08 07:05:13 -04:00
for (uint8_t i = 40; i != 0; i--)
{
2023-10-25 11:21:50 -04:00
// EACH BIT START WITH ~50 us LOW
if (_waitFor(HIGH, 90))
2022-05-08 07:05:13 -04:00
{
2023-10-25 11:21:50 -04:00
// Most critical timeout
// Serial.print("IC: ");
// Serial.println(i);
2022-05-08 07:05:13 -04:00
return DHTLIB_ERROR_TIMEOUT_C;
}
2023-10-25 11:21:50 -04:00
// DURATION OF HIGH DETERMINES 0 or 1
// 26-28 us ==> 0
// 70 us ==> 1
2022-05-08 07:05:13 -04:00
uint32_t t = micros();
if (_waitFor(LOW, 90))
{
2023-10-25 11:21:50 -04:00
// Serial.print("ID: ");
// Serial.println(i);
2022-05-08 07:05:13 -04:00
return DHTLIB_ERROR_TIMEOUT_D;
}
if ((micros() - t) > DHTLIB_BIT_THRESHOLD)
{
_bits[idx] |= mask;
}
2023-10-25 11:21:50 -04:00
// PREPARE FOR NEXT BIT
2022-05-08 07:05:13 -04:00
mask >>= 1;
if (mask == 0) // next byte?
{
mask = 0x80;
idx++;
}
}
2023-10-25 11:21:50 -04:00
// After 40 bits the sensor pulls the line LOW for 50 us
// No functional need to wait for this one
// if (_waitFor(HIGH, 60)) return DHTLIB_ERROR_TIMEOUT_E;
2022-05-08 07:05:13 -04:00
2023-10-25 11:21:50 -04:00
// CATCH RIGHTSHIFT BUG ESP (only 1 single bit shift)
// humidity is maximum 1000 = 0x03E8 for DHT22 and 0x6400 for DHT11
// so most significant bit may never be set.
2022-05-08 07:05:13 -04:00
if (_bits[0] & 0x80) return DHTLIB_ERROR_BIT_SHIFT;
return DHTLIB_OK;
}
2023-10-25 11:21:50 -04:00
// returns true if timeout has passed.
// returns false if timeout is not reached and state is seen.
2022-05-08 07:05:13 -04:00
bool DHTINT::_waitFor(uint8_t state, uint32_t timeout)
{
uint32_t start = micros();
uint8_t count = 2;
while ((micros() - start) < timeout)
{
2023-10-25 11:21:50 -04:00
// delayMicroseconds(1); // less # reads ==> minimizes # glitch reads
2022-05-08 07:05:13 -04:00
if (digitalRead(_dataPin) == state)
{
count--;
2023-10-25 11:21:50 -04:00
if (count == 0) return false; // requested state seen count times
2022-05-08 07:05:13 -04:00
}
}
return true;
}
2023-10-25 11:21:50 -04:00
// -- END OF FILE --
2022-05-08 07:05:13 -04:00