Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp@1:a6eded1f5043, 2019-06-25 (annotated)
- Committer:
- pmic
- Date:
- Tue Jun 25 11:46:33 2019 +0000
- Revision:
- 1:a6eded1f5043
- Parent:
- 0:5119eeafd9ce
- Child:
- 2:ecd5c6118888
first adjustments
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pmic | 0:5119eeafd9ce | 1 | #include "mbed.h" |
pmic | 0:5119eeafd9ce | 2 | |
pmic | 1:a6eded1f5043 | 3 | #define I2C_BAROMETER_ADDRESS 0x76 << 1 // 0xEC, device adress |
pmic | 1:a6eded1f5043 | 4 | |
pmic | 1:a6eded1f5043 | 5 | #define HP20X_SOFT_RST 0x06 // for initializing, takes longer than next |
pmic | 1:a6eded1f5043 | 6 | #define HP20X_ANA_CAL 0x28 // recalibrate analog internal circuitries, for unstable environment |
pmic | 1:a6eded1f5043 | 7 | |
pmic | 0:5119eeafd9ce | 8 | #define HP20X_WR_CONVERT_CMD 0x40 |
pmic | 1:a6eded1f5043 | 9 | |
pmic | 1:a6eded1f5043 | 10 | #define HP20X_READ_PT 0x10 // read pressure and altitude command |
pmic | 1:a6eded1f5043 | 11 | #define HP20X_READ_A 0x31 // read altitude command |
pmic | 1:a6eded1f5043 | 12 | |
pmic | 1:a6eded1f5043 | 13 | #define HP20X_WR_REG_MODE 0xC0 |
pmic | 1:a6eded1f5043 | 14 | #define HP20X_RD_REG_MODE 0x80 |
pmic | 1:a6eded1f5043 | 15 | |
pmic | 1:a6eded1f5043 | 16 | #define HP20X_OK_DEV 0X80 // successfully initialized |
pmic | 1:a6eded1f5043 | 17 | #define HP20X_REG_PARA 0X0F // status register |
pmic | 1:a6eded1f5043 | 18 | |
pmic | 0:5119eeafd9ce | 19 | #define HP20X_CONVERT_OSR4096 0 << 2 |
pmic | 0:5119eeafd9ce | 20 | #define HP20X_CONVERT_OSR2048 1 << 2 |
pmic | 0:5119eeafd9ce | 21 | #define HP20X_CONVERT_OSR1024 2 << 2 |
pmic | 0:5119eeafd9ce | 22 | #define HP20X_CONVERT_OSR512 3 << 2 |
pmic | 0:5119eeafd9ce | 23 | #define HP20X_CONVERT_OSR256 4 << 2 |
pmic | 0:5119eeafd9ce | 24 | #define HP20X_CONVERT_OSR128 5 << 2 |
pmic | 0:5119eeafd9ce | 25 | |
pmic | 1:a6eded1f5043 | 26 | #define OSR_CFG HP20X_CONVERT_OSR1024 |
pmic | 0:5119eeafd9ce | 27 | |
pmic | 0:5119eeafd9ce | 28 | Serial serial(SERIAL_TX, SERIAL_RX); |
pmic | 0:5119eeafd9ce | 29 | I2C i2c(I2C_SDA, I2C_SCL); // PB_9, PB_8 |
pmic | 0:5119eeafd9ce | 30 | |
pmic | 0:5119eeafd9ce | 31 | float temperature = 0.0f; |
pmic | 0:5119eeafd9ce | 32 | float pressure = 0.0f; |
pmic | 0:5119eeafd9ce | 33 | float altitude = 0.0f; |
pmic | 0:5119eeafd9ce | 34 | bool baro_found = false; |
pmic | 0:5119eeafd9ce | 35 | |
pmic | 0:5119eeafd9ce | 36 | typedef enum { |
pmic | 0:5119eeafd9ce | 37 | HP20X_READ_TEMP, |
pmic | 0:5119eeafd9ce | 38 | HP20X_READ_PRES |
pmic | 0:5119eeafd9ce | 39 | } barometerReadingType; |
pmic | 0:5119eeafd9ce | 40 | |
pmic | 0:5119eeafd9ce | 41 | // send a register reading command |
pmic | 0:5119eeafd9ce | 42 | unsigned char readRegister(unsigned char reg) { |
pmic | 0:5119eeafd9ce | 43 | char i2cBuffer[1]; |
pmic | 0:5119eeafd9ce | 44 | i2cBuffer[0] = (reg | HP20X_RD_REG_MODE); |
pmic | 0:5119eeafd9ce | 45 | i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1); |
pmic | 0:5119eeafd9ce | 46 | |
pmic | 0:5119eeafd9ce | 47 | // read the data |
pmic | 0:5119eeafd9ce | 48 | i2c.read(I2C_BAROMETER_ADDRESS, i2cBuffer, 1); |
pmic | 0:5119eeafd9ce | 49 | |
pmic | 0:5119eeafd9ce | 50 | return i2cBuffer[0]; |
pmic | 0:5119eeafd9ce | 51 | } |
pmic | 0:5119eeafd9ce | 52 | |
pmic | 0:5119eeafd9ce | 53 | // send a register writing command |
pmic | 0:5119eeafd9ce | 54 | void writeRegister(unsigned char reg, unsigned char data) { |
pmic | 0:5119eeafd9ce | 55 | char i2cBuffer[1]; |
pmic | 0:5119eeafd9ce | 56 | i2cBuffer[0] = (reg | HP20X_WR_REG_MODE); |
pmic | 0:5119eeafd9ce | 57 | i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1); |
pmic | 0:5119eeafd9ce | 58 | i2cBuffer[0] = data; |
pmic | 0:5119eeafd9ce | 59 | i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1); |
pmic | 0:5119eeafd9ce | 60 | } |
pmic | 0:5119eeafd9ce | 61 | |
pmic | 0:5119eeafd9ce | 62 | void enableCompensation() { |
pmic | 0:5119eeafd9ce | 63 | writeRegister(HP20X_REG_PARA, 0x01); |
pmic | 0:5119eeafd9ce | 64 | } |
pmic | 0:5119eeafd9ce | 65 | |
pmic | 0:5119eeafd9ce | 66 | void disableCompensation() { |
pmic | 0:5119eeafd9ce | 67 | writeRegister(HP20X_REG_PARA, 0x00); |
pmic | 0:5119eeafd9ce | 68 | } |
pmic | 0:5119eeafd9ce | 69 | |
pmic | 0:5119eeafd9ce | 70 | void softReset() { |
pmic | 0:5119eeafd9ce | 71 | char i2cBuffer[1]; |
pmic | 0:5119eeafd9ce | 72 | i2cBuffer[0] = HP20X_SOFT_RST; |
pmic | 0:5119eeafd9ce | 73 | i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1); |
pmic | 0:5119eeafd9ce | 74 | } |
pmic | 0:5119eeafd9ce | 75 | |
pmic | 0:5119eeafd9ce | 76 | void recalibrate() { |
pmic | 0:5119eeafd9ce | 77 | char i2cBuffer[1]; |
pmic | 0:5119eeafd9ce | 78 | i2cBuffer[0] = HP20X_ANA_CAL; |
pmic | 0:5119eeafd9ce | 79 | i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1); |
pmic | 0:5119eeafd9ce | 80 | } |
pmic | 0:5119eeafd9ce | 81 | |
pmic | 0:5119eeafd9ce | 82 | uint32_t readData3Bytes() { |
pmic | 0:5119eeafd9ce | 83 | uint32_t tmpData; |
pmic | 0:5119eeafd9ce | 84 | char tmpArray[3] = {0}; |
pmic | 0:5119eeafd9ce | 85 | |
pmic | 0:5119eeafd9ce | 86 | // request 3 bytes from device |
pmic | 0:5119eeafd9ce | 87 | i2c.read(I2C_BAROMETER_ADDRESS, tmpArray, 3); |
pmic | 0:5119eeafd9ce | 88 | |
pmic | 0:5119eeafd9ce | 89 | // MSB |
pmic | 0:5119eeafd9ce | 90 | tmpData = tmpArray[0] << 16 | tmpArray[1] << 8 | tmpArray[2]; |
pmic | 0:5119eeafd9ce | 91 | |
pmic | 0:5119eeafd9ce | 92 | if(tmpData & 0x800000) { |
pmic | 0:5119eeafd9ce | 93 | tmpData |= 0xff000000; |
pmic | 0:5119eeafd9ce | 94 | } |
pmic | 0:5119eeafd9ce | 95 | |
pmic | 0:5119eeafd9ce | 96 | return tmpData; |
pmic | 0:5119eeafd9ce | 97 | } |
pmic | 0:5119eeafd9ce | 98 | |
pmic | 0:5119eeafd9ce | 99 | uint32_t *readData6Bytes() { |
pmic | 0:5119eeafd9ce | 100 | static uint32_t tmpData[2]; |
pmic | 0:5119eeafd9ce | 101 | char tmpArray[6] = {0}; |
pmic | 0:5119eeafd9ce | 102 | |
pmic | 0:5119eeafd9ce | 103 | // request 6 bytes from device |
pmic | 0:5119eeafd9ce | 104 | i2c.read(I2C_BAROMETER_ADDRESS, tmpArray, 6); |
pmic | 0:5119eeafd9ce | 105 | |
pmic | 0:5119eeafd9ce | 106 | // MSB |
pmic | 0:5119eeafd9ce | 107 | tmpData[0] = tmpArray[0] << 16 | tmpArray[1] << 8 | tmpArray[2]; // temperature |
pmic | 0:5119eeafd9ce | 108 | tmpData[1] = tmpArray[3] << 16 | tmpArray[4] << 8 | tmpArray[5]; // pressure |
pmic | 0:5119eeafd9ce | 109 | |
pmic | 0:5119eeafd9ce | 110 | if(tmpData[0] & 0x800000) { |
pmic | 0:5119eeafd9ce | 111 | tmpData[0] |= 0xff000000; |
pmic | 0:5119eeafd9ce | 112 | } |
pmic | 0:5119eeafd9ce | 113 | if(tmpData[1] & 0x800000) { |
pmic | 0:5119eeafd9ce | 114 | tmpData[1] |= 0xff000000; |
pmic | 0:5119eeafd9ce | 115 | } |
pmic | 0:5119eeafd9ce | 116 | |
pmic | 0:5119eeafd9ce | 117 | return tmpData; |
pmic | 0:5119eeafd9ce | 118 | } |
pmic | 0:5119eeafd9ce | 119 | |
pmic | 0:5119eeafd9ce | 120 | void readTemperatureAndPressureStep1() { |
pmic | 0:5119eeafd9ce | 121 | char i2cBuffer[2]; |
pmic | 0:5119eeafd9ce | 122 | i2cBuffer[0] = HP20X_WR_CONVERT_CMD | OSR_CFG; |
pmic | 0:5119eeafd9ce | 123 | i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1); // ADC convert |
pmic | 0:5119eeafd9ce | 124 | } |
pmic | 0:5119eeafd9ce | 125 | |
pmic | 0:5119eeafd9ce | 126 | void readTemperatureAndPressureStep2() { |
pmic | 0:5119eeafd9ce | 127 | char i2cBuffer[1]; |
pmic | 0:5119eeafd9ce | 128 | |
pmic | 0:5119eeafd9ce | 129 | i2cBuffer[0] = HP20X_READ_PT; |
pmic | 0:5119eeafd9ce | 130 | i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1); |
pmic | 0:5119eeafd9ce | 131 | |
pmic | 0:5119eeafd9ce | 132 | uint32_t *p = readData6Bytes(); |
pmic | 0:5119eeafd9ce | 133 | temperature = ((double)p[0] / 100.0f); |
pmic | 0:5119eeafd9ce | 134 | pressure = ((double)p[1] / 100.0f); |
pmic | 0:5119eeafd9ce | 135 | } |
pmic | 0:5119eeafd9ce | 136 | |
pmic | 0:5119eeafd9ce | 137 | void readAltitude() { |
pmic | 0:5119eeafd9ce | 138 | char i2cBuffer[1]; |
pmic | 0:5119eeafd9ce | 139 | i2cBuffer[0] = HP20X_READ_A; |
pmic | 0:5119eeafd9ce | 140 | i2c.write(I2C_BAROMETER_ADDRESS, i2cBuffer, 1); |
pmic | 0:5119eeafd9ce | 141 | |
pmic | 0:5119eeafd9ce | 142 | altitude = ((double)readData3Bytes() / 100.0f); |
pmic | 0:5119eeafd9ce | 143 | } |
pmic | 0:5119eeafd9ce | 144 | |
pmic | 0:5119eeafd9ce | 145 | // calculate the conversion time needed before reading back the sensor values |
pmic | 0:5119eeafd9ce | 146 | uint8_t getConversionTime(barometerReadingType type) { |
pmic | 0:5119eeafd9ce | 147 | uint32_t OSR_ConvertTime; |
pmic | 0:5119eeafd9ce | 148 | if (OSR_CFG == HP20X_CONVERT_OSR128) { |
pmic | 0:5119eeafd9ce | 149 | switch (type) { |
pmic | 0:5119eeafd9ce | 150 | case HP20X_READ_TEMP: OSR_ConvertTime = 3; break; // 2.1 ms |
pmic | 0:5119eeafd9ce | 151 | case HP20X_READ_PRES: OSR_ConvertTime = 5; break; // 4.1 ms |
pmic | 0:5119eeafd9ce | 152 | } |
pmic | 0:5119eeafd9ce | 153 | } else if (OSR_CFG == HP20X_CONVERT_OSR256) { |
pmic | 0:5119eeafd9ce | 154 | switch (type) { |
pmic | 0:5119eeafd9ce | 155 | case HP20X_READ_TEMP: OSR_ConvertTime = 5; break; // 4.1 ms |
pmic | 0:5119eeafd9ce | 156 | case HP20X_READ_PRES: OSR_ConvertTime = 9; break; // 8.2 ms |
pmic | 0:5119eeafd9ce | 157 | } |
pmic | 0:5119eeafd9ce | 158 | } else if (OSR_CFG == HP20X_CONVERT_OSR512) { |
pmic | 0:5119eeafd9ce | 159 | switch (type) { |
pmic | 0:5119eeafd9ce | 160 | case HP20X_READ_TEMP: OSR_ConvertTime = 9; break; // 8.2 ms |
pmic | 0:5119eeafd9ce | 161 | case HP20X_READ_PRES: OSR_ConvertTime = 17; break; // 16.4 ms |
pmic | 0:5119eeafd9ce | 162 | } |
pmic | 0:5119eeafd9ce | 163 | } else if (OSR_CFG == HP20X_CONVERT_OSR1024) { |
pmic | 0:5119eeafd9ce | 164 | switch (type) { |
pmic | 0:5119eeafd9ce | 165 | case HP20X_READ_TEMP: OSR_ConvertTime = 17; break; // 16.4 ms |
pmic | 0:5119eeafd9ce | 166 | case HP20X_READ_PRES: OSR_ConvertTime = 34; break; // 32.8 ms |
pmic | 0:5119eeafd9ce | 167 | } |
pmic | 0:5119eeafd9ce | 168 | } else if (OSR_CFG == HP20X_CONVERT_OSR2048) { |
pmic | 0:5119eeafd9ce | 169 | switch (type) { |
pmic | 0:5119eeafd9ce | 170 | case HP20X_READ_TEMP: OSR_ConvertTime = 34; break; // 32.8 ms |
pmic | 0:5119eeafd9ce | 171 | case HP20X_READ_PRES: OSR_ConvertTime = 67; break; // 65.6 ms |
pmic | 0:5119eeafd9ce | 172 | } |
pmic | 0:5119eeafd9ce | 173 | } else if (OSR_CFG == HP20X_CONVERT_OSR4096) { |
pmic | 0:5119eeafd9ce | 174 | switch (type) { |
pmic | 0:5119eeafd9ce | 175 | case HP20X_READ_TEMP: OSR_ConvertTime = 67; break; // 65.6 ms |
pmic | 0:5119eeafd9ce | 176 | case HP20X_READ_PRES: OSR_ConvertTime = 132; break; // 131.1 ms |
pmic | 0:5119eeafd9ce | 177 | } |
pmic | 0:5119eeafd9ce | 178 | } |
pmic | 0:5119eeafd9ce | 179 | |
pmic | 0:5119eeafd9ce | 180 | return OSR_ConvertTime; |
pmic | 0:5119eeafd9ce | 181 | } |
pmic | 0:5119eeafd9ce | 182 | |
pmic | 0:5119eeafd9ce | 183 | int main() |
pmic | 0:5119eeafd9ce | 184 | { |
pmic | 0:5119eeafd9ce | 185 | serial.baud(115200); |
pmic | 0:5119eeafd9ce | 186 | i2c.frequency((uint32_t)100e3); |
pmic | 0:5119eeafd9ce | 187 | |
pmic | 0:5119eeafd9ce | 188 | serial.printf("HP206C barometer example...\n"); |
pmic | 0:5119eeafd9ce | 189 | |
pmic | 0:5119eeafd9ce | 190 | // detect the barometer |
pmic | 0:5119eeafd9ce | 191 | unsigned char result = readRegister(HP20X_REG_PARA); |
pmic | 0:5119eeafd9ce | 192 | if (result == HP20X_OK_DEV) { |
pmic | 0:5119eeafd9ce | 193 | baro_found = true; |
pmic | 0:5119eeafd9ce | 194 | softReset(); |
pmic | 1:a6eded1f5043 | 195 | // recalibrate(); |
pmic | 0:5119eeafd9ce | 196 | disableCompensation(); |
pmic | 1:a6eded1f5043 | 197 | // enableCompensation(); |
pmic | 0:5119eeafd9ce | 198 | serial.printf("barometer found\n"); |
pmic | 0:5119eeafd9ce | 199 | } else { |
pmic | 0:5119eeafd9ce | 200 | serial.printf("barometer NOT found \n"); |
pmic | 0:5119eeafd9ce | 201 | while(1); |
pmic | 0:5119eeafd9ce | 202 | } |
pmic | 0:5119eeafd9ce | 203 | |
pmic | 0:5119eeafd9ce | 204 | while(1) |
pmic | 0:5119eeafd9ce | 205 | { |
pmic | 0:5119eeafd9ce | 206 | if (baro_found) { |
pmic | 1:a6eded1f5043 | 207 | // recalibrate(); |
pmic | 1:a6eded1f5043 | 208 | // 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 |
pmic | 0:5119eeafd9ce | 209 | readTemperatureAndPressureStep1(); |
pmic | 0:5119eeafd9ce | 210 | wait_ms(getConversionTime(HP20X_READ_PRES)); // get only the pressure, because its the longest interval |
pmic | 0:5119eeafd9ce | 211 | readTemperatureAndPressureStep2(); |
pmic | 0:5119eeafd9ce | 212 | readAltitude(); |
pmic | 0:5119eeafd9ce | 213 | |
pmic | 1:a6eded1f5043 | 214 | //serial.printf("temperature %f, pressure %f, altitude %f\r\n", temperature, pressure, altitude); |
pmic | 1:a6eded1f5043 | 215 | serial.printf("altitude %f\r\n", altitude); |
pmic | 1:a6eded1f5043 | 216 | // wait_ms(1); // don't hammer the serial console |
pmic | 0:5119eeafd9ce | 217 | } |
pmic | 0:5119eeafd9ce | 218 | } |
pmic | 0:5119eeafd9ce | 219 | } |