Hi there, I’m trying to work out a greenhouse automation. It works pretty well except for the bumpy ride with noisy sensor data. My sensor for gathering temp and humidity is DHT 22. It works ok, for this project, but generates noise. Small noise, due to the instability of the sensor, and also some ridiculous (1546 °C) spikes from time to time.
I thought that it would be nice to fight both these noises with some filtering. I couldn’t find any serious library for that task, and so decided to write the filtering on my own. I prefer to write this on my own, so that I understand what is happening inside.
My idea is to handle the noises accordingly:
Small noise - average from multiple readings
Spikes - High-pass and Low-pass filter that works on a threshold based on the last GOOD temperature.
Also, that the system has to self calibrate when it starts and doesn’t have the “last good temperature” to look for. This is zero at start. Could use setup() to get the first reading but i never know will this be or not a spike, so I decided for self calibrating method.
The problem is that I can’t get the high-pass + low-pass filter to work - probably due to some stupid logical mistake I’ve made. What the code I paste below do is go into infinite loop. Could you point me in to the right direction?
What I would like to happen is as follows:
- Check the DHT sensor for temp and humidity
- Check are the readings within a reasonable range (2 * last reading; should be ok for this application). But if the readings are off from the range for 10 subsequent times - eg. at start when the last temp is 0, this checking stage should accept the 11 reading.
- If yes than wait for another reading and add this to the variable. If not - repeat the reading.
- When enough repetitions happened (different function in my code) - calculate the average, and post this to Blynk.
BTW - I tend to convert (or cast when the extra precision is not needed) the floats into int’s to make the math faster.
I’m sure the problem is somewhere in these lines:
int check = 0;
float H; // Read Humidity
do{
H = dht.getHumidity();
check++;
} while (((int)H >= ((int)h+(int)h) && (int)H <= ((int)h-(int)h)) || check <= 10);
check = 0;
temp_Humid = temp_Humid + (H * 10);
float T; // Read temperature as Celcius
do{
T = dht.getTempCelcius();
} while (((int)T >= ((int)t+(int)t) && (int)T <= ((int)t-(int)t)) || check <= 10);
check = 0;
temp_Temp = temp_Temp + (T * 10);
But probably this might be not enough to get my logic in the code, so here is the whole code boiled down just to the relevant functions and variables:
void na_start()
{
WiFi.selectAntenna(ANT_EXTERNAL);
System.enableFeature(FEATURE_RETAINED_MEMORY);
pinMode(D0, OUTPUT);
digitalWrite(D0, LOW);
}
#include "Adafruit_DHT/Adafruit_DHT.h"
#include "blynk/blynk.h"
#define DHTTYPE DHT22 // DHT 22 (AM2302)
#define DHTPIN D4
DHT dht(DHTPIN, DHTTYPE);
// temp and humidity
float h;
float t;
float dirt;
unsigned long previousMillis = 0;
const long interval = 15*1000; // interval for timed event in a loop
uint32_t lastReset = 0;
int repetition = 0; // counter for how many times the repeted function happened
int temp_Humid = 0;
int temp_Temp = 0;
int dirt_temp = 0;
void after_repetition() { // Will be called automatically after enough repetitions
h = ((float)temp_Humid/repetition)/10;
Blynk.virtualWrite(V5, h);
temp_Humid = 0;
t = ((float)temp_Temp/repetition) / 10;
Blynk.virtualWrite(V6, t);
temp_Temp = 0;
dirt = ((float)dirt_temp/repetition) / 10;
Blynk.virtualWrite(V7, dirt);
dirt_temp = 0;
repetition = 0;
}
void setup() {
lastReset = millis();
pinMode(dirt_humid_pwr, OUTPUT);
delay(3000); // Allow board to settle
dht.begin();
Blynk.begin(auth);
}
void loop() {
Blynk.run();
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
int check = 0;
float H; // Read Humidity
do{
H = dht.getHumidity();
check++;
} while (((int)H >= ((int)h+(int)h) && (int)H <= ((int)h-(int)h)) || check <= 10);
check = 0;
temp_Humid = temp_Humid + (H * 10);
float T; // Read temperature as Celcius
do{
T = dht.getTempCelcius();
} while (((int)T >= ((int)t+(int)t) && (int)T <= ((int)t-(int)t)) || check <= 10);
check = 0;
temp_Temp = temp_Temp + (T * 10);
digitalWrite(dirt_humid_pwr, HIGH); // Read dirt humidity ( I don't power the dirt humidity constantly due to the heavy corrosion it suffers while constantly ON)
delay(5);
int D = analogRead(dirt_humid);
dirt_temp = dirt_temp + map(D, 0, 4095, 0, 1000);
digitalWrite(dirt_humid_pwr,LOW);
repetition ++;
}
if (repetition >= 4) {
after_repetition();
repetition = 0;
}
}
Any help will be greatly appreciated. Thanks