Carter John
/
HP206C_barometer
An example on how to read temperature, pressure and altitude from HP206C barometer sensor.
Revision 0:0a071ea90726, committed 2017-08-02
- 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