Table of Contents

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.

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

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)

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.

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> 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.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`

.

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;

Lastly, add 10 to compensate for the adjustment of the line.

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

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> 3: #include <adc.h> 4: 5: void main() 6: { 7: 8: int xvalue = 0; 9: long 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); // calculations convert ADC value to pressure value in kiloPascals - multiplication 24: y = z/921 + 10; // calculations convert ADC value to pressure value in kiloPascals - division and addition 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 15 and 115.