# 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%.

## Connect the sensor

The sensor contains 3 pins:

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

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>
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);
15:
18:
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>
4:
5:  void main()
6:  {
7:
8:       int xvalue = 0;
9:       unsigned int z = 0;
10:       int y = 0;
11:       char xvalueASCII = 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);
18: