Humidity sensors

Hi guys what is the best humidity sensor, the most reliable one, I have tried th dht22 and I was very disappointed, I am now trying the bme280 and am even less impressed, I need a reliable sensor in a constant high humdity state????

What the bme280 is doing is it functions perfectly till the rh gets up to 92 percent then it gives a reading of 100 percent on th humidity and -145 on the temp, I have tried 2 separate units both brand new with the same results

Sounds like the temperature of the sensor is going below dew point and water (dew) is condensing on it causing current leakage between terminals. Does the library you're using give a dew point reading? Should be less than temperature unless humidity is 100%.
EDIT: How are you controlling humidity? Maybe it's going up faster than the sensor can track it.

That's quite possible how would I know if there is a few point in the library, I am still quite new to this, I have a control code switching the humidifier off at 90 and on at 88, will post my code shortly, I am using the adrfuit bme280.h libray

#include <DS3231.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
const byte RelayPin = 4;
DS3231  rtc(SDA, SCL);
Time ti;
LiquidCrystal_I2C lcd(0X27, 2, 1, 0, 4, 5, 6, 7);


Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);
//humidity control points
#define SETPOINT 90.0
#define DEADBAND 2.0

#define HUMIDIFIER (10) //instead of using 9 for pin 9 we will name it HUMIDIFIER

#define ON false
#define OFF true
#define FAN 9


void setup() 
  { rtc.begin();
  pinMode(RelayPin, OUTPUT);
  digitalWrite(RelayPin, LOW);
 
  
  lcd.begin(16, 2);                     // for 16x2 LCD module
  lcd.setBacklightPin(3, POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.setCursor(0, 0);
  lcd.print("T");
  lcd.setCursor(0, 1);
  lcd.print("RH");
  lcd.setCursor(8,0);
  lcd.print("FAN");
  Serial.begin(9600);
  Serial.println(F("BME280 test"));
  pinMode(FAN, OUTPUT);
  digitalWrite (FAN, OFF);
  pinMode(HUMIDIFIER, OUTPUT);
  digitalWrite (HUMIDIFIER, OFF);
 


  if (!bme.begin())
  {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
}
void SetRelayOnState(bool newOnState)
{
  static bool currentOnState = true;
  // Only print when the state changes
  if (newOnState == currentOnState)
    return; // Nothing to do
  currentOnState = newOnState;
  if (currentOnState)
  {
    digitalWrite(RelayPin, LOW);
    Serial.println("RELAY ON");
  }
  else
  {
    digitalWrite(RelayPin, HIGH);
    Serial.println("RELAY OFF");
  }
}


  void loop() {
    delay(3000);
   static int currentMinute = -1;
  ti = rtc.getTime();
  // Show time at the start of each new minute
  if (ti.min != currentMinute)
  {
    currentMinute = ti.min;
    Serial.print(ti.hour);
    Serial.print(" hour(s), ");
    Serial.print(ti.min);
    Serial.println(" minute(s)");
  }
  if (ti.min % 30 < 15)
  {
    // For the first half of every half hour, turn on the Relay
   { SetRelayOnState(true);
   lcd.setCursor(12,0);
   lcd.print("ON ");
   }
   
  }
  else
  {
    // For the second half of every half hour, turn off the Relay
   { SetRelayOnState(false);
   lcd.setCursor(12,0);
   lcd.print("OFF");
   }
  }
   





    //Move the cursor to the end of the word temp: and print the reading to 2 decimal places
    lcd.setCursor(2, 0);
    lcd.print(bme.readTemperature(), 2);
    //Move the cursor to the end of the word Humidity: and print the reading to 2 decimal places
    lcd.setCursor(3, 1);
    lcd.print(bme.readHumidity(), 2);



    //Now begin with the control logic
    if (digitalRead(HUMIDIFIER) == ON)

    {
      //If the humidifier is on, check to see if the humidity is above set point
      if (bme.readHumidity() > SETPOINT + DEADBAND)


        //we've reached the upper limit, so kill the humidifier
      { digitalWrite(HUMIDIFIER, OFF);
        digitalWrite(FAN, OFF);
      }
      }


    
    else
    
      // If the humidifier is off, check to see if humidity is below setpoint
      if (bme.readHumidity() < SETPOINT - DEADBAND)

        // We've reached the lower limit, so kiick on the humidifier
    {  { digitalWrite(HUMIDIFIER, ON);
        digitalWrite(FAN, ON); }
    }
  }

So I updated the libray now with the latest one and now it's not working at all

Most sensors of this type will not withstand condensing humidity , which is what I suspect is happening.
You could look at using a heated lambda ( car type) oxygen sensor , and measure the reduced oxygen levels caused by the water vapour .
It might help to explain the application, there may be other ways to solve the problem , the control differences you have in humidity are small and very temperature dependant - why not go for 100% for example ??

Ok so I grow gourmet mushrooms at home in a grow room and I need the humdity level to stay at around 90 percent, now when I was using the dht22 it would work for a few weeks before it would fail, however with this bme280 it's not even running a day,

Do you think a different sensor like the bme680 would be better as I believe the sensor is heard before it takes a reading

What method are you using to increase humidity? Your program turns on the humidifier at 88%, how long does it take to raise the humidity to 92% and turn off? Does the humidity stop increasing immediately, or keep rising to 100% and cause condensation on the sensor? Maybe your humidifier is too big for your enclosure.
EDIT: I've had good luck with SHT31:

I have a 10 disc fogger that pumps the mist into the room and it takes around 10 minutes to pick it up around 4 percent, I will check out that sensor thank you, and it rises to around 95 percent after it's off, however the bme stops reading as soon as the humidifier switches off

Mushroom_man:
however the bme stops reading as soon as the humidifier switches off

That sounds suspicious. Power spike perhaps. Do you get the same thing if you set the humidity threshold (quite a bit) lower?

A couple of thoughts:

I believe the humidity portion of the BME680 is the same as the BME280.

I have two BME280's I'm testing side by side. On an earlier test I put the sensors outside and while it was humid, one went to 100% (like you saw). I thought it might be the sensor needed precondiitoning, so I baked both at 125 °C for 2 hours, now they are in a 75% humid container. Have not finished the 75% "soak"

My application will be an outdoor monitor. I was planning on covering the BME280 with some gore like material that "should" let in the humidity but keep out water and dirt. I will be testing the effect of the material once the sensors seem to work reasonable consistent.

I am using the Tyler Glenn driver found on github. The Adafruit driver seems over complicated to me.

Not sure if any of this helps you.

John

wildbill:
That sounds suspicious. Power spike perhaps. Do you get the same thing if you set the humidity threshold (quite a bit) lower?

I have not tried it lower I will give it a bash, also I have noticed that the whole room fills with mist and the reaction time is quite slow, when I was using the dht22 the reaction time was way faster

In my experience the BME280 is a spectacularly good humidity sensor. There are two sources of error to watch out for...

  1. A teeny tiny drop if water covering the sensor hole will obviously prevent it sensing the air. Also water on the PCB will corrode the copper tracks and solder joints.

So never let it get wet.

  1. Most circuit boards you might use it on will heat up the sensor. So it will always be warmer than the surrounding air.

Since warm air has more capacity to hold water, the % humidity will be read as lower than the actual humidity in the surrounding air.

But point 2 helps with point 1.

The trick is to convert the "warmed" humidity to the actual humidity of the cooler air you want to measure. The amount of water in both air samples is the same.

MorganS:
In my experience the BME280 is a spectacularly good humidity sensor. There are two sources of error to watch out for...

  1. A teeny tiny drop if water covering the sensor hole will obviously prevent it sensing the air. Also water on the PCB will corrode the copper tracks and solder joints.

So never let it get wet.

  1. Most circuit boards you might use it on will heat up the sensor. So it will always be warmer than the surrounding air.

Since warm air has more capacity to hold water, the % humidity will be read as lower than the actual humidity in the surrounding air.

But point 2 helps with point 1.

The trick is to convert the "warmed" humidity to the actual humidity of the cooler air you want to measure. The amount of water in both air samples is the same.

I get both points, however I have zero idea on how to solve it, any help will be greatly appreciated

Humidity can be absolute or relative. Relative is always %. It is the most common measurement because that is closest to the way that humans percieve humidity. Warm air at 40% humidity contains many times more water than cold air at 90% humidity but 90% feels wetter.

Absolute humidity can be measured as grams of water per liter of air or a dozen other units. One interesting measurement is "dew point" which is the temperature that you have to cool the air to for it to start making condensation.

The formulas to convert between the different measurements are not simple, but not difficult either.

If you take two air samples with the same humility and then heat one of them then the relative humidity of the warm one will be lower. But you did not add or remove water so the absolute humidity must still be the same. If you know the temperature of both samples you can calculate the % humidity for the cold one.

So let the BME280 get warm. Add another temperature sensor like a DS18B20 in the area where you actually want to know the humidity. The Arduino can do all the calculation.

hi guys, I am seriously battling with my project, it could be dew point that's causing the issue but I have zero idea on how to fix it, I have tried multiple librarys as well and all have the same result, its a mushroom grow room and needs to be kept at a humidity of 90 percent with a humidifier controlled by the ardrino uno, it stops reading at random times, sometimes at 70 % other times at 90%

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include "BlueDot_BME280_TSL2591.h"
BlueDot_BME280_TSL2591 bme280;
LiquidCrystal_I2C lcd(0X27, 2, 1, 0, 4, 5, 6, 7);
#define HUMIDIFIER 4
#define SETPOINT 90.0
#define DEADBAND 2.0
#define ON false
#define OFF true
void setup() {
  Serial.begin(9600);
  pinMode(HUMIDIFIER, OUTPUT);
  lcd.begin(16, 2);                     // for 16x2 LCD module
  lcd.setBacklightPin(3, POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.setCursor(0, 0);
  lcd.print("Temp");
  lcd.setCursor(0, 1);
  lcd.print("Humidity");
  bme280.parameter.I2CAddress = 0x77;
  bme280.parameter.sensorMode = 0b11;
  bme280.parameter.IIRfilter = 0b100;
  bme280.parameter.humidOversampling = 0b101;
  bme280.parameter.tempOversampling = 0b101;
  bme280.parameter.tempOutsideCelsius = 15;
  if (bme280.init_BME280() != 0x60)
  {
    Serial.println(F("Ops! BME280 could not be found!"));
  }
  else
  {
    Serial.println(F("BME280 detected!"));
  }
  Serial.println();
  Serial.println();
}
void loop()
{ delay(1000);
  lcd.setCursor(11, 0);
  lcd.print(bme280.readTempC(), 2);
  //Move the cursor to the end of the word Humidity: and print the reading to 2 decimal places
  lcd.setCursor(11, 1);
  lcd.print(bme280.readHumidity(), 2);


  Serial.print(F("Temperature in Celsius:\t\t"));
  Serial.println(bme280.readTempC());

  Serial.print(F("Humidity in %:\t\t\t"));
  Serial.println(bme280.readHumidity());

  if (digitalRead(HUMIDIFIER) == OFF)
  {
    if (bme280.readHumidity() > SETPOINT + DEADBAND)
    {
      digitalWrite(HUMIDIFIER, ON);
    }
  }
  else
  {
    if (bme280.readHumidity() < SETPOINT - DEADBAND)
      digitalWrite(HUMIDIFIER, OFF);
  }
}

I have the same problem with BME280 sensors randomly returning NaN (not a number) or zero when reading data so I check for this

  scratchfloat = bme.readHumidity();
  if(isnan(scratchfloat) || (scratchfloat == 0))
  {
    scratchfloat = humidity;                                // Just use last value instead
    sendStatus(LoRaDevice " Humidity Reboot.");
    resetNeeded = true;
  }
  humidity += scratchfloat;
  humidity = humidity / 2;
  
  if(resetNeeded)
  {
    BME280_Reset();
    pktNumber = 222;
    //sendStatus(LoRaDevice " Reboot.");
    //delay(1000);
    //errLoop();
  }

and reset the BME280 if this happens

void BME280_Reset()
{
  if(DEBUG) Serial.println(F("BME280 Reset"));
  Wire.beginTransmission(BME280_I2C_ADDR);
  Wire.write((uint8_t)BME280_REGISTER_SOFTRESET);
  Wire.write((uint8_t)0xB6);
  Wire.endTransmission();
  delay(200);
  Wire.beginTransmission(BME280_I2C_ADDR);
  Wire.write((uint8_t)BME280_REGISTER_SOFTRESET);
  Wire.write((uint8_t)0xB6);
  Wire.endTransmission();
  delay(1000);
}

The readings could fail within hours of a reset or maybe last days/weeks before failing but since implementing the reset I have not seen any problems.
I use the Adafruit library so you will need to tweak things to suit the library you use.

Riva:
I have the same problem with BME280 sensors randomly returning NaN (not a number) or zero when reading data so I check for this

  scratchfloat = bme.readHumidity();

if(isnan(scratchfloat) || (scratchfloat == 0))
  {
    scratchfloat = humidity;                                // Just use last value instead
    sendStatus(LoRaDevice " Humidity Reboot.");
    resetNeeded = true;
  }
  humidity += scratchfloat;
  humidity = humidity / 2;
 
  if(resetNeeded)
  {
    BME280_Reset();
    pktNumber = 222;
    //sendStatus(LoRaDevice " Reboot.");
    //delay(1000);
    //errLoop();
  }



and reset the BME280 if this happens


void BME280_Reset()
{
  if(DEBUG) Serial.println(F("BME280 Reset"));
  Wire.beginTransmission(BME280_I2C_ADDR);
  Wire.write((uint8_t)BME280_REGISTER_SOFTRESET);
  Wire.write((uint8_t)0xB6);
  Wire.endTransmission();
  delay(200);
  Wire.beginTransmission(BME280_I2C_ADDR);
  Wire.write((uint8_t)BME280_REGISTER_SOFTRESET);
  Wire.write((uint8_t)0xB6);
  Wire.endTransmission();
  delay(1000);
}



The readings could fail within hours of a reset or maybe last days/weeks before failing but since implementing the reset I have not seen any problems.
I use the Adafruit library so you will need to tweak things to suit the library you use.

you are a star I will try it thank you