Go Down

Topic: Using an HS1101 humidity sensor (Read 16178 times) previous topic - next topic

robtillaart

Quote
just worked? Where's the fun in that?

Once and a while in the future you will wish for such "luck" ;)

The fun is now you can think of adding new functionalities, actions to be taken at certain humidity levels (motors valve, airco's etc)  , logging the levels and analyse them day vs night (add an RTC!!) ... There is always fun around the corner !

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

dpotthast

(using UNO)
Got this circuit working with code below.  Used a storebought humidity gauge to calibrate, according to Parallax datasheet, the function is linear.  Could have tried to calibrate using the result++, but I found the micros() method gave me better results.  Is this off base?  i am a newb.

Regardless, using a 2M pull down resistor, I get spot on humidity readings using a script that averages mulitple readings of the capacitor decay time in microseconds and is calibrated using a slope of .1667 and offset of -67.00.   -- The averaging gives much more consistent readings than one-off reads.

don't make readDelay too small or it will affect the sensor readings.  An accurate read could take a few seconds if your sample size is large.

thoughts?  i am sure this script could be tidied up a bit... would love feedback, I am just happy I am getting accurate reads!
Quote

int sensorPin1 = 4;

long result = 0;
unsigned long time1=0;
unsigned long time2=0;

long readingsPer=20.0;
long readDelay=200.0;

#define RH1(time) ((.1667*time)-67)

void setup()                    // run once, when the sketch starts
{

  Serial.begin(9600);
  Serial.println("start");      // a personal quirk
}
void loop()                     // run over and over again
{
  long H=RH1(evalHumid(readingsPer, sensorPin1));
  Serial.println("_____");
  Serial.println(H);
  Serial.println("_____");
  delay(1000);

}

long evalHumid(long samples, int sPin){
  long avgtime=0;
  for (int i=0;i<samples;i++){
    RCtime(sPin);
    avgtime+= decayTime(3);
  }
  avgtime=avgtime/samples; 
  return(avgtime);

}

long RCtime(int sensPin){
  long result = 0;
  pinMode(sensPin, OUTPUT);       // make pin OUTPUT
  digitalWrite(sensPin, HIGH);    // make pin HIGH to discharge capacitor - study the schematic
  delay(1);                       // wait a  ms to make sure cap is discharged

  pinMode(sensPin, INPUT);  // turn pin into an input and time till pin goes low
  digitalWrite(sensPin, LOW);// turn pullups off - or it won't work
  decayTime(1);  
  while(digitalRead(sensPin)){    // wait for pin to go low
    //result++;
  }
  decayTime(2);
  delay(readDelay);
  //return result;                   // report results   
}

long decayTime(int input){
  if (input==1){
    time1=micros();
  }
  if (input==2 ){
    time2=micros();
  }
  if (input==3){
    return (time2-time1);
  }
}


gmorchio

Hi there, I've been struggling with this sensor, I have used your code, but still I don't get the results done well. I'm comparing it to a SHT15 sensor.
My question is, how do you calculate the slope and the difference, in this case RH1(time) ((.1667*time)-67) ??
For example, for a 60% humidity, I get 242 as a reading. I have tried increasing the 67 to 247 to get the same results, but when I put it on a 75% humidity environment, the results goes to 108, which obviously is off the chart.

Please enlight my path!

Thanks
Greetings
Giovanni

sgargel


Hi there, I've been struggling with this sensor, I have used your code, but still I don't get the results done well....


Me too...

Code: [Select]

start
_____
226
_____
_____
225
_____
_____
224
_____


but... reading the device Documentation from here http://www.parallax.com/Portals/0/Downloads/docs/prod/sens/27920-HS1101-v1.0.pdf seems that getting the RH is simple as:

TDecay= 2.4•%RH + RHconstant

Code: [Select]

endTime=micros()-startTime;
endTime=endTime*10;
endTime=endTime-HS1101_RH_CONSTANT;
endTime=(endTime)/24;


also in this way readings seems meaningless... may be my hs1101 is broken? What happens if polarity is inverted?

pwillard

Quote
What happens if polarity is inverted


Hmm. I don't recall it having a polarity.  It is essentially a "humidity" variable non polarized capacitor.

hector915

This circuit is not  working for me =( , Can you please explain me  your circuit because I don't understand very well, you always have the hs1101 capacitor loaded by default if you connect the +5v directly ??...I implement this code

Code: [Select]
const float Vsupply=1024.0;
const int   analogHumidityPin = 4;

void setup()
{
Serial.begin(9600);
Serial.println("Configurando");      //Envio inicial

}

void loop()
{
Serial.println("Inicia Conversion");      //Envio inicial
float Vout = analogRead(analogHumidityPin);
float RelativeHumidity=(Vout/Vsupply)*100.0;
Serial.print((int)Vout);
Serial.print(" ");
Serial.print(RelativeHumidity);
Serial.println("%");
delay(500);
}


Thanks in advanced.

bomez

(using UNO)
Got this circuit working with code below.  Used a storebought humidity gauge to calibrate, according to Parallax datasheet, the function is linear.  Could have tried to calibrate using the result++, but I found the micros() method gave me better results.  Is this off base?  i am a newb.

 Regardless, using a 2M pull down resistor, I get spot on humidity readings using a script that averages mulitple readings of the capacitor decay time in microseconds and is calibrated using a slope of .1667 and offset of -67.00.   -- The averaging gives much more consistent readings than one-off reads.

don't make readDelay too small or it will affect the sensor readings.  An accurate read could take a few seconds if your sample size is large.

thoughts?  i am sure this script could be tidied up a bit... would love feedback, I am just happy I am getting accurate reads!
master, i want to ask. How make program to convert the serial data to RH and displays it at LCD??

milkay

Hi. Im having trouble with HS1101. I need it for my humidity controller. I just cant get the correct RH reading. I did every recommendations here but still cant get it. Do i need to replace the sensor? Any recommendations? Thanks :)

robtillaart

post your code and a picture/photo of your schema/wiring might help us to get started.

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

milkay

#24
Dec 26, 2014, 04:30 am Last Edit: Dec 26, 2014, 01:20 pm by robtillaart
Hi Sir Rob! Merry Christmas :)

Hardware setup:
HS1101 between common point and ground. 10m ohm resistor between charge pin and common point. 220 ohm resistor between discharge pin and common point. Then a wire between common point and analog pin (A/D input).

Code: [Select]

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#define analogPin      0         
#define chargePin      13         
#define dischargePin   10       
#define resistorValue  10000000.0F 
                         
unsigned long startTime;
unsigned long chargeTime;
unsigned long dischargeTime;
float microFarads;             
float picoFarads;
float RHslope = 0.24;
float  RHconstant = 121.69;
float relhum;
float rh;
void setup(){
  pinMode(chargePin, OUTPUT);   
  digitalWrite(chargePin, LOW); 
  lcd.begin(16, 2);
       
}

void loop(){
  float avgcap;
  float samplehum;
  float avghum;
 
    for(int i = 0 ; i < 300; i++){
      digitalWrite(chargePin, HIGH);  // set chargePin HIGH and capacitor charging
      startTime = micros();
 
      while(analogRead(analogPin) < 648){       // 647 is 63.2% of 1023, which corresponds to full-scale voltage
      }

      chargeTime = micros() - startTime;
 
      // convert milliseconds to seconds ( 10^-3 ) and Farads to microFarads ( 10^6 ),  net 10^3 (1000) 
      microFarads = ((float)chargeTime / resistorValue);
   

      picoFarads = microFarads * 1000000.0;      // multiply by 1000 to convert to nanoFarads (10^-9 Farads)

      samplecap = samplecap + picoFarads;
 
      /* dicharge the capacitor  */
      digitalWrite(chargePin, LOW);             // set charge pin to  LOW
      pinMode(dischargePin, OUTPUT);            // set discharge pin to output
      digitalWrite(dischargePin, LOW);          // set discharge pin LOW
 
      while(analogRead(analogPin) > 0){         // wait until capacitor is completely discharged
      }
      pinMode(dischargePin, INPUT);            // set discharge pin back to input
     
    }
    avgcap = samplecap/300;
   
    samplehum = ((avgcap - RHconstant)/RHslope);

  lcd.setCursor(0,0);
  lcd.print(avgcap);
  lcd.setCursor(0,1);
   lcd.print("RH: " );
  lcd.print(samplehum);
  lcd.print("%" );
 
  delay(5000);
}

Thanks :)

abeltomillo

I've got it.

Code: [Select]
int sensorPin = 4;              // 220 or 1k resistor connected to this pin
long result = 0;
void setup()                    // run once, when the sketch starts
{
  Serial.begin(9600);
}

void loop()                     // run over and over again
{
  Serial.println( RCtime(sensorPin) );
  delay(1000);
}

long RCtime(int sensPin){
  long result = 0;
  pinMode(sensPin, OUTPUT);       // make pin OUTPUT
  digitalWrite(sensPin, HIGH);    // make pin HIGH to discharge capacitor - study the schematic
  delay(1);                       // wait a  ms to make sure cap is discharged

  pinMode(sensPin, INPUT);        // turn pin into an input and time till pin goes low
  digitalWrite(sensPin, LOW);     // turn pullups off - or it won't work
  while(digitalRead(sensPin)){    // wait for pin to go low
     result++;
  }

  result = map (result, 0, 122, 100, 0);
 
  return result;

leolectric

#26
Feb 23, 2015, 09:28 pm Last Edit: Feb 25, 2015, 06:05 pm by leolectric
Hy to all,

I have just started playing with this stuff, and i got abeltomillo code to work.

 I'm building a fan control but i''m having a problem to switch something on.

I was thinking something like:

if  (result  > 40){ digitalWrite (led,HIGH);}

But this doesn't seem to work. Any suggestions? I can't find a variable to connect something with.

Also, @ abeltomillo,

What does this line do? :

 result = map (result, 0, 122, 100, 0);

mjmes

How accurately can you measure the humidity with a HS1101 and an Arduino?

According to the specifications of the HS1101 at https://www.parallax.com/sites/default/files/downloads/27920-Humidity-Sensor-Datasheet.pdf  the difference in capacity over 100% RH is about 40 pF (from ~163 to ~201 pF according to the typical HS1101 response curve) or approximately 0.4 pF per %RH. Measuring differences of this size accurately is a challenge.

When the capacitor (the HS1101) is charged the program sketch aims at measuring how long it takes to discharge the capacitor through the 1M resistor (see the attachment HS1101-a.jpeg  posted earlier, other diagrams show a 10M resistor). If no other resistances are involved, the range in seconds to discharge the HS1101 to ~37% of the original charge at 0% and at 100% RH is 40 micro-seconds or 0.4 micros per %RH. A description of the formulas can be found at:
https://en.wikipedia.org/wiki/RC  circuit ,
and a calculator for the RC time constant found at:
http://www.referencedesigner.com/rfcal/cal_05.php  .

A simple measurement of the resistance of the DUE PWM pins to ground is in the range of 3 to 6 M. The same measurements at a Mega 2560 gave a value in the range of 15 to16M. That built-in resistance shunts the capacitor as well, it influences (shortens) the discharge time.  A circuit diagram depicting this condition is attached.  The variability of this resistance of the Arduino PWM pins to ground makes precise calibration a necessity under any circumstance.

For a DUE the maximum sampling rate is around 3.4 MHz or ~0.3 micros per sample according to http://forum.arduino.cc/index.php?topic=252690.0 .  This is an indication of how accurately the discharge time can be measured if the start and finish voltages are always the same for every measurement.

In the example programs above the discharge time is measured by the program sketch lines such as:
Code: [Select]
while(digitalRead(sensPin)){    // wait for pin to go low
     result++;
  }


How accurate is the cutoff level measured for the digital read to go from high to low? If an ADC is used, the best accuracy could be as little as 1 / 4096 * 5V=1 milli Volt for the DUE and 4 mV for the Mega. To test how accurately a Due and a Mega can measure the time for a pin to go from high to low I connected a 300 pF capacitor shunted with a 1 M resistor to PWM pin 12 and ground for both the Due and the Mega. I used a minor variation of the program above to find the variability of the discharge time between the high and low setting:
 pinMode(sensPin, INPUT);        // turn pin into an input and time till pin goes low
 digitalWrite(sensPin, LOW);     // turn pullups off - or it won't work
 while(digitalRead(sensPin)){    // wait for pin to go low
    result++;   }

I repeated the tests using a 250 pF capacitor, covering the approximate range of capacitance of the HS1101.

I plotted the "result" counter, the plots for the Arduino Mega and the Due are attached. The results indicate that for indicative measurements the Due based system could perhaps work, the Mega based system does not give usable results. But neither system will yield reasonable humidity measurements if the HS1101 is used with this setup.

One could omit the external 1M resistor in parallel to the HS1101 so that the capacitor discharges against the Arduino internal resistance. The above tests were repeated without the 1M resistor. This did not work for the Due. For the Mega the plotted results are attached. The measurements took a lot longer. There is an obvious unexplained cyclicity in the measurements, which make this measurement system very questionable for serious measurements of humidity.

From the above experiments I concluded that it is not easily possible to obtain reliable humidity measurements using an Arduino Mega or Due and a HS1101 sensor. Even if long term averaging or regression techniques would be used serious and difficult calibrations would be necessary.

Any comments or suggestions to make an Arduino Mega or Due and a HS1101 sensor work?


Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy