An example on how to read temperature, pressure and altitude from HP206C barometer sensor.

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
ElectronicsSanta
Date:
Wed Aug 02 12:18:49 2017 +0000
Commit message:
first commit

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 0a071ea90726 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Aug 02 12:18:49 2017 +0000
@@ -0,0 +1,219 @@
+#include "mbed.h"
+
+#define HP20X_SOFT_RST        0x06
+#define HP20X_WR_CONVERT_CMD  0x40
+#define HP20X_CONVERT_OSR4096 0 << 2
+#define HP20X_CONVERT_OSR2048 1 << 2
+#define HP20X_CONVERT_OSR1024 2 << 2
+#define HP20X_CONVERT_OSR512  3 << 2
+#define HP20X_CONVERT_OSR256  4 << 2
+#define HP20X_CONVERT_OSR128  5 << 2
+
+#define HP20X_READ_P          0x30 // read_p command
+#define HP20X_READ_A          0x31 // read_a command
+#define HP20X_READ_T          0x32 // read_t command
+#define HP20X_READ_PT         0x10 // read_pt command
+#define HP20X_READ_AT         0x11 // read_at command
+#define HP20X_READ_CAL        0X28 // RE-CAL ANALOG
+
+#define HP20X_WR_REG_MODE 0xC0
+#define HP20X_RD_REG_MODE 0x80
+
+#define HP20X_ANA_CAL  0x28 // recalibrate analog internal circuitries
+
+#define HP20X_OK_DEV   0X80 // successfully initialized
+#define HP20X_REG_PARA 0X0F // status register
+
+#define I2C_BAROMETER_ADDRESS 0x76 << 1 // 0xEC
+
+#define OSR_CFG HP20X_CONVERT_OSR2048
+
+Serial serial(SERIAL_TX, SERIAL_RX);
+I2C i2c(I2C_SDA, I2C_SCL); // PB_9, PB_8
+
+float temperature = 0.0f;
+float pressure = 0.0f;
+float altitude = 0.0f;
+bool baro_found = false;
+
+typedef enum {
+    HP20X_READ_TEMP,
+    HP20X_READ_PRES
+} barometerReadingType;
+
+// send a register reading command
+unsigned char readRegister(unsigned char reg) {
+    char i2cBuffer[1];
+    i2cBuffer[0] = (reg | HP20X_RD_REG_MODE);
+    i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
+
+    // read the data
+    i2c.read(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
+
+    return i2cBuffer[0];
+}
+
+// send a register writing command
+void writeRegister(unsigned char reg, unsigned char data) {
+    char i2cBuffer[1];
+    i2cBuffer[0] = (reg | HP20X_WR_REG_MODE);
+    i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
+    i2cBuffer[0] = data;
+    i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
+}
+
+void enableCompensation() {
+    writeRegister(HP20X_REG_PARA, 0x01);
+}
+
+void disableCompensation() {
+    writeRegister(HP20X_REG_PARA, 0x00);
+}
+
+void softReset() {
+    char i2cBuffer[1];
+    i2cBuffer[0] = HP20X_SOFT_RST;
+    i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
+}
+
+void recalibrate() {
+    char i2cBuffer[1];
+    i2cBuffer[0] = HP20X_ANA_CAL;
+    i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
+}
+
+uint32_t readData3Bytes() {
+    uint32_t tmpData;
+    char tmpArray[3] = {0};
+
+    // request 3 bytes from device
+    i2c.read(I2C_BAROMETER_ADDRESS, tmpArray, 3);
+
+    // MSB
+    tmpData = tmpArray[0] << 16 | tmpArray[1] << 8 | tmpArray[2];
+
+    if(tmpData & 0x800000) {
+        tmpData |= 0xff000000;
+    }
+
+    return tmpData;
+}
+
+uint32_t *readData6Bytes() {
+    static uint32_t tmpData[2];
+    char tmpArray[6] = {0};
+
+    // request 6 bytes from device
+    i2c.read(I2C_BAROMETER_ADDRESS, tmpArray, 6);
+
+    // MSB
+    tmpData[0] = tmpArray[0] << 16 | tmpArray[1] << 8 | tmpArray[2]; // temperature
+    tmpData[1] = tmpArray[3] << 16 | tmpArray[4] << 8 | tmpArray[5]; // pressure
+
+    if(tmpData[0] & 0x800000) {
+        tmpData[0] |= 0xff000000;
+    }
+    if(tmpData[1] & 0x800000) {
+        tmpData[1] |= 0xff000000;
+    }
+
+    return tmpData;
+}
+
+void readTemperatureAndPressureStep1() {
+    char i2cBuffer[2];
+    i2cBuffer[0] = HP20X_WR_CONVERT_CMD | OSR_CFG;
+    i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1); // ADC convert
+}
+
+void readTemperatureAndPressureStep2() {
+    char i2cBuffer[1];
+
+    i2cBuffer[0] = HP20X_READ_PT;
+    i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
+
+    uint32_t *p = readData6Bytes();
+    temperature = ((double)p[0] / 100.0f);
+    pressure = ((double)p[1] / 100.0f);
+}
+
+void readAltitude() {
+    char i2cBuffer[1];
+    i2cBuffer[0] = HP20X_READ_A;
+    i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
+
+    altitude = ((double)readData3Bytes() / 100.0f);
+}
+
+// calculate the conversion time needed before reading back the sensor values
+uint8_t getConversionTime(barometerReadingType type) {
+    uint32_t OSR_ConvertTime;
+    if (OSR_CFG == HP20X_CONVERT_OSR128) {
+        switch (type) {
+            case HP20X_READ_TEMP: OSR_ConvertTime = 3; break; // 2.1 ms
+            case HP20X_READ_PRES: OSR_ConvertTime = 5; break; // 4.1 ms
+        }
+    } else if (OSR_CFG == HP20X_CONVERT_OSR256) {
+        switch (type) {
+            case HP20X_READ_TEMP: OSR_ConvertTime = 5; break; // 4.1 ms
+            case HP20X_READ_PRES: OSR_ConvertTime = 9; break; // 8.2 ms
+        }
+    } else if (OSR_CFG == HP20X_CONVERT_OSR512) {
+        switch (type) {
+            case HP20X_READ_TEMP: OSR_ConvertTime = 9; break; // 8.2 ms
+            case HP20X_READ_PRES: OSR_ConvertTime = 17; break; // 16.4 ms
+        }
+    } else if (OSR_CFG == HP20X_CONVERT_OSR1024) {
+        switch (type) {
+            case HP20X_READ_TEMP: OSR_ConvertTime = 17; break; // 16.4 ms
+            case HP20X_READ_PRES: OSR_ConvertTime = 34; break; // 32.8 ms
+        }
+    } else if (OSR_CFG == HP20X_CONVERT_OSR2048) {
+        switch (type) {
+            case HP20X_READ_TEMP: OSR_ConvertTime = 34; break; // 32.8 ms
+            case HP20X_READ_PRES: OSR_ConvertTime = 67; break; // 65.6 ms
+        }
+    } else if (OSR_CFG == HP20X_CONVERT_OSR4096) {
+        switch (type) {
+            case HP20X_READ_TEMP: OSR_ConvertTime = 67; break; // 65.6 ms
+            case HP20X_READ_PRES: OSR_ConvertTime = 132; break; // 131.1 ms
+        }
+    }
+
+    return OSR_ConvertTime;
+}
+
+int main()
+{
+    serial.baud(115200);
+    i2c.frequency((uint32_t)100e3);
+
+    serial.printf("HP206C barometer example...\n");
+
+    // detect the barometer
+    unsigned char result = readRegister(HP20X_REG_PARA);
+    if (result == HP20X_OK_DEV) {
+        baro_found = true;
+        softReset();
+        disableCompensation();
+        serial.printf("barometer found\n");
+    } else {
+        serial.printf("barometer NOT found \n");
+        while(1);
+    }
+
+    while(1)
+    {
+        if (baro_found) {
+            recalibrate();
+            wait_us(70); // this delay is a must if we read temperature, pressure or altitude right after the recalibration (in tests, 60 didn't worked) in microseconds
+            readTemperatureAndPressureStep1();
+            wait_ms(getConversionTime(HP20X_READ_PRES)); // get only the pressure, because its the longest interval
+            readTemperatureAndPressureStep2();
+            readAltitude();
+
+            serial.printf("temperature %f, pressure %f, altitude %f\n", temperature, pressure, altitude);
+            wait_ms(100); // don't hammer the serial console
+        }
+    }
+}
diff -r 000000000000 -r 0a071ea90726 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Aug 02 12:18:49 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/a97add6d7e64
\ No newline at end of file