DHT22/DHT11 humidity/temperature sensor usermod (#1719)
* DHT22/DHT11 humidity/temperature sensor usermod * cleanup - don't report when usermod is auto-disabled since report isn't persistent * track error count; retry once after error occurs * for esp32, use esp32DHT library * fix unreliable ESP32 readings by switching DHT library to https://github.com/alwynallan/DHT_nonblocking * change default pin to Q2; don't burst readings if error occurs Co-authored-by: Aircoookie <dev.aircoookie@gmail.com>
This commit is contained in:
parent
d56ab6c971
commit
aa242d897d
22
usermods/DHT/platformio_override.ini
Normal file
22
usermods/DHT/platformio_override.ini
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
; Options
|
||||||
|
; -------
|
||||||
|
; USERMOD_DHT - define this to have this user mod included wled00\usermods_list.cpp
|
||||||
|
; USERMOD_DHT_DHTTYPE - DHT model: 11, 21, 22 for DHT11, DHT21, or DHT22, defaults to 22/DHT22
|
||||||
|
; USERMOD_DHT_PIN - pin to which DTH is connected, defaults to Q2 pin on QuinLed Dig-Uno's board
|
||||||
|
; USERMOD_DHT_CELSIUS - define this to report temperatures in degrees celsious, otherwise fahrenheit will be reported
|
||||||
|
; USERMOD_DHT_MEASUREMENT_INTERVAL - the number of milliseconds between measurements, defaults to 60 seconds
|
||||||
|
; USERMOD_DHT_FIRST_MEASUREMENT_AT - the number of milliseconds after boot to take first measurement, defaults to 90 seconds
|
||||||
|
; USERMOD_DHT_STATS - For debug, report delay stats
|
||||||
|
|
||||||
|
[env:d1_mini_usermod_dht_C]
|
||||||
|
extends = env:d1_mini
|
||||||
|
build_flags = ${env:d1_mini.build_flags} -D USERMOD_DHT -D USERMOD_DHT_CELSIUS
|
||||||
|
lib_deps = ${env.lib_deps}
|
||||||
|
https://github.com/alwynallan/DHT_nonblocking
|
||||||
|
|
||||||
|
[env:custom32_LEDPIN_16_usermod_dht_C]
|
||||||
|
extends = env:custom32_LEDPIN_16
|
||||||
|
build_flags = ${env:custom32_LEDPIN_16.build_flags} -D USERMOD_DHT -D USERMOD_DHT_CELSIUS -D USERMOD_DHT_STATS
|
||||||
|
lib_deps = ${env.lib_deps}
|
||||||
|
https://github.com/alwynallan/DHT_nonblocking
|
||||||
|
|
41
usermods/DHT/readme.md
Normal file
41
usermods/DHT/readme.md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# DHT Temperature/Humidity sensor usermod
|
||||||
|
|
||||||
|
This usermod will read from an attached DHT22 or DHT11 humidity and temperature sensor.
|
||||||
|
The sensor readings are displayed in the Info section of the web UI.
|
||||||
|
|
||||||
|
If sensor is not detected after a while (10 update intervals), this usermod will be disabled.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Copy the example `platformio_override.ini` to the root directory. This file should be placed in the same directory as `platformio.ini`.
|
||||||
|
|
||||||
|
### Define Your Options
|
||||||
|
|
||||||
|
* `USERMOD_DHT` - define this to have this user mod included wled00\usermods_list.cpp
|
||||||
|
* `USERMOD_DHT_DHTTYPE` - DHT model: 11, 21, 22 for DHT11, DHT21, or DHT22, defaults to 22/DHT22
|
||||||
|
* `USERMOD_DHT_PIN` - pin to which DTH is connected, defaults to Q2 pin on QuinLed Dig-Uno's board
|
||||||
|
* `USERMOD_DHT_CELSIUS` - define this to report temperatures in degrees celsious, otherwise fahrenheit will be reported
|
||||||
|
* `USERMOD_DHT_MEASUREMENT_INTERVAL` - the number of milliseconds between measurements, defaults to 60 seconds
|
||||||
|
* `USERMOD_DHT_FIRST_MEASUREMENT_AT` - the number of milliseconds after boot to take first measurement, defaults to 90 seconds
|
||||||
|
* `USERMOD_DHT_STATS` - For debug, report delay stats
|
||||||
|
|
||||||
|
## Project link
|
||||||
|
|
||||||
|
* [QuinLED-Dig-Uno](https://quinled.info/2018/09/15/quinled-dig-uno/) - Project link
|
||||||
|
|
||||||
|
### PlatformIO requirements
|
||||||
|
|
||||||
|
If you are using `platformio_override.ini`, you should be able to refresh the task list and see your custom task, for example `env:d1_mini_usermod_dht_C`. If not, you can add the libraries and dependencies into `platformio.ini` as you see fit.
|
||||||
|
|
||||||
|
|
||||||
|
## Change Log
|
||||||
|
|
||||||
|
2020-02-04
|
||||||
|
* Change default QuinLed pin to Q2
|
||||||
|
* Instead of trying to keep updates at constant cadence, space readings out by measurement interval; hope this helps to avoid occasional bursts of readings with errors
|
||||||
|
* Add some more (optional) stats
|
||||||
|
2020-02-03
|
||||||
|
* Due to poor readouts on ESP32 with previous DHT library, rewrote to use https://github.com/alwynallan/DHT_nonblocking
|
||||||
|
* The new library serializes/delays up to 5ms for the sensor readout
|
||||||
|
2020-02-02
|
||||||
|
* Created
|
216
usermods/DHT/usermod_dht.h
Normal file
216
usermods/DHT/usermod_dht.h
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "wled.h"
|
||||||
|
|
||||||
|
#include <dht_nonblocking.h>
|
||||||
|
|
||||||
|
// USERMOD_DHT_DHTTYPE:
|
||||||
|
// 11 // DHT 11
|
||||||
|
// 21 // DHT 21
|
||||||
|
// 22 // DHT 22 (AM2302), AM2321 *** default
|
||||||
|
#ifndef USERMOD_DHT_DHTTYPE
|
||||||
|
#define USERMOD_DHT_DHTTYPE 22
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USERMOD_DHT_DHTTYPE == 11
|
||||||
|
#define DHTTYPE DHT_TYPE_11
|
||||||
|
#elif USERMOD_DHT_DHTTYPE == 21
|
||||||
|
#define DHTTYPE DHT_TYPE_21
|
||||||
|
#elif USERMOD_DHT_DHTTYPE == 22
|
||||||
|
#define DHTTYPE DHT_TYPE_22
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Connect pin 1 (on the left) of the sensor to +5V
|
||||||
|
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
|
||||||
|
// to 3.3V instead of 5V!
|
||||||
|
// Connect pin 2 of the sensor to whatever your DHTPIN is
|
||||||
|
// NOTE: Pin defaults below are for QuinLed Dig-Uno's Q2 on the board
|
||||||
|
// Connect pin 4 (on the right) of the sensor to GROUND
|
||||||
|
// NOTE: If using a bare sensor (AM*), Connect a 10K resistor from pin 2
|
||||||
|
// (data) to pin 1 (power) of the sensor. DHT* boards have the pullup already
|
||||||
|
|
||||||
|
#ifdef USERMOD_DHT_PIN
|
||||||
|
#define DHTPIN USERMOD_DHT_PIN
|
||||||
|
#else
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
#define DHTPIN 21
|
||||||
|
#else //ESP8266 boards
|
||||||
|
#define DHTPIN 4
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// the frequency to check sensor, 1 minute
|
||||||
|
#ifndef USERMOD_DHT_MEASUREMENT_INTERVAL
|
||||||
|
#define USERMOD_DHT_MEASUREMENT_INTERVAL 60000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// how many seconds after boot to take first measurement, 90 seconds
|
||||||
|
// 90 gives enough time to OTA update firmware if this crashses
|
||||||
|
#ifndef USERMOD_DHT_FIRST_MEASUREMENT_AT
|
||||||
|
#define USERMOD_DHT_FIRST_MEASUREMENT_AT 90000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// from COOLDOWN_TIME in dht_nonblocking.cpp
|
||||||
|
#define DHT_TIMEOUT_TIME 10000
|
||||||
|
|
||||||
|
DHT_nonblocking dht_sensor(DHTPIN, DHTTYPE);
|
||||||
|
|
||||||
|
class UsermodDHT : public Usermod {
|
||||||
|
private:
|
||||||
|
unsigned long nextReadTime = 0;
|
||||||
|
unsigned long lastReadTime = 0;
|
||||||
|
float humidity, temperature = 0;
|
||||||
|
bool initializing = true;
|
||||||
|
bool disabled = false;
|
||||||
|
#ifdef USERMOD_DHT_STATS
|
||||||
|
unsigned long nextResetStatsTime = 0;
|
||||||
|
uint16_t updates = 0;
|
||||||
|
uint16_t clean_updates = 0;
|
||||||
|
uint16_t errors = 0;
|
||||||
|
unsigned long maxDelay = 0;
|
||||||
|
unsigned long currentIteration = 0;
|
||||||
|
unsigned long maxIteration = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
void setup() {
|
||||||
|
nextReadTime = millis() + USERMOD_DHT_FIRST_MEASUREMENT_AT;
|
||||||
|
lastReadTime = millis();
|
||||||
|
#ifdef USERMOD_DHT_STATS
|
||||||
|
nextResetStatsTime = millis() + 60*60*1000;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (millis() < nextReadTime) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USERMOD_DHT_STATS
|
||||||
|
if (millis() >= nextResetStatsTime) {
|
||||||
|
nextResetStatsTime += 60*60*1000;
|
||||||
|
errors = 0;
|
||||||
|
updates = 0;
|
||||||
|
clean_updates = 0;
|
||||||
|
}
|
||||||
|
unsigned long dcalc = millis();
|
||||||
|
if (currentIteration == 0) {
|
||||||
|
currentIteration = millis();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float tempC;
|
||||||
|
if (dht_sensor.measure(&tempC, &humidity)) {
|
||||||
|
#ifdef USERMOD_DHT_CELSIUS
|
||||||
|
temperature = tempC;
|
||||||
|
#else
|
||||||
|
temperature = tempC * 9 / 5 + 32;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nextReadTime = millis() + USERMOD_DHT_MEASUREMENT_INTERVAL;
|
||||||
|
lastReadTime = millis();
|
||||||
|
initializing = false;
|
||||||
|
|
||||||
|
#ifdef USERMOD_DHT_STATS
|
||||||
|
unsigned long icalc = millis() - currentIteration;
|
||||||
|
if (icalc > maxIteration) {
|
||||||
|
maxIteration = icalc;
|
||||||
|
}
|
||||||
|
if (icalc > DHT_TIMEOUT_TIME) {
|
||||||
|
errors += icalc/DHT_TIMEOUT_TIME;
|
||||||
|
} else {
|
||||||
|
clean_updates += 1;
|
||||||
|
}
|
||||||
|
updates += 1;
|
||||||
|
currentIteration = 0;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USERMOD_DHT_STATS
|
||||||
|
dcalc = millis() - dcalc;
|
||||||
|
if (dcalc > maxDelay) {
|
||||||
|
maxDelay = dcalc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (((millis() - lastReadTime) > 10*USERMOD_DHT_MEASUREMENT_INTERVAL)) {
|
||||||
|
disabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addToJsonInfo(JsonObject& root) {
|
||||||
|
if (disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JsonObject user = root["u"];
|
||||||
|
if (user.isNull()) user = root.createNestedObject("u");
|
||||||
|
|
||||||
|
JsonArray temp = user.createNestedArray("Temperature");
|
||||||
|
JsonArray hum = user.createNestedArray("Humidity");
|
||||||
|
|
||||||
|
#ifdef USERMOD_DHT_STATS
|
||||||
|
JsonArray next = user.createNestedArray("next");
|
||||||
|
if (nextReadTime >= millis()) {
|
||||||
|
next.add((nextReadTime - millis()) / 1000);
|
||||||
|
next.add(" sec until read");
|
||||||
|
} else {
|
||||||
|
next.add((millis() - nextReadTime) / 1000);
|
||||||
|
next.add(" sec active reading");
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray last = user.createNestedArray("last");
|
||||||
|
last.add((millis() - lastReadTime) / 60000);
|
||||||
|
last.add(" min since read");
|
||||||
|
|
||||||
|
JsonArray err = user.createNestedArray("errors");
|
||||||
|
err.add(errors);
|
||||||
|
err.add(" Errors");
|
||||||
|
|
||||||
|
JsonArray upd = user.createNestedArray("updates");
|
||||||
|
upd.add(updates);
|
||||||
|
upd.add(" Updates");
|
||||||
|
|
||||||
|
JsonArray cupd = user.createNestedArray("cleanUpdates");
|
||||||
|
cupd.add(clean_updates);
|
||||||
|
cupd.add(" Updates");
|
||||||
|
|
||||||
|
JsonArray iter = user.createNestedArray("maxIter");
|
||||||
|
iter.add(maxIteration);
|
||||||
|
iter.add(" ms");
|
||||||
|
|
||||||
|
JsonArray delay = user.createNestedArray("maxDelay");
|
||||||
|
delay.add(maxDelay);
|
||||||
|
delay.add(" ms");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (initializing) {
|
||||||
|
// if we haven't read the sensor yet, let the user know
|
||||||
|
// that we are still waiting for the first measurement
|
||||||
|
temp.add((nextReadTime - millis()) / 1000);
|
||||||
|
temp.add(" sec until read");
|
||||||
|
hum.add((nextReadTime - millis()) / 1000);
|
||||||
|
hum.add(" sec until read");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hum.add(humidity);
|
||||||
|
hum.add("%");
|
||||||
|
|
||||||
|
temp.add(temperature);
|
||||||
|
#ifdef USERMOD_DHT_CELSIUS
|
||||||
|
temp.add("°C");
|
||||||
|
#else
|
||||||
|
temp.add("°F");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t getId()
|
||||||
|
{
|
||||||
|
return USERMOD_ID_DHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
@ -24,6 +24,7 @@
|
|||||||
#define USERMOD_ID_FOUR_LINE_DISP 7 //Usermod "usermod_v2_four_line_display.h
|
#define USERMOD_ID_FOUR_LINE_DISP 7 //Usermod "usermod_v2_four_line_display.h
|
||||||
#define USERMOD_ID_ROTARY_ENC_UI 8 //Usermod "usermod_v2_rotary_encoder_ui.h"
|
#define USERMOD_ID_ROTARY_ENC_UI 8 //Usermod "usermod_v2_rotary_encoder_ui.h"
|
||||||
#define USERMOD_ID_AUTO_SAVE 9 //Usermod "usermod_v2_auto_save.h"
|
#define USERMOD_ID_AUTO_SAVE 9 //Usermod "usermod_v2_auto_save.h"
|
||||||
|
#define USERMOD_ID_DHT 10 //Usermod "usermod_dht.h"
|
||||||
|
|
||||||
//Access point behavior
|
//Access point behavior
|
||||||
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot
|
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot
|
||||||
|
@ -31,6 +31,10 @@
|
|||||||
#include "../usermods/usermod_v2_auto_save/usermod_v2_auto_save.h"
|
#include "../usermods/usermod_v2_auto_save/usermod_v2_auto_save.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USERMOD_DHT
|
||||||
|
#include "../usermods/DHT/usermod_dht.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
void registerUsermods()
|
void registerUsermods()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -49,7 +53,6 @@ void registerUsermods()
|
|||||||
#ifdef USERMOD_SENSORSTOMQTT
|
#ifdef USERMOD_SENSORSTOMQTT
|
||||||
usermods.add(new UserMod_SensorsToMQTT());
|
usermods.add(new UserMod_SensorsToMQTT());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USERMOD_FOUR_LINE_DISLAY
|
#ifdef USERMOD_FOUR_LINE_DISLAY
|
||||||
usermods.add(new FourLineDisplayUsermod());
|
usermods.add(new FourLineDisplayUsermod());
|
||||||
#endif
|
#endif
|
||||||
@ -59,4 +62,7 @@ void registerUsermods()
|
|||||||
#ifdef USERMOD_AUTO_SAVE
|
#ifdef USERMOD_AUTO_SAVE
|
||||||
usermods.add(new AutoSaveUsermod());
|
usermods.add(new AutoSaveUsermod());
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USERMOD_DHT
|
||||||
|
usermods.add(new UsermodDHT());
|
||||||
|
#endif
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user