Carter John
/
HP206C_barometer
An example on how to read temperature, pressure and altitude from HP206C barometer sensor.
main.cpp@0:0a071ea90726, 2017-08-02 (annotated)
- Committer:
- ElectronicsSanta
- Date:
- Wed Aug 02 12:18:49 2017 +0000
- Revision:
- 0:0a071ea90726
first commit
Who changed what in which revision?
User | Revision | Line number | New 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 | } |