Interfacing Barometer and Altimeter HP203B Pressure sensor with Arduino

In this article we are Interfacing a highly precise pressure sensor with Arduino. It is a package of Pressure, Altitude and Temperature sensor in a single chip. The pressure ranges from 300mbar to 1200mbar. The operating temperature varies from -40-degree Celsius to +85 degree Celsius. The data rate for pressure, altitude and temperature are 20 bits.

Application
– Sports watches
– Data Logger
– Project prototyping
– Weather station
– Navigation and map assistance

Advantages
The reading of pressure sensor is fast and precise. Using HP203B gives a combination of 2 sensors in a single chip with an I2C interface. The device stays in the sleep state unless it receives a proper command from the external MCU. This will help to achieve minimum power consumption.

Hardware Required
HP203B sensor
– Arduino of your choice
NCD I2C shield

Overview

The HP203B employs a MEMS pressure sensor with an I²C interface to provide accurate temperature, pressure or altitude data. The sensor pressure and temperature outputs are digitized by a high-resolution 24-bit ADC. The altitude value is calculated by a specific patented algorithm according to the pressure and temperature data. Data compensation is integrated internally to save the effort of the external host MCU system. The fully-compensated values can be read out via the I²C interface by external MCU. The uncompensated values can also be read out in case the user wants to perform their own data compensation. The devices can also compute the value of altitude according to the measured pressure and temperature. Furthermore, the device allows the user to set up the temperature, pressure and altitude threshold values for various events.

Pins and pull up resistors
It has 1 address pin and pull-up resistors on the device. It has only 2 pullup resister pins which are used by the SDA, SCL lines. The SDA,SCL pins need a pull-up resistor from the VDD line to the SDA pin which is used to transfer data in and out of the sensor.

Registers configuration and settings
The configuration depends on the OSR parameter sent to the device between 128 to 4096 count. The higher OSR will normally achieve higher measuring precision but consume more time and power. There are few commands to configure the device like reset command with address 0x06, read temperature and pressure with address 0x10, read temperature and pressure with address 0x11 and much more as explained below

  #define HP203B_DEFAULT_ADDRESS              (0x76)     // (0xEC)>>1
    #define HP203B_ADDRESS_UPDATED              (0x77)     // (0xEE)>>1

/**************************************************************************
    CONVERSION DELAY (in hp)
**************************************************************************/
    #define HP203B_CONVERSIONDELAY              (100)

/**************************************************************************
    COMMAND REGISTER
**************************************************************************/
    #define HP203B_CMD_SOFT_RESET               (0x06)
    #define HP203B_CMD_CONVERT                  (0x40)      // Convert the Sensor Output to the Digital Values
    #define HP203B_CMD_OSR_4096                 (0x00)      // Convert D1 (OSR=4096)
    #define HP203B_CMD_OSR_2048                 (0x04)      // OSR: 2048
    #define HP203B_CMD_OSR_1024                 (0x08)      // OSR: 1024
    #define HP203B_CMD_OSR_512                  (0x0C)      // OSR: 512
    #define HP203B_CMD_OSR_256                  (0x10)      // OSR: 256
    #define HP203B_CMD_OSR_128                  (0x14)      // OSR: 128
    #define HP203B_CMD_CHNL_PRESTEMP            (0x00)      // Sensor Pressure and Temperature Channel
    #define HP203B_CMD_CHNL_TEMP                (0x10)      // Sensor Temperature Channel
    #define HP203B_CMD_READ_PT                  (0x10)      // Read Temperature and Pressure Values
    #define HP203B_CMD_READ_AT                  (0x11)      // Read Temperature and Altitude Values
    #define HP203B_CMD_READ_P                   (0x30)      // Read Pressure Value Only
    #define HP203B_CMD_READ_A                   (0x31)      // Read Altitude Value Only
    #define HP203B_CMD_READ_T                   (0x32)      // Read Temperature Value Only
    #define HP203B_CMD_ANA_CAL                  (0x28)      // Re-Calibrate the Internal Analog Blocks
    #define HP203B_CMD_READ_REG                 (0x80)      // Read Out the Control Registers
    #define HP203B_CMD_WRITE_REG                (0xC0)      // Write Out the Control Registers

Sensor values
Functions like Measure_Pressure(), Measure_Temperature() and Measure_Altitude() are used to call from Arduino code to read sensor values and convert them into decimal form as you can see below

void HP203B::Measure_Pressure()
{
    // Set Up the Configuration for the Pressure Sensor
    uint8_t command =   HP203B_CMD_CONVERT           |  // Convert the Sensor Output to the Digital Values
                        HP203B_CMD_CHNL_PRESTEMP;       // Sensor Pressure and Temperature Channel
    
    command |= hp_osr;       // OSR
    
    // Write the configuration to the Pressure Sensor
    writeRegister(hp_i2cAddress, command);
    
    // Wait for the configuration to complete
    delay(hp_conversionDelay);
    
    // Reads the pressure value
    uint32_t pressure = readRegister(hp_i2cAddress, HP203B_CMD_READ_P);
    hp_sensorData.P = pressure /100.0;
}

/**************************************************************************/
/*
        Reads 20-bits from the destination register
        Reads the results for Digital Altitude Value
*/
/**************************************************************************/
void HP203B::Measure_Altitude()
{
    // Set Up the Configuration for the Altitude Sensor
    uint8_t command =   HP203B_CMD_CONVERT           |  // Convert the Sensor Output to the Digital Values
                        HP203B_CMD_CHNL_PRESTEMP;       // Sensor Pressure and Temperature Channel
    
    command |= hp_osr;       // OSR
    
    // Write the configuration to the Altitude Sensor
    writeRegister(hp_i2cAddress, command);
    
    // Wait for the configuration to complete
    delay(hp_conversionDelay);
    
    // Reads the Altitude value
    uint32_t altitude = readRegister(hp_i2cAddress, HP203B_CMD_READ_A);
    hp_sensorData.A = altitude /100.0;
}

/**************************************************************************/
/*
        Reads 20-bits from the destination register
        Reads the results for Digital Temperature Value
*/
/**************************************************************************/
void HP203B::Measure_Temperature()
{
    // Set Up the Configuration for the Temperature Sensor
    uint8_t command =   HP203B_CMD_CONVERT           |  // Convert the Sensor Output to the Digital Values
                        HP203B_CMD_CHNL_PRESTEMP;       // Sensor Pressure and Temperature Channel
    
    command |= hp_osr;       // OSR
    
    // Write the configuration to the Temperature Sensor
    writeRegister(hp_i2cAddress, command);
    
    // Wait for the configuration to complete
    delay(hp_conversionDelay);
    
    // Reads the Temperature value
    uint32_t temperature = readRegister(hp_i2cAddress, HP203B_CMD_READ_T);
    hp_sensorData.T = temperature /100.0;
}

Arduino code

#include 
#include 

HP203B hp;

double referencePressure;

void setup(void)
{
    Serial.begin(9600);

    // The address can be changed making the option of connecting multiple devices
    hp.getAddr_HP203B(HP203B_DEFAULT_ADDRESS);          // 0x76
    // hp.getAddr_HP203B(HP203B_ADDRESS_UPDATED);       // 0x77

    // The OSR command value to intiate the Pressure, Altitude and Temperature Conversions
    // can be changed via the following functions

    hp.setOSR(OSR_4096);            // OSR=4096
    // hp.setOSR(OSR_2048);         // OSR=2048
    // hp.setOSR(OSR_1024);         // OSR=1024
    // hp.setOSR(OSR_512);          // OSR=512
    // hp.setOSR(OSR_256);          // OSR=256
    // hp.setOSR(OSR_128);          // OSR=128

    hp.begin();

    delay(500);
}


void loop(void)
{
    byte error;
    int8_t address;

    address = hp.hp_i2cAddress;
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0)
    {

        Serial.println("Getting Pressure, Altitude and Temperature Readings from HP203B");
        Serial.println(" ");
        delay(300);

        // Read the Pressure, Altitude and Temperature
        hp.Measure_Sensor();

        // Output Data to Screen
        Serial.print("Digital Pressure Reading: ");
        Serial.print(hp.hp_sensorData.P);
        Serial.println(" hPa");
        Serial.print("Digital Altitude Reading: ");
        Serial.print(hp.hp_sensorData.A);
        Serial.println(" m");
        Serial.print("Temperature Reading in Celsius: ");
        Serial.print(hp.hp_sensorData.T);
        Serial.println(" °C");
        Serial.print("Temperature Reading in Fahrenheit: ");
        Serial.print(hp.hp_sensorData.T * 1.8 + 32);
        Serial.println(" °F");
        Serial.println(" ");
        Serial.println("        ***************************        ");
        Serial.println(" ");
    }
    else
    {
        Serial.println("HP203B Disconnected!");
        Serial.println(" ");
        Serial.println("        ************        ");
        Serial.println(" ");
    }

    delay(1000);
}

Test values

Reference
Datasheet
Library