Over the past six months or so I have been helping my daughter with a remote mounted sensors project to supplement the info from her weather station on her blog. Light and temperature sensing via the analogue ports has presented no problems (LDR and TMP36), but when it comes down to humidity sensing its a bit more complex.
Although you can buy some inexpensive resistive humidity sensors, these are not suitable for DC reading and have to be read using an AC waveform at a few KHz to avoid eventual damage to the devices.
There are ready made humidity sensor system which use SPI/I2C bus communication which give very good results, but looking at them,they tend to be a little pricey and the required source code is a bit beyond the level of Arduino coding Emily is happy with.
After a LOT of digging I came up with the Humirel HTF3223 Sensor.
Unlike other sensors, it provides an analogue value out which is linear with the relative humidity, but rather than a voltage it outputs a variable frequency square wave at between 8 and 10KHz.
So - how are we going to convert frequency to something useful??
Well there is a frequency counter lib available, but for a top frequency of around 10KHz its a bit like using a sledgehammer to crack a nut.
After a bit of googling I found several examples of using the pulsein function. The following code gives a very quick example of reading the frequency from the humidity module, and using a simple conversion formula, convert it to relative humidity.
/*
Humidity sensor test for HTF3223 humidity sensor
By G7NBP - Chris Williams
V0.0.1 28th - May 2011
The inexpensive HTF3223 sensor (ebay etc) provides good accuracy relative humidity
sensor readings (typically +/- 5%) and has a simple linear output.
Its output however is in the form of a variable frequency proportionate to the humidity.
The formula for convertion is RH = (9740/Freq)/18
Although it is possible to use the frequency library to collect the frequency, this
is somewhat overkill as the freq is not expected to be above 10KHz.
Instead the pulseIn function is used and frequency averaged over 4096 counts.
connect H pin on HTF3223 to digital pin 7
*/
const int hpin = 7; // the sensor pin
void setup() {
Serial.begin(9600);
pinMode(hpin, INPUT);
}
void loop() {
long sensorValue = getFrequency(hpin); // get the raw sensor frequency
long humidity = convertToRH(sensorValue); // convert it to RH%
Serial.print("S:");
Serial.print(sensorValue, DEC);
Serial.print(" H:");
Serial.print(humidity, DEC);
Serial.println("%");
delay(3000);
}
long getFrequency(int pin){
#define SAMPLES 4096
long freq = 0;
for(unsigned int j=0; j<SAMPLES; j++) freq+= 500000/pulseIn(pin, HIGH, 250000);
return freq / SAMPLES;
}
long convertToRH(long sensorValue){
long rh = (9740-sensorValue)/18;
return rh;
}
Although you can buy some inexpensive resistive humidity sensors, these are not suitable for DC reading and have to be read using an AC waveform at a few KHz to avoid eventual damage to the devices.
There are ready made humidity sensor system which use SPI/I2C bus communication which give very good results, but looking at them,they tend to be a little pricey and the required source code is a bit beyond the level of Arduino coding Emily is happy with.
After a LOT of digging I came up with the Humirel HTF3223 Sensor.
Unlike other sensors, it provides an analogue value out which is linear with the relative humidity, but rather than a voltage it outputs a variable frequency square wave at between 8 and 10KHz.
So - how are we going to convert frequency to something useful??
Well there is a frequency counter lib available, but for a top frequency of around 10KHz its a bit like using a sledgehammer to crack a nut.
After a bit of googling I found several examples of using the pulsein function. The following code gives a very quick example of reading the frequency from the humidity module, and using a simple conversion formula, convert it to relative humidity.
Humidity sensor test for HTF3223 humidity sensor
By G7NBP - Chris Williams
V0.0.1 28th - May 2011
The inexpensive HTF3223 sensor (ebay etc) provides good accuracy relative humidity
sensor readings (typically +/- 5%) and has a simple linear output.
Its output however is in the form of a variable frequency proportionate to the humidity.
The formula for convertion is RH = (9740/Freq)/18
Although it is possible to use the frequency library to collect the frequency, this
is somewhat overkill as the freq is not expected to be above 10KHz.
Instead the pulseIn function is used and frequency averaged over 4096 counts.
connect H pin on HTF3223 to digital pin 7
*/
const int hpin = 7; // the sensor pin
void setup() {
Serial.begin(9600);
pinMode(hpin, INPUT);
}
void loop() {
long sensorValue = getFrequency(hpin); // get the raw sensor frequency
long humidity = convertToRH(sensorValue); // convert it to RH%
Serial.print("S:");
Serial.print(sensorValue, DEC);
Serial.print(" H:");
Serial.print(humidity, DEC);
Serial.println("%");
delay(3000);
}
long getFrequency(int pin){
#define SAMPLES 4096
long freq = 0;
for(unsigned int j=0; j<SAMPLES; j++) freq+= 500000/pulseIn(pin, HIGH, 250000);
return freq / SAMPLES;
}
long convertToRH(long sensorValue){
long rh = (9740-sensorValue)/18;
return rh;
}
Edited: noticed that blogger was stripping the code after the < in the getFrequency function - corrected now.
ReplyDeleteThanks for the code this was a nice start for me.
ReplyDeleteBut don't you use the temperature coming from this sensor?
The modules we had didnt actually have the temperature sensor fitted so the pin for temp out was floating. The boards come either with or without the temnp sensor.
ReplyDeleteHowever, even if it did, we probably wouldnt have used it.
Reason?? - learning.
Emily is 13 and just starting out in electronics and software development. We started out with and arduino with a simple switch, reporting on/off via serial. Next we did reading a value from a potentiometer - with background understanding about the ratios involved in a potential divider circuit. Then we looked at LDRs for light levels - agin as a potential divider. Then we looked at actual voltages being measured along with discrete step size for the ADC and looked at the TMP36 sensor.
Each of the above steps was run via crocodile clips / EWB as a simulation, then tested on breadboard and finally as a circuit in its own right. Each stage was tested and incorperated into the project stage by stage over a period of about 12 months so the tmp36 circuit was already built and tested and working long before the Humirel was even on the bench
Only when we had got to the point fully understanding ADC representation of light and temperature values did we move on to more complex ways of representing a real world value as a variable input - in this case a variable frequency used to represent relative humididty.
Sometimes the best approach for learning is not the simplest - nor the best engineered.
Ive just realised I didnt include a link to Emily's sensor page in the post:
ReplyDeletehttp://myweatherblog.wordpress.com/livedata/ is the data and there is a bit more about the equipment http://myweatherblog.wordpress.com/equipment-4/
merci professeur
ReplyDelete