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

Dependencies:   mbed

Committer:
ElectronicsSanta
Date:
Wed Aug 02 12:18:49 2017 +0000
Revision:
0:0a071ea90726
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ElectronicsSanta 0:0a071ea90726 1 #include "mbed.h"
ElectronicsSanta 0:0a071ea90726 2
ElectronicsSanta 0:0a071ea90726 3 #define HP20X_SOFT_RST 0x06
ElectronicsSanta 0:0a071ea90726 4 #define HP20X_WR_CONVERT_CMD 0x40
ElectronicsSanta 0:0a071ea90726 5 #define HP20X_CONVERT_OSR4096 0 << 2
ElectronicsSanta 0:0a071ea90726 6 #define HP20X_CONVERT_OSR2048 1 << 2
ElectronicsSanta 0:0a071ea90726 7 #define HP20X_CONVERT_OSR1024 2 << 2
ElectronicsSanta 0:0a071ea90726 8 #define HP20X_CONVERT_OSR512 3 << 2
ElectronicsSanta 0:0a071ea90726 9 #define HP20X_CONVERT_OSR256 4 << 2
ElectronicsSanta 0:0a071ea90726 10 #define HP20X_CONVERT_OSR128 5 << 2
ElectronicsSanta 0:0a071ea90726 11
ElectronicsSanta 0:0a071ea90726 12 #define HP20X_READ_P 0x30 // read_p command
ElectronicsSanta 0:0a071ea90726 13 #define HP20X_READ_A 0x31 // read_a command
ElectronicsSanta 0:0a071ea90726 14 #define HP20X_READ_T 0x32 // read_t command
ElectronicsSanta 0:0a071ea90726 15 #define HP20X_READ_PT 0x10 // read_pt command
ElectronicsSanta 0:0a071ea90726 16 #define HP20X_READ_AT 0x11 // read_at command
ElectronicsSanta 0:0a071ea90726 17 #define HP20X_READ_CAL 0X28 // RE-CAL ANALOG
ElectronicsSanta 0:0a071ea90726 18
ElectronicsSanta 0:0a071ea90726 19 #define HP20X_WR_REG_MODE 0xC0
ElectronicsSanta 0:0a071ea90726 20 #define HP20X_RD_REG_MODE 0x80
ElectronicsSanta 0:0a071ea90726 21
ElectronicsSanta 0:0a071ea90726 22 #define HP20X_ANA_CAL 0x28 // recalibrate analog internal circuitries
ElectronicsSanta 0:0a071ea90726 23
ElectronicsSanta 0:0a071ea90726 24 #define HP20X_OK_DEV 0X80 // successfully initialized
ElectronicsSanta 0:0a071ea90726 25 #define HP20X_REG_PARA 0X0F // status register
ElectronicsSanta 0:0a071ea90726 26
ElectronicsSanta 0:0a071ea90726 27 #define I2C_BAROMETER_ADDRESS 0x76 << 1 // 0xEC
ElectronicsSanta 0:0a071ea90726 28
ElectronicsSanta 0:0a071ea90726 29 #define OSR_CFG HP20X_CONVERT_OSR2048
ElectronicsSanta 0:0a071ea90726 30
ElectronicsSanta 0:0a071ea90726 31 Serial serial(SERIAL_TX, SERIAL_RX);
ElectronicsSanta 0:0a071ea90726 32 I2C i2c(I2C_SDA, I2C_SCL); // PB_9, PB_8
ElectronicsSanta 0:0a071ea90726 33
ElectronicsSanta 0:0a071ea90726 34 float temperature = 0.0f;
ElectronicsSanta 0:0a071ea90726 35 float pressure = 0.0f;
ElectronicsSanta 0:0a071ea90726 36 float altitude = 0.0f;
ElectronicsSanta 0:0a071ea90726 37 bool baro_found = false;
ElectronicsSanta 0:0a071ea90726 38
ElectronicsSanta 0:0a071ea90726 39 typedef enum {
ElectronicsSanta 0:0a071ea90726 40 HP20X_READ_TEMP,
ElectronicsSanta 0:0a071ea90726 41 HP20X_READ_PRES
ElectronicsSanta 0:0a071ea90726 42 } barometerReadingType;
ElectronicsSanta 0:0a071ea90726 43
ElectronicsSanta 0:0a071ea90726 44 // send a register reading command
ElectronicsSanta 0:0a071ea90726 45 unsigned char readRegister(unsigned char reg) {
ElectronicsSanta 0:0a071ea90726 46 char i2cBuffer[1];
ElectronicsSanta 0:0a071ea90726 47 i2cBuffer[0] = (reg | HP20X_RD_REG_MODE);
ElectronicsSanta 0:0a071ea90726 48 i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
ElectronicsSanta 0:0a071ea90726 49
ElectronicsSanta 0:0a071ea90726 50 // read the data
ElectronicsSanta 0:0a071ea90726 51 i2c.read(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
ElectronicsSanta 0:0a071ea90726 52
ElectronicsSanta 0:0a071ea90726 53 return i2cBuffer[0];
ElectronicsSanta 0:0a071ea90726 54 }
ElectronicsSanta 0:0a071ea90726 55
ElectronicsSanta 0:0a071ea90726 56 // send a register writing command
ElectronicsSanta 0:0a071ea90726 57 void writeRegister(unsigned char reg, unsigned char data) {
ElectronicsSanta 0:0a071ea90726 58 char i2cBuffer[1];
ElectronicsSanta 0:0a071ea90726 59 i2cBuffer[0] = (reg | HP20X_WR_REG_MODE);
ElectronicsSanta 0:0a071ea90726 60 i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
ElectronicsSanta 0:0a071ea90726 61 i2cBuffer[0] = data;
ElectronicsSanta 0:0a071ea90726 62 i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
ElectronicsSanta 0:0a071ea90726 63 }
ElectronicsSanta 0:0a071ea90726 64
ElectronicsSanta 0:0a071ea90726 65 void enableCompensation() {
ElectronicsSanta 0:0a071ea90726 66 writeRegister(HP20X_REG_PARA, 0x01);
ElectronicsSanta 0:0a071ea90726 67 }
ElectronicsSanta 0:0a071ea90726 68
ElectronicsSanta 0:0a071ea90726 69 void disableCompensation() {
ElectronicsSanta 0:0a071ea90726 70 writeRegister(HP20X_REG_PARA, 0x00);
ElectronicsSanta 0:0a071ea90726 71 }
ElectronicsSanta 0:0a071ea90726 72
ElectronicsSanta 0:0a071ea90726 73 void softReset() {
ElectronicsSanta 0:0a071ea90726 74 char i2cBuffer[1];
ElectronicsSanta 0:0a071ea90726 75 i2cBuffer[0] = HP20X_SOFT_RST;
ElectronicsSanta 0:0a071ea90726 76 i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
ElectronicsSanta 0:0a071ea90726 77 }
ElectronicsSanta 0:0a071ea90726 78
ElectronicsSanta 0:0a071ea90726 79 void recalibrate() {
ElectronicsSanta 0:0a071ea90726 80 char i2cBuffer[1];
ElectronicsSanta 0:0a071ea90726 81 i2cBuffer[0] = HP20X_ANA_CAL;
ElectronicsSanta 0:0a071ea90726 82 i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
ElectronicsSanta 0:0a071ea90726 83 }
ElectronicsSanta 0:0a071ea90726 84
ElectronicsSanta 0:0a071ea90726 85 uint32_t readData3Bytes() {
ElectronicsSanta 0:0a071ea90726 86 uint32_t tmpData;
ElectronicsSanta 0:0a071ea90726 87 char tmpArray[3] = {0};
ElectronicsSanta 0:0a071ea90726 88
ElectronicsSanta 0:0a071ea90726 89 // request 3 bytes from device
ElectronicsSanta 0:0a071ea90726 90 i2c.read(I2C_BAROMETER_ADDRESS, tmpArray, 3);
ElectronicsSanta 0:0a071ea90726 91
ElectronicsSanta 0:0a071ea90726 92 // MSB
ElectronicsSanta 0:0a071ea90726 93 tmpData = tmpArray[0] << 16 | tmpArray[1] << 8 | tmpArray[2];
ElectronicsSanta 0:0a071ea90726 94
ElectronicsSanta 0:0a071ea90726 95 if(tmpData & 0x800000) {
ElectronicsSanta 0:0a071ea90726 96 tmpData |= 0xff000000;
ElectronicsSanta 0:0a071ea90726 97 }
ElectronicsSanta 0:0a071ea90726 98
ElectronicsSanta 0:0a071ea90726 99 return tmpData;
ElectronicsSanta 0:0a071ea90726 100 }
ElectronicsSanta 0:0a071ea90726 101
ElectronicsSanta 0:0a071ea90726 102 uint32_t *readData6Bytes() {
ElectronicsSanta 0:0a071ea90726 103 static uint32_t tmpData[2];
ElectronicsSanta 0:0a071ea90726 104 char tmpArray[6] = {0};
ElectronicsSanta 0:0a071ea90726 105
ElectronicsSanta 0:0a071ea90726 106 // request 6 bytes from device
ElectronicsSanta 0:0a071ea90726 107 i2c.read(I2C_BAROMETER_ADDRESS, tmpArray, 6);
ElectronicsSanta 0:0a071ea90726 108
ElectronicsSanta 0:0a071ea90726 109 // MSB
ElectronicsSanta 0:0a071ea90726 110 tmpData[0] = tmpArray[0] << 16 | tmpArray[1] << 8 | tmpArray[2]; // temperature
ElectronicsSanta 0:0a071ea90726 111 tmpData[1] = tmpArray[3] << 16 | tmpArray[4] << 8 | tmpArray[5]; // pressure
ElectronicsSanta 0:0a071ea90726 112
ElectronicsSanta 0:0a071ea90726 113 if(tmpData[0] & 0x800000) {
ElectronicsSanta 0:0a071ea90726 114 tmpData[0] |= 0xff000000;
ElectronicsSanta 0:0a071ea90726 115 }
ElectronicsSanta 0:0a071ea90726 116 if(tmpData[1] & 0x800000) {
ElectronicsSanta 0:0a071ea90726 117 tmpData[1] |= 0xff000000;
ElectronicsSanta 0:0a071ea90726 118 }
ElectronicsSanta 0:0a071ea90726 119
ElectronicsSanta 0:0a071ea90726 120 return tmpData;
ElectronicsSanta 0:0a071ea90726 121 }
ElectronicsSanta 0:0a071ea90726 122
ElectronicsSanta 0:0a071ea90726 123 void readTemperatureAndPressureStep1() {
ElectronicsSanta 0:0a071ea90726 124 char i2cBuffer[2];
ElectronicsSanta 0:0a071ea90726 125 i2cBuffer[0] = HP20X_WR_CONVERT_CMD | OSR_CFG;
ElectronicsSanta 0:0a071ea90726 126 i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1); // ADC convert
ElectronicsSanta 0:0a071ea90726 127 }
ElectronicsSanta 0:0a071ea90726 128
ElectronicsSanta 0:0a071ea90726 129 void readTemperatureAndPressureStep2() {
ElectronicsSanta 0:0a071ea90726 130 char i2cBuffer[1];
ElectronicsSanta 0:0a071ea90726 131
ElectronicsSanta 0:0a071ea90726 132 i2cBuffer[0] = HP20X_READ_PT;
ElectronicsSanta 0:0a071ea90726 133 i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
ElectronicsSanta 0:0a071ea90726 134
ElectronicsSanta 0:0a071ea90726 135 uint32_t *p = readData6Bytes();
ElectronicsSanta 0:0a071ea90726 136 temperature = ((double)p[0] / 100.0f);
ElectronicsSanta 0:0a071ea90726 137 pressure = ((double)p[1] / 100.0f);
ElectronicsSanta 0:0a071ea90726 138 }
ElectronicsSanta 0:0a071ea90726 139
ElectronicsSanta 0:0a071ea90726 140 void readAltitude() {
ElectronicsSanta 0:0a071ea90726 141 char i2cBuffer[1];
ElectronicsSanta 0:0a071ea90726 142 i2cBuffer[0] = HP20X_READ_A;
ElectronicsSanta 0:0a071ea90726 143 i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1);
ElectronicsSanta 0:0a071ea90726 144
ElectronicsSanta 0:0a071ea90726 145 altitude = ((double)readData3Bytes() / 100.0f);
ElectronicsSanta 0:0a071ea90726 146 }
ElectronicsSanta 0:0a071ea90726 147
ElectronicsSanta 0:0a071ea90726 148 // calculate the conversion time needed before reading back the sensor values
ElectronicsSanta 0:0a071ea90726 149 uint8_t getConversionTime(barometerReadingType type) {
ElectronicsSanta 0:0a071ea90726 150 uint32_t OSR_ConvertTime;
ElectronicsSanta 0:0a071ea90726 151 if (OSR_CFG == HP20X_CONVERT_OSR128) {
ElectronicsSanta 0:0a071ea90726 152 switch (type) {
ElectronicsSanta 0:0a071ea90726 153 case HP20X_READ_TEMP: OSR_ConvertTime = 3; break; // 2.1 ms
ElectronicsSanta 0:0a071ea90726 154 case HP20X_READ_PRES: OSR_ConvertTime = 5; break; // 4.1 ms
ElectronicsSanta 0:0a071ea90726 155 }
ElectronicsSanta 0:0a071ea90726 156 } else if (OSR_CFG == HP20X_CONVERT_OSR256) {
ElectronicsSanta 0:0a071ea90726 157 switch (type) {
ElectronicsSanta 0:0a071ea90726 158 case HP20X_READ_TEMP: OSR_ConvertTime = 5; break; // 4.1 ms
ElectronicsSanta 0:0a071ea90726 159 case HP20X_READ_PRES: OSR_ConvertTime = 9; break; // 8.2 ms
ElectronicsSanta 0:0a071ea90726 160 }
ElectronicsSanta 0:0a071ea90726 161 } else if (OSR_CFG == HP20X_CONVERT_OSR512) {
ElectronicsSanta 0:0a071ea90726 162 switch (type) {
ElectronicsSanta 0:0a071ea90726 163 case HP20X_READ_TEMP: OSR_ConvertTime = 9; break; // 8.2 ms
ElectronicsSanta 0:0a071ea90726 164 case HP20X_READ_PRES: OSR_ConvertTime = 17; break; // 16.4 ms
ElectronicsSanta 0:0a071ea90726 165 }
ElectronicsSanta 0:0a071ea90726 166 } else if (OSR_CFG == HP20X_CONVERT_OSR1024) {
ElectronicsSanta 0:0a071ea90726 167 switch (type) {
ElectronicsSanta 0:0a071ea90726 168 case HP20X_READ_TEMP: OSR_ConvertTime = 17; break; // 16.4 ms
ElectronicsSanta 0:0a071ea90726 169 case HP20X_READ_PRES: OSR_ConvertTime = 34; break; // 32.8 ms
ElectronicsSanta 0:0a071ea90726 170 }
ElectronicsSanta 0:0a071ea90726 171 } else if (OSR_CFG == HP20X_CONVERT_OSR2048) {
ElectronicsSanta 0:0a071ea90726 172 switch (type) {
ElectronicsSanta 0:0a071ea90726 173 case HP20X_READ_TEMP: OSR_ConvertTime = 34; break; // 32.8 ms
ElectronicsSanta 0:0a071ea90726 174 case HP20X_READ_PRES: OSR_ConvertTime = 67; break; // 65.6 ms
ElectronicsSanta 0:0a071ea90726 175 }
ElectronicsSanta 0:0a071ea90726 176 } else if (OSR_CFG == HP20X_CONVERT_OSR4096) {
ElectronicsSanta 0:0a071ea90726 177 switch (type) {
ElectronicsSanta 0:0a071ea90726 178 case HP20X_READ_TEMP: OSR_ConvertTime = 67; break; // 65.6 ms
ElectronicsSanta 0:0a071ea90726 179 case HP20X_READ_PRES: OSR_ConvertTime = 132; break; // 131.1 ms
ElectronicsSanta 0:0a071ea90726 180 }
ElectronicsSanta 0:0a071ea90726 181 }
ElectronicsSanta 0:0a071ea90726 182
ElectronicsSanta 0:0a071ea90726 183 return OSR_ConvertTime;
ElectronicsSanta 0:0a071ea90726 184 }
ElectronicsSanta 0:0a071ea90726 185
ElectronicsSanta 0:0a071ea90726 186 int main()
ElectronicsSanta 0:0a071ea90726 187 {
ElectronicsSanta 0:0a071ea90726 188 serial.baud(115200);
ElectronicsSanta 0:0a071ea90726 189 i2c.frequency((uint32_t)100e3);
ElectronicsSanta 0:0a071ea90726 190
ElectronicsSanta 0:0a071ea90726 191 serial.printf("HP206C barometer example...\n");
ElectronicsSanta 0:0a071ea90726 192
ElectronicsSanta 0:0a071ea90726 193 // detect the barometer
ElectronicsSanta 0:0a071ea90726 194 unsigned char result = readRegister(HP20X_REG_PARA);
ElectronicsSanta 0:0a071ea90726 195 if (result == HP20X_OK_DEV) {
ElectronicsSanta 0:0a071ea90726 196 baro_found = true;
ElectronicsSanta 0:0a071ea90726 197 softReset();
ElectronicsSanta 0:0a071ea90726 198 disableCompensation();
ElectronicsSanta 0:0a071ea90726 199 serial.printf("barometer found\n");
ElectronicsSanta 0:0a071ea90726 200 } else {
ElectronicsSanta 0:0a071ea90726 201 serial.printf("barometer NOT found \n");
ElectronicsSanta 0:0a071ea90726 202 while(1);
ElectronicsSanta 0:0a071ea90726 203 }
ElectronicsSanta 0:0a071ea90726 204
ElectronicsSanta 0:0a071ea90726 205 while(1)
ElectronicsSanta 0:0a071ea90726 206 {
ElectronicsSanta 0:0a071ea90726 207 if (baro_found) {
ElectronicsSanta 0:0a071ea90726 208 recalibrate();
ElectronicsSanta 0:0a071ea90726 209 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
ElectronicsSanta 0:0a071ea90726 210 readTemperatureAndPressureStep1();
ElectronicsSanta 0:0a071ea90726 211 wait_ms(getConversionTime(HP20X_READ_PRES)); // get only the pressure, because its the longest interval
ElectronicsSanta 0:0a071ea90726 212 readTemperatureAndPressureStep2();
ElectronicsSanta 0:0a071ea90726 213 readAltitude();
ElectronicsSanta 0:0a071ea90726 214
ElectronicsSanta 0:0a071ea90726 215 serial.printf("temperature %f, pressure %f, altitude %f\n", temperature, pressure, altitude);
ElectronicsSanta 0:0a071ea90726 216 wait_ms(100); // don't hammer the serial console
ElectronicsSanta 0:0a071ea90726 217 }
ElectronicsSanta 0:0a071ea90726 218 }
ElectronicsSanta 0:0a071ea90726 219 }