PIC16F877A & MPL3115A2: Precision Altimeter Integration Guide

by Marwen Maghrebi

In this article, we’ll explore how to integrate the MPL3115A2 sensor with the PIC16F877A microcontroller. This combination enables precise altitude and pressure measurements, ideal for environmental sensing projects.

Key features of the MPL3115A2 sensor project, including pressure, altitude, and temperature measurement capabilities.

Things used in this project

Software apps and online services:

1- MPLAB

2- Proteus 8

Interfacing PIC16F877A with MPL3115A2 Sensor for Accurate Pressure and Altitude Measurement

In this project, we will demonstrate how to interface the PIC16F877A microcontroller with the MPL3115A2 sensor, enabling accurate pressure and altitude readings for various environmental applications. For instance, similar projects like the PIC16F877A I2C BMP180  Sensor showcase the versatility of such integration 

MPL3115A2 Overview

The MPL3115A2, a compact piezoresistive pressure sensor from NXP Semiconductors, provides precise altitude and pressure measurements. Specifically, it is designed for applications such as weather stations, GPS enhancement, and indoor navigation. Additionally, the sensor integrates a high-resolution ADC (Analog-to-Digital Converter) and an I²C interface, making it easy to interface with microcontrollers and other digital systems. Notably, the MPL3115A2 measures pressure from 20 kPa to 110 kPa, covering the full range of atmospheric pressure at different altitudes.

Furthermore, the device is housed in a small, low-profile package, making it suitable for space-constrained applications. It also operates over a wide temperature range (-40°C to +85°C) and is designed for low power consumption, making it ideal for battery-powered devices.”

Overview of the MPL3115A2 sensor, showcasing its compact design, pressure range, and I²C interface for microcontroller integration.

MPL3115A2 Features and Applications

Key Features:

  • Pressure Measurement Range: 20 kPa to 110 kPa (covers all altitudes on Earth).
  • Altitude Measurement: Provides accurate altitude data with a resolution of up to 0.3 meters.
  • Temperature Measurement: Integrated temperature sensor with ±1°C accuracy.
  • High Resolution: 24-bit ADC for precise pressure and altitude readings.
  • Low Power Consumption: Optimized for battery-powered applications.
  • I²C Interface: Simple digital communication interface.
  • FIFO (First In, First Out) Buffer: Stores up to 32 samples for efficient data handling.
  • Programmable Interrupts: Configurable for specific altitude, pressure, or temperature thresholds.
  • Operating Voltage: 1.95V to 3.6V, compatible with most microcontrollers.

Applications:

  • Weather Stations: Accurate barometric pressure measurement for weather forecasting.
  • Altitude Tracking: Used in drones, UAVs, and outdoor sports devices for altitude monitoring.
  • Indoor Navigation: Enhances indoor positioning systems by providing altitude data.
  • GPS Enhancement: Improves GPS accuracy by providing altitude corrections.
  • Health and Fitness: Altitude and pressure data for fitness tracking devices.
  • Industrial Control: Pressure monitoring in industrial environments.

MPL3115A2 Block Diagram

The MPL3115A2 consists of several key components that work together to provide accurate pressure, altitude, and temperature measurements. To illustrate this, a simplified block diagram of the sensor is provided below.

Block diagram of the MPL3115A2 sensor, illustrating its pressure sensor, temperature sensor, 24-bit ADC, control logic, and I²C interface.

Explanation:

  • Pressure Sensor: Measures absolute pressure using a piezoresistive sensing element.
  • Temperature Sensor: Provides temperature compensation for pressure readings and standalone temperature data.
  • 24-bit ADC: Converts analog pressure and temperature signals into high-resolution digital data.
  • Control Logic: Manages data acquisition, FIFO buffer, and interrupt generation.
  • I²C Interface: Facilitates communication with external microcontrollers or proces

Key Design Considerations and Advanced Features

Calibration and Compensation:

The MPL3115A2 includes built-in compensation algorithms to ensure accurate readings across a wide range of temperatures and pressures. Moreover, the sensor automatically compensates for temperature variations, which is critical for maintaining accuracy in real-world applications.

FIFO Buffer:

Another key feature of the MPL3115A2 is its FIFO buffer. This buffer allows the sensor to store up to 32 pressure or altitude samples, reducing the need for frequent communication with the host microcontroller. As a result, it is particularly useful in low-power applications where the microcontroller may be in sleep mode for extended periods.”

Interrupts:

The sensor supports multiple interrupt modes, including data-ready interrupts, pressure/altitude threshold interrupts, and temperature threshold interrupts. These interrupts can be configured to wake up a microcontroller or trigger specific actions, enhancing system efficiency.

Power Modes:

The MPL3115A2 offers several power modes to optimize energy consumption:

  • Active Mode: Full operation with continuous data acquisition.
  • Standby Mode: Low-power state with minimal current draw.
  • One-Shot Mode: The sensor takes a single measurement and then returns to standby mode, ideal for battery-powered devices.

I²C Address:

The default I²C address for the MPL3115A2 is 0x60; however, it can be changed to 0x61 by pulling the SDO pin high. This flexibility allows multiple sensors to be used on the same I²C bus.

Data Output:

The sensor outputs pressure, altitude, and temperature data in a 24-bit format. Additionally, the data can be read directly from the I²C interface, while the FIFO buffer ensures efficient data retrieval.

Project: Interfacing MPL3115A2 Sensor with Microcontroller for Pressure, Altitude, and Temperature Monitoring

This project demonstrates how to interface the MPL3115A2 sensor with a microcontroller to measure atmospheric pressure, altitude, and temperature. Specifically, the sensor communicates with the microcontroller via the I²C protocol, while the measured data is sent over UART for real-time monitoring. Furthermore, the system is designed to be scalable, making it suitable for integration into various applications such as weather stations, altitude tracking, and environmental monitoring.

main Header File (main.h)

This file defines global settings and includes necessary libraries for the project, such as <stdio.h> and <stdbool.h>. Additionally, it sets the microcontroller’s clock frequency (_XTAL_FREQ) to 16 MHz.

// main.h
#ifndef MAIN_H
#define MAIN_H

#include <xc.h>
#include <stdlib.h> // For atoi function to convert text to integer
#include <stdbool.h>
#include <stdio.h>

#define _XTAL_FREQ             16000000

#endif

I2C Driver Header File (i2c.h)

This header file provides I²C communication functions, including initialization, start/stop conditions, and data read/write operations. Furthermore, it enables communication between the microcontroller and the MPL3115A2 sensor.

// I2C.h
#ifndef I2C_H
#define I2C_H
#include "main.h"
// Define constants
#define I2C_BaudRate           100000
#define SCL_D                  TRISC3
#define SDA_D                  TRISC4

// Function prototypes
void I2C_Master_Init(void);
void I2C_Master_Wait(void);
void I2C_Master_Start(void);
void I2C_Master_RepeatedStart(void);
void I2C_Master_Stop(void);
void I2C_ACK(void);
void I2C_NACK(void);
unsigned char I2C_Master_Write(unsigned char data);
unsigned char I2C_Read_Byte(void);

#endif

UART Driver Header File (uart.h)

This file defines UART communication functions for transmitting data. For instance, it includes functions for initializing UART, sending single bytes, and transmitting text strings, which developers use for debugging and data output.


//uart.h
#ifndef UART_H
#define UART_H
#include "main.h"

void UART_TX_Init(void);
uint8_t UART_TX_Empty(void);
void UART_Write(uint8_t data);
void UART_Write_Text(const char* text);

#endif // UART_H

MPL3115A2 Sensor Driver Header File (MPL3115A2.h)

This header file defines the MPL3115A2 sensor’s registers, control bits, and function prototypes. Moreover, it includes functions for reading/writing registers, initializing the sensor, and retrieving pressure, altitude, and temperature data.


#ifndef __MPL3115A2__
#define __MPL3115A2__

#include "main.h"
#include "i2c.h"

#define MPL3115A2_ADDRESS 0x60 ///< default I2C address 1100000

/** MPL3115A2 registers **/
enum {
    MPL3115A2_REGISTER_STATUS = 0x00,
    
    MPL3115A2_REGISTER_PRESSURE_MSB = 0x01,
    MPL3115A2__EGISTER_PRESSURE_CSB = 0x02,
    MPL3115A2_REGISTER_PRESSURE_LSB = 0x03,
    
    MPL3115A2_REGISTER_TEMP_MSB = 0x04,
    MPL3115A2_REGISTER_TEMP_LSB = 0x05,
    
    MPL3115A2_REGISTER_DR_STATUS = 0x06,
    
    MPL3115A2_OUT_P_DELTA_MSB = 0x07,
    MPL3115A2_OUT_P_DELTA_CSB = 0x08,
    MPL3115A2_OUT_P_DELTA_LSB = 0x09,
    
    MPL3115A2_OUT_T_DELTA_MSB = 0x0A,
    MPL3115A2_OUT_T_DELTA_LSB = 0x0B,
    
    MPL3115A2_WHOAMI = 0x0C,
    
    MPL3115A2_BAR_IN_MSB = 0x14,
    MPL3115A2_BAR_IN_LSB = 0x15,
    
    MPL3115A2_OFF_H = 0x2D,
    };
    
/** MPL3115A2 status register bits **/
enum {
    MPL3115A2_REGISTER_STATUS_TDR = 0x02,
    MPL3115A2_REGISTER_STATUS_PDR = 0x04,
    MPL3115A2_REGISTER_STATUS_PTDR = 0x08,
    };

/** MPL3115A2 PT DATA register bits **/
enum {
    MPL3115A2_PT_DATA_CFG = 0x13,
    MPL3115A2_PT_DATA_CFG_TDEFE = 0x01,
    MPL3115A2_PT_DATA_CFG_PDEFE = 0x02,
    MPL3115A2_PT_DATA_CFG_DREM = 0x04,
    };

/** MPL3115A2 control registers **/
enum {
    MPL3115A2_CTRL_REG1 = 0x26,
    MPL3115A2_CTRL_REG2 = 0x27,
    MPL3115A2_CTRL_REG3 = 0x28,
    MPL3115A2_CTRL_REG4 = 0x29,
    MPL3115A2_CTRL_REG5 = 0x2A,
    };

/** MPL3115A2 control register bits **/
enum {
    MPL3115A2_CTRL_REG1_SBYB = 0x01,
    MPL3115A2_CTRL_REG1_OST = 0x02,
    MPL3115A2_CTRL_REG1_RST = 0x04,
    MPL3115A2_CTRL_REG1_RAW = 0x40,
    MPL3115A2_CTRL_REG1_ALT = 0x80,
    MPL3115A2_CTRL_REG1_BAR = 0x00,
    };
                    
/** MPL3115A2 oversample values **/
enum {
    MPL3115A2_CTRL_REG1_OS1 = 0x00,
    MPL3115A2_CTRL_REG1_OS2 = 0x08,
    MPL3115A2_CTRL_REG1_OS4 = 0x10,
    MPL3115A2_CTRL_REG1_OS8 = 0x18,
    MPL3115A2_CTRL_REG1_OS16 = 0x20,
    MPL3115A2_CTRL_REG1_OS32 = 0x28,
    MPL3115A2_CTRL_REG1_OS64 = 0x30,
    MPL3115A2_CTRL_REG1_OS128 = 0x38,
};
                        
/** MPL3115A2 measurement modes **/
typedef enum {
    MPL3115A2_BAROMETER = 0,
    MPL3115A2_ALTIMETER,
} mpl3115a2_mode_t;

/** MPL3115A2 measurement types **/
typedef enum {
    MPL3115A2_PRESSURE,
    MPL3115A2_ALTITUDE,
    MPL3115A2_TEMPERATURE,
} mpl3115a2_meas_t;

#define MPL3115A2_REGISTER_STARTCONVERSION 0x12 ///< start conversion

// Function prototypes
uint8_t MPL3115A2_ReadRegister(uint8_t reg);
void MPL3115A2_WriteRegister(uint8_t reg, uint8_t value);
bool MPL3115A2_Init(void);
void MPL3115A2_SetMode(mpl3115a2_mode_t mode);
void MPL3115A2_StartOneShot(void);
bool MPL3115A2_ConversionComplete(void) ;
float MPL3115A2_GetLastConversionResults(mpl3115a2_meas_t value);

float MPL3115A2_GetPressure(void);
float MPL3115A2_GetAltitude(void);
float MPL3115A2_GetTemperature(void);

int8_t MPL3115A2_GetAltitudeOffset(void);
void MPL3115A2_SetSeaPressure(float SLP);
void MPL3115A2_SetAltitudeOffset(int8_t offset);

// Data structure and variables
typedef union {
    struct {
        uint8_t SBYB : 1;
        uint8_t OST : 1;
        uint8_t RST : 1;
        uint8_t OS : 3;
        uint8_t RAW : 1;
        uint8_t ALT : 1;
        } bit;
    uint8_t reg;
} ctrl_reg1;

ctrl_reg1 _ctrl_reg1;
mpl3115a2_mode_t currentMode;
                                                        
#endif
                                                        
                                                        

Main Application File (main.c)

The main application initializes UART and the MPL3115A2 sensor. Then, it continuously reads and transmits pressure, altitude, and temperature data over UART. Finally, the system formats and displays the data in real time for monitoring.

#include "main.h"
#include "uart.h"
#include "Mpl3115a2.h"

void main(void) {
    // Initialize UART for debugging
    UART_TX_Init();
    
    UART_Write_Text("MPL3115A2 test!\n\r");
    // Initialize the MPL3115A2 sensor
    if (!MPL3115A2_Init()) {
        UART_Write_Text("Could not find sensor. Check wiring.!\n\r");
        while (1); // Infinite loop to halt execution
        }
    
    // Set sea level pressure for accurate altitude measurement
    MPL3115A2_SetSeaPressure(1013.26);
    
    // Main loop
    while (1) {
        // Variables to store sensor data
        float pressure_hpa = MPL3115A2_GetPressure();
        float pressure_pa = pressure_hpa * 100;
        float altitude = MPL3115A2_GetAltitude();
        float temperature = MPL3115A2_GetTemperature();
        
        UART_Write_Text("pressure = ");
        char pressureText[16];
        sprintf(pressureText, "%.2f hPa\n\r", pressure_pa);
        UART_Write_Text(pressureText);
        
        UART_Write_Text("altitude = ");
        char altitudeText[16];
        sprintf(altitudeText, "%.2f m\n\r", altitude);
        UART_Write_Text(altitudeText);
        
        UART_Write_Text("temperature = ");
        char temperatureText[16];
        sprintf(temperatureText, "%.2f C\n\r", temperature);
        UART_Write_Text(temperatureText);
        
        // Delay before the next reading
        __delay_ms(250);
        }
    }

Proteus Configuration :

  • Open Proteus & Create New Project and click next
  • Click on Pick Device
  • Search for PIC16F877A& MPL3115A2& RESISTOR
  • Click on Virtual Instruments Mode then choose I2C DEBUGGER & TERMINAL
  • Click on Terminal Mode then choose (DEFAULT & POWER &GROUND)
  • finally make the circuit below and start the simulation
Proteus 8 simulation circuit design for the MPL3115A2 sensor project, demonstrating microcontroller integration and sensor connectivity.

That’s all!

If you have any questions or suggestions don’t hesitate to leave a comment below

You Might Also Like

1 comment

PIC16F877A I2C BMP180 Temperature and Pressure Sensor - The Embedded Things January 6, 2025 - 5:59 pm

[…] In this project, we will explore how to interface the PIC16F877A microcontroller with the BMP180 sensor for precise temperature and pressure measurement. For similar projects, check out our “PIC16F877A I2C MPL3115A2 Sensor Interface.” […]

Reply

Leave a Comment


Are you sure want to unlock this post?
Unlock left : 0
Are you sure want to cancel subscription?
-
00:00
00:00
Update Required Flash plugin
-
00:00
00:00