Strict Standards: Declaration of action_plugin_googleanalytics::register() should be compatible with DokuWiki_Action_Plugin::register($controller) in /home/ulcape/www/wiki.ulcape.org/lib/plugins/googleanalytics/action.php on line 6

Strict Standards: Declaration of action_plugin_stripslashes::register() should be compatible with DokuWiki_Action_Plugin::register($controller) in /home/ulcape/www/wiki.ulcape.org/lib/plugins/stripslashes/action.php on line 0
CAPE Wiki » tutorials:pic:pic18_adc_hih-3610
 
Strict Standards: Declaration of syntax_plugin_code::render() should be compatible with DokuWiki_Syntax_Plugin::render($format, &$renderer, $data) in /home/ulcape/www/wiki.ulcape.org/lib/plugins/code/syntax.php on line 41

ADC Using the HIH-3610 Humidity Sensor

Understanding the HIH-3610

The Honeywell HIH-3610 is a relative humidity sensor powered by 5V and delivers and output from 0.8V to 3.9V based on the humidity detected at room temperature (25C). As the humidity rises, so will the output of the sensor. 0.8V represents 0% relative humidity and 3.9V represents 100%.

Before continuing, be sure to read through the ADC tutorial.

HIH3610graph.jpg

Connect the sensor

The sensor contains 3 pins:

  • power (pin 3)
  • ground (pin 1)
  • output (pin 2)

HIH3610pinout.jpg

Using an ADC channel on the PIC, connect the output (pin 2) of the sensor to the input of an ADC channel. For our example, we will use channel 0. Connect the ground (pin 1) to the common ground and connect the power (pin 3) to 5V power.

Convert ADC Value to a Humidity Value

Using the ADC tutorial, the variable xvalue stores the binary number of the analog voltage of channel 0. After an ADC conversion occurs and the value is stored, some simple calculations can be made in order to produce the value of the relative humidity in percentage.

 1:  #include <p18cxxx.h>
 2:  #include <usart.h>
 3:  #include <adc.h>
 4:
 5:  void main()
 6:  {
 7:
 8:       int xvalue = 0;
 9:
10:       TRISC = 0x00;
11:       TRISA = 0xFF;
12:
13:       OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 129);
14:       OpenADC(ADC_FOSC_2 & ADC_RIGHT_JUST & ADC_8ANA_0REF, ADC_CH0 & ADC_INT_OFF);
15:
16:       ConvertADC();
17:       while(BusyADC());
18:
19:       xvalue = ReadADC();            // store binary value
20:
21:  }

Assuming room temperature, the minimum voltage produced by the sensor is 0.8V and the maximum is 3.9V. Therefore, the minimum digital binary number from an ADC conversion should be 164 and the maximum number should be 798. Knowing this information, the following calculations are done in the PIC to linearly convert any number between 165 and 798 to the appropriate percentage between 0 and 100, respectively.

Luckily, the sensor’s output is extremely linear. Using the equation of a line, ideally, the value of y should be 0 when 164 is stored in xvalue. A simple subtraction occurs first.

1:  y = xvalue - 164;

Now, the range of y is from 0 to 634. Given this new range, the slope can be calculated with a simple division.

Issues with Floats and Memory

In the case of using division, floating numbers can be an issue if there is no software support for floating point numbers. If there is no support, then a simple division such as x = 9/10; would produce 0 instead of a fractional number. However, there is a simple way to work around this.

23:  y = 100/634*(xvalue - 164);

Normally, the above calculation would be fine, however, if the division of 634 occurs before the multiplication 100, then the answer will be 0. By separating the equation into smaller portions, we can perform a proper division leading to a more accurate answer. Begin by initializing z as an unsigned int, giving a memory range of 16 bits.

 9:  unsigned int z = 0;

By performing the multiplication first, we can have a certain amount of precision using division exclusively in the integer domain. The largest number possible is 63400 making a unsigned int datatype more than enough.

23:  z = 100*(xvalue - 164);

Then, z can be divided by 634 and stored in y.

23:  z = 100*(xvalue - 164);
24:  y = z/634;

Final Code

Finally, the equation is complete. When xvalue is 164, y equals 0. When xvalue is 798, y equals 100. y now represents the humidity value in percentage. The value can be printed to screen using the putsUSART() function, itoa function and the xvalueASCII variable.

 1:  #include <p18cxxx.h>
 2:  #include <usart.h>
 3:  #include <adc.h>
 4:
 5:  void main()
 6:  {
 7:
 8:       int xvalue = 0;
 9:       unsigned int z = 0;
10:       int y = 0;
11:       char xvalueASCII[5] = 0;
12:
13:       TRISC = 0x00;
14:       TRISA = 0xFF;
15:
16:       OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 129);
17:       OpenADC(ADC_FOSC_2 & ADC_RIGHT_JUST & ADC_8ANA_0REF, ADC_CH0 & ADC_INT_OFF);
18:
19:       ConvertADC();
20:       while(BusyADC());
21:
22:       xvalue = ReadADC();            // store binary value
23:       z = 100*(xvalue - 164);           // calculations convert ADC value to humidity value in percentage - subtraction and then multiplication
24:       y = z/634;                        // calculations convert ADC value to humidity value in percentage - division
25:       itoa(y, xvalueASCII);          // convert binary value to a series of printable characters
26:       putsUSART( xvalueASCII );      // print the string of printable characters
27:
28:  }

The output of the string should be a number between 0 and 100.

duty free alcohol airport duty free cigs uk buy duty free cuban cigars where to buy cosmetics duty free fragrances buy tobacco duty free