# ADC Using the MPX4115A Pressure Sensor

## Understanding the MPX4115A

The Motorola MPX4115A is a atmospheric pressure sensor powered by 5V and delivers and output from ~0.25V to ~4.75V based on the pressure detected at room temperature (25C). As the pressure rises, so will the output of the sensor. ~0.25V represents <15 kPa pressure relative to a vacuum and ~4.75V represents >115 kPa. For example, 1 atmosphere of pressure at sea level is equal to 101,325 Pa or 101 kPa. Notice the approximate voltages given. See the graph below.

There is a transfer function below for this graph:

• Vout = Vs* (.009*P-.095) ± Error
• Vs = 5.1 volts
• P = pressure in kiloPascals
• Error = ±1.5 (kPa)

## Connect the sensor

The sensor contains 6 pins, however only 3 will be used:

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

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

## Convert ADC Value to a Pressure 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 pressure in kiloPascals.

``` 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.25V and the maximum is ~4.75V. Therefore, the minimum digital binary number from an ADC conversion should be 51 and the maximum number should be 972. Knowing this information, the following calculations are done in the PIC to linearly convert any number between 51 and 972 to the appropriate pressure between 15 and 115, respectively.

Luckily, the sensor’s output is extremely linear. Using the equation of a line, ideally, the value of `y`> should be 15 when 51 is stored in `xvalue`.

### 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/921 * xvalue) + 10;
```

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

``` 9:  long 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 97200 making a `long int` datatype more than enough.

```23:  z = (100 * xvalue);
```

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

```23:  z = (100 * xvalue);
24:  y = z/921;
```

```23:  z = (100 * xvalue);
24:  y = z/921 + 10;
```

## Final Code

Finally, the equation is complete. When `xvalue` is 51, `y` equals 15. When `xvalue` is 972, `y` equals 115. `y` now represents the pressure value in kiloPascals. 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:       long 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: